diff --git a/openair2/UTIL/ASYNC_IF/link_manager.c b/openair2/UTIL/ASYNC_IF/link_manager.c index 7486fbd1710caa630a1d625111d96853a9ec19d8..ddbb89fdaacc852210620e50e5e11529bdfbdf17 100644 --- a/openair2/UTIL/ASYNC_IF/link_manager.c +++ b/openair2/UTIL/ASYNC_IF/link_manager.c @@ -76,7 +76,7 @@ static void *link_manager_receiver_thread(void *_manager) LOG_D(MAC, "starting link manager receiver thread\n"); while (manager->run) { - if (link_receive_packet(manager->socket_link, &data, &size, manager->type, manager->peer_addr, manager->port)) + if (link_receive_packet(manager->socket_link, &data, &size, manager->type)) goto error; /* todo: priority */ if (message_put(manager->receive_queue, data, size, 0)) diff --git a/openair2/UTIL/ASYNC_IF/link_manager.h b/openair2/UTIL/ASYNC_IF/link_manager.h index f7efc928676fafadd92335b61fb2ffb845505448..f749119de67beeed2a2c90d454879233bf6e85de 100644 --- a/openair2/UTIL/ASYNC_IF/link_manager.h +++ b/openair2/UTIL/ASYNC_IF/link_manager.h @@ -46,7 +46,7 @@ typedef struct { message_queue_t *receive_queue; socket_link_t *socket_link; uint16_t type; - char *peer_addr; + const char *peer_addr; int port; pthread_t sender; pthread_t receiver; diff --git a/openair2/UTIL/ASYNC_IF/socket_link.c b/openair2/UTIL/ASYNC_IF/socket_link.c index e7100a2797cfa4eb8ff5984775bd5fb8ddc86252..d8dcb764e913b55d79434b67d4a2be05506bb499 100644 --- a/openair2/UTIL/ASYNC_IF/socket_link.c +++ b/openair2/UTIL/ASYNC_IF/socket_link.c @@ -163,8 +163,8 @@ error: return NULL; } -socket_link_t *new_link_udp_server(int port){ - +socket_link_t *new_link_udp_server(const char *bind_addr, int bind_port) +{ socket_link_t *ret = NULL; struct sockaddr_in si_me; @@ -181,19 +181,25 @@ socket_link_t *new_link_udp_server(int port){ //create a UDP socket if ((socket_server=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { - goto error; + goto error; } // zero out the structure memset((char *) &si_me, 0, sizeof(si_me)); si_me.sin_family = AF_INET; - si_me.sin_port = htons(port); - si_me.sin_addr.s_addr = INADDR_ANY; + si_me.sin_port = htons(bind_port); + if (bind_addr) { + if (!inet_aton(bind_addr, &si_me.sin_addr)) + goto error; + } else { + si_me.sin_addr.s_addr = INADDR_ANY; + } //bind socket to port if( bind(socket_server , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1) { - goto error; + fprintf(stderr, "could not bind to address %s: %s\n", bind_addr, strerror(errno)); + goto error; } ret->socket_fd = socket_server; ret->peer_port = 0; @@ -356,13 +362,11 @@ error: return NULL; } -static int socket_udp_send(int socket_fd, void *buf, int size, char *peer_addr, int port) +static int socket_udp_send(int socket_fd, void *buf, int size, const char *peer_addr, int port) { - struct sockaddr_in si_other; int slen = sizeof(si_other); - char *s = buf; - int l; + int l; int my_socket; LOG_D(PROTO_AGENT,"UDP send\n"); @@ -378,15 +382,10 @@ static int socket_udp_send(int socket_fd, void *buf, int size, char *peer_addr, exit(1); } - while (size) { - l = sendto(my_socket, s, size, 0, (struct sockaddr *) &si_other, slen); - if (l == -1) goto error; - if (l == 0) { printf("\n\n\nERROR PROTO_AGENT: %s:%d: this cannot happen, normally...\n", __FILE__, __LINE__); abort(); } - size -= l; - s += l; - } + l = sendto(my_socket, buf, size, 0, (struct sockaddr *) &si_other, slen); + if (l == -1) goto error; - return 0; + return l; error: LOG_E(MAC,"socket_udp_send: ERROR: %s\n", strerror(errno)); return -1; @@ -398,20 +397,14 @@ static int socket_udp_receive(int socket_fd, void *buf, int size) struct sockaddr_in client; socklen_t slen; - char *s = buf; int l; - while (size) { - l = recvfrom(socket_fd, s, size, 0, (struct sockaddr *) &client, &slen); - getsockname(socket_fd, (struct sockaddr *)&client, &slen); - LOG_D(PROTO_AGENT, "Got message from src port: %u\n", ntohs(client.sin_port)); - if (l == -1) goto error; - if (l == 0) goto socket_closed; - size -= l; - s += l; - } + l = recvfrom(socket_fd, buf, size, 0, (struct sockaddr *) &client, &slen); + //getsockname(socket_fd, (struct sockaddr *)&client, &slen); + if (l == -1) goto error; + if (l == 0) goto socket_closed; - return ntohs(client.sin_port); + return l; error: LOG_E(MAC, "socket_udp_receive: ERROR: %s\n", strerror(errno)); @@ -476,18 +469,18 @@ socket_closed: /* * return -1 on error and 0 if the sending was fine */ -int link_send_packet(socket_link_t *link, void *data, int size, uint16_t proto_type, char *peer_addr, int port) +int link_send_packet(socket_link_t *link, void *data, int size, uint16_t proto_type, const char *peer_addr, int peer_port) { char sizebuf[4]; int32_t s = size; - /* send the size first, maximum is 2^31 bytes */ - sizebuf[0] = (s >> 24) & 255; - sizebuf[1] = (s >> 16) & 255; - sizebuf[2] = (s >> 8) & 255; - sizebuf[3] = s & 255; if ((proto_type == 0) || (proto_type == 2)) { + /* send the size first, maximum is 2^31 bytes */ + sizebuf[0] = (s >> 24) & 255; + sizebuf[1] = (s >> 16) & 255; + sizebuf[2] = (s >> 8) & 255; + sizebuf[3] = s & 255; if (socket_send(link->socket_fd, sizebuf, 4) == -1) goto error; @@ -496,29 +489,18 @@ int link_send_packet(socket_link_t *link, void *data, int size, uint16_t proto_t if (socket_send(link->socket_fd, data, size) == -1) goto error; - link->bytes_sent += size; - link->packets_sent++; } else if (proto_type == 1 ) { - while (link->peer_port == 0) - { - sleep(0.1); - } - LOG_D(PROTO_AGENT, "peer port is %d", link->peer_port); - if (socket_udp_send(link->socket_fd, sizebuf, 4, peer_addr, link->peer_port) == -1) - goto error; - - LOG_I(PROTO_AGENT,"sent 4 bytes over the channel\n"); - link->bytes_sent += 4; - - if (socket_udp_send(link->socket_fd, data, size, peer_addr, link->peer_port) == -1) + /* UDP is connectionless -> only send the data */ + if (socket_udp_send(link->socket_fd, data, size, peer_addr, peer_port) == -1) goto error; - link->bytes_sent += size; - link->packets_sent++; } + link->bytes_sent += size; + link->packets_sent++; + return 0; error: @@ -529,50 +511,47 @@ error: * return -1 on error and 0 if the sending was fine */ -int link_receive_packet(socket_link_t *link, void **ret_data, int *ret_size, uint16_t proto_type, char *peer_addr, int port) +int link_receive_packet(socket_link_t *link, void **ret_data, int *ret_size, uint16_t proto_type) { unsigned char sizebuf[4]; - int32_t size; + int32_t size = 0; void *data = NULL; - int peer_port = 0; /* received the size first, maximum is 2^31 bytes */ if ((proto_type == 0) || (proto_type == 2)) { if (socket_receive(link->socket_fd, sizebuf, 4) == -1) goto error; - } - else if (proto_type == 1) - { - /* received the size first, maximum is 2^31 bytes */ - peer_port = socket_udp_receive(link->socket_fd, sizebuf, 4); - if ( peer_port == -1) - goto error; - if (peer_port == 0) link->peer_port = peer_port; - } - - size = (sizebuf[0] << 24) | - (sizebuf[1] << 16) | - (sizebuf[2] << 8) | - sizebuf[3]; - link->bytes_received += 4; + size = (sizebuf[0] << 24) | + (sizebuf[1] << 16) | + (sizebuf[2] << 8) | + sizebuf[3]; + link->bytes_received += 4; + + data = malloc(size); + if (data == NULL) { + LOG_E(MAC, "%s:%d: out of memory\n", __FILE__, __LINE__); + goto error; + } - data = malloc(size); - if (data == NULL) { - LOG_E(MAC, "%s:%d: out of memory\n", __FILE__, __LINE__); - goto error; - } - if ((proto_type == 0) || (proto_type == 2)) - { - if (socket_receive(link->socket_fd, data, size) == -1) goto error; } else if (proto_type == 1) - { - if (socket_udp_receive(link->socket_fd, data, size) == -1) + { + /* we get a single packet (no size, UDP could lose it). Therefore, prepare + * for the maximum UDP packet size */ + size = 65535; + data = malloc(size); + if (data == NULL) { + LOG_E(MAC, "%s:%d: out of memory\n", __FILE__, __LINE__); + goto error; + } + + size = socket_udp_receive(link->socket_fd, data, size); + if (size < 0) goto error; } diff --git a/openair2/UTIL/ASYNC_IF/socket_link.h b/openair2/UTIL/ASYNC_IF/socket_link.h index 1ce5c27424a67b8f01feb5412a43ce57bab5a483..a7a83f66c68da5bd38652cda1c2be417fa11316c 100644 --- a/openair2/UTIL/ASYNC_IF/socket_link.h +++ b/openair2/UTIL/ASYNC_IF/socket_link.h @@ -48,12 +48,13 @@ typedef struct { socket_link_t *new_link_server(int port); socket_link_t *new_link_client(const char *server, int port); -socket_link_t *new_link_udp_server(int port); +/* setting bind_addr to NULL binds server to INADDR_ANY */ +socket_link_t *new_link_udp_server(const char *bind_addr, int bind_port); socket_link_t *new_link_udp_client(const char *server, int port); socket_link_t *new_link_sctp_server(int port); socket_link_t *new_link_sctp_client(const char *server, int port); -int link_send_packet(socket_link_t *link, void *data, int size, uint16_t proto_type, char *peer_addr, int port); -int link_receive_packet(socket_link_t *link, void **data, int *size, uint16_t proto_type, char *peer_addr, int port); +int link_send_packet(socket_link_t *link, void *data, int size, uint16_t proto_type, const char *peer_addr, int port); +int link_receive_packet(socket_link_t *link, void **data, int *size, uint16_t proto_type); int close_link(socket_link_t *link);