creation of util class net_addr_t that provides methods for conversion of IP addr const char* to sockaddr_in

This commit is contained in:
Francisco Paisana 2019-11-12 16:05:47 +00:00
parent 31dffde6c3
commit 2c3e4a3daf
3 changed files with 89 additions and 36 deletions

View File

@ -36,7 +36,29 @@
namespace srslte {
class rx_sctp_socket_ref_t;
class rx_socket_itf_t
{
virtual int read(void* buf, size_t nbytes) const = 0;
};
class tx_socket_itf_t
{
virtual int send(const void* buf, size_t nbytes) const = 0;
};
class net_addr_t
{
public:
std::string ip() const;
bool set_ip(const char* ip_str);
void set_port(int port) { addr.sin_port = port; }
int port() const { return addr.sin_port; }
const sockaddr_in& get_sockaddr_in() const { return addr; }
sockaddr_in& get_sockaddr_in() { return addr; }
private:
struct sockaddr_in addr = {};
};
/**
* Description: Class created for code reuse by different sockets
@ -54,10 +76,6 @@ public:
bool is_init() const { return sockfd >= 0; }
int fd() const { return sockfd; }
// generic read/write interface
virtual int read(void* buf, size_t nbytes) const = 0;
virtual int send(void* buf, size_t nbytes) const = 0;
protected:
void reset_();
int bind_addr(const char* bind_addr_str, int port);
@ -79,28 +97,22 @@ public:
int listen_addr(const char* bind_addr_str, int port);
int connect_addr(const char* bind_addr_str, const char* dest_addr_str, int dest_port);
int read_from(void* buf,
size_t nbytes,
struct sockaddr_in* from = nullptr,
socklen_t* fromlen = nullptr,
struct sctp_sndrcvinfo* sinfo = nullptr,
int msg_flags = 0) const;
int read(void* buf, size_t nbytes, net_addr_t* addr) const;
int read(void* buf,
size_t nbytes,
struct sockaddr_in* from = nullptr,
socklen_t* fromlen = nullptr,
struct sctp_sndrcvinfo* sinfo = nullptr,
int msg_flags = 0) const;
int send(void* buf, size_t nbytes, uint32_t ppid, uint32_t stream_id) const;
int read(void* buf, size_t nbytes) const override { return read_from(buf, nbytes, nullptr, nullptr, nullptr, 0); }
int send(void* buf, size_t nbytes) const override
{
printf("SCTP interface send is invalid\n");
return -1;
}
private:
int create_socket() override;
struct sockaddr_in dest_addr = {};
};
class tcp_socket_t final : public base_socket_t
class tcp_socket_t final : public base_socket_t, public rx_socket_itf_t, public tx_socket_itf_t
{
public:
void reset();
@ -109,7 +121,7 @@ public:
int connect_addr(const char* bind_addr_str, const char* dest_addr_str, int dest_port);
int read(void* buf, size_t nbytes) const override;
int send(void* buf, size_t nbytes) const override;
int send(const void* buf, size_t nbytes) const override;
private:
int create_socket() override;

View File

@ -30,6 +30,27 @@
namespace srslte {
std::string net_addr_t::ip() const
{
char ip_str[128];
inet_ntop(addr.sin_family, &addr.sin_addr, ip_str, sizeof(ip_str));
return std::string{ip_str};
}
bool net_addr_t::set_ip(const char* ip_str)
{
addr.sin_family = AF_INET; // ip4 only for now
if (inet_pton(AF_INET, ip_str, &addr.sin_addr) != 1) {
perror("inet_pton");
return false;
}
return true;
}
/********************************************
* Socket Classes
*******************************************/
base_socket_t::base_socket_t(base_socket_t&& other) noexcept
{
sockfd = other.sockfd;
@ -157,17 +178,28 @@ int sctp_socket_t::connect_addr(const char* bind_addr_str, const char* dest_addr
return SRSLTE_SUCCESS;
}
int sctp_socket_t::read_from(void* buf,
size_t nbytes,
struct sockaddr_in* from,
socklen_t* fromlen,
struct sctp_sndrcvinfo* sinfo,
int msg_flags) const
int sctp_socket_t::read(void* buf, size_t nbytes, net_addr_t* addr) const
{
if (fromlen != nullptr) {
*fromlen = sizeof(*from);
if (addr != nullptr) {
sockaddr_in* from = &addr->get_sockaddr_in();
socklen_t fromlen = sizeof(*from);
return read(buf, nbytes, from, &fromlen);
}
return sctp_recvmsg(sockfd, buf, nbytes, (struct sockaddr*)from, fromlen, sinfo, &msg_flags);
return read(buf, nbytes);
}
int sctp_socket_t::read(void* buf,
size_t nbytes,
struct sockaddr_in* from,
socklen_t* fromlen,
struct sctp_sndrcvinfo* sinfo,
int msg_flags) const
{
if (from != nullptr) {
*fromlen = sizeof(*from);
return sctp_recvmsg(sockfd, buf, nbytes, (struct sockaddr*)from, fromlen, sinfo, &msg_flags);
}
return sctp_recvmsg(sockfd, buf, nbytes, nullptr, nullptr, sinfo, &msg_flags);
}
int sctp_socket_t::send(void* buf, size_t nbytes, uint32_t ppid, uint32_t stream_id) const
@ -258,7 +290,7 @@ int tcp_socket_t::read(void* buf, size_t nbytes) const
return n;
}
int tcp_socket_t::send(void* buf, size_t nbytes) const
int tcp_socket_t::send(const void* buf, size_t nbytes) const
{
// Loop until all bytes are sent
char* ptr = (char*)buf;

View File

@ -40,20 +40,23 @@ int test_socket_handler()
int counter = 0;
srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance();
srslte::sctp_socket_t server_sock, client_sock;
srslte::sctp_socket_t server_sock, client_sock, client_sock2;
srslte::rx_multisocket_handler sockhandler("RXSOCKETS", &log);
TESTASSERT(server_sock.listen_addr("127.0.100.1", 36412) == 0);
log.info("Listening from fd=%d\n", server_sock.fd());
TESTASSERT(client_sock.connect_addr("127.0.0.1", "127.0.100.1", 36412) == 0);
TESTASSERT(client_sock2.connect_addr("127.0.0.2", "127.0.100.1", 36412) == 0);
// register server Rx handler
sockhandler.register_socket(server_sock, [pool, &log, &counter](const srslte::sctp_socket_t& sock) {
srslte::unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true);
int rd_sz = sock.read(pdu->msg, pdu->get_tailroom());
srslte::unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true);
srslte::net_addr_t addr;
int rd_sz = sock.read(pdu->msg, pdu->get_tailroom(), &addr);
if (rd_sz > 0) {
pdu->N_bytes = rd_sz;
log.info_hex(pdu->msg, pdu->N_bytes, "Received msg:");
log.info_hex(pdu->msg, pdu->N_bytes, "Received msg from %s:", addr.ip().c_str());
counter++;
}
});
@ -64,8 +67,14 @@ int test_socket_handler()
uint8_t buf[128] = {};
int32_t nof_counts = 5;
for (int32_t i = 0; i < nof_counts; ++i) {
buf[i] = i;
ssize_t n_sent = client_sock.send(buf, i + 1, PPID, NONUE_STREAM_ID);
buf[i] = i;
// Round-robin between clients
srslte::sctp_socket_t* chosen = &client_sock;
if (i % 2 == 1) {
chosen = &client_sock2;
}
// send packet
ssize_t n_sent = chosen->send(buf, i + 1, PPID, NONUE_STREAM_ID);
TESTASSERT(n_sent >= 0);
usleep(1000);
log.info("Message %d sent.\n", i);