From d1ae6560ab2b8b5d474e58f865314a6cf18b958c Mon Sep 17 00:00:00 2001 From: Don Ward Date: Sun, 18 Apr 2010 19:01:56 -0400 Subject: [PATCH] Use getaddrinfo in gr_udp_{source,sink} Using getaddrinfo allows more common code between posix and winsock systems. Remove unused variables and #include files. Close sockets when done. --- gnuradio-core/src/lib/io/gr_udp_sink.cc | 69 +++++++++++------------ gnuradio-core/src/lib/io/gr_udp_sink.h | 21 ++----- gnuradio-core/src/lib/io/gr_udp_source.cc | 46 +++++++-------- gnuradio-core/src/lib/io/gr_udp_source.h | 16 ++---- 4 files changed, 66 insertions(+), 86 deletions(-) mode change 100644 => 100755 gnuradio-core/src/lib/io/gr_udp_source.h diff --git a/gnuradio-core/src/lib/io/gr_udp_sink.cc b/gnuradio-core/src/lib/io/gr_udp_sink.cc index dff06628..3d8d6514 100755 --- a/gnuradio-core/src/lib/io/gr_udp_sink.cc +++ b/gnuradio-core/src/lib/io/gr_udp_sink.cc @@ -26,14 +26,15 @@ #include #include #include -#if defined(HAVE_SOCKET) -#include +#include #include +#include +#if defined(HAVE_NETDB_H) typedef void* optval_t; #else +// if not posix, assume winsock #define USING_WINSOCK #define SHUT_RDWR 2 -#define inet_aton(N,A) ( (A)->s_addr = inet_addr(N), ( (A)->s_addr != INADDR_NONE ) ) typedef char* optval_t; #define ENOPROTOOPT 109 #endif @@ -99,39 +100,24 @@ gr_udp_sink::gr_udp_sink (size_t itemsize, // Set up the address stucture for the source address and port numbers // Get the source IP address from the host name - struct hostent *hsrc = gethostbyname(src); - if(hsrc) { // if the source was provided as a host namex - d_ip_src = *(struct in_addr*)hsrc->h_addr_list[0]; - } - else { // assume it was specified as an IP address - if((ret=inet_aton(src, &d_ip_src)) == 0) { // format IP address - report_error("Not a valid source IP address or host name", - "can't initialize source socket"); - } - } + struct addrinfo hints; + memset( (void*)&hints, 0, sizeof(hints) ); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + char port_str[7]; + sprintf( port_str, "%d", port_src ); + ret = getaddrinfo( src, port_str, &hints, &d_ip_src ); + if( ret != 0 ) + report_error("gr_udp_source/getaddrinfo", + "can't initialize source socket" ); // Get the destination IP address from the host name - struct hostent *hdst = gethostbyname(dst); - if(hdst) { // if the source was provided as a host namex - d_ip_dst = *(struct in_addr*)hdst->h_addr_list[0]; - } - else { // assume it was specified as an IP address - if((ret=inet_aton(dst, &d_ip_dst)) == 0) { // format IP address - report_error("Not a valid destination IP address or host name", - "can't initialize destination socket"); - } - } - - d_port_src = htons(port_src); // format port number - d_port_dst = htons(port_dst); // format port number - - d_sockaddr_src.sin_family = AF_INET; - d_sockaddr_src.sin_addr = d_ip_src; - d_sockaddr_src.sin_port = d_port_src; - - d_sockaddr_dst.sin_family = AF_INET; - d_sockaddr_dst.sin_addr = d_ip_dst; - d_sockaddr_dst.sin_port = d_port_dst; + sprintf( port_str, "%d", port_dst ); + ret = getaddrinfo( dst, port_str, &hints, &d_ip_dst ); + if( ret != 0 ) + report_error("gr_udp_source/getaddrinfo", + "can't initialize destination socket" ); open(); } @@ -152,6 +138,8 @@ gr_make_udp_sink (size_t itemsize, gr_udp_sink::~gr_udp_sink () { + freeaddrinfo(d_ip_src); + freeaddrinfo(d_ip_dst); close(); #if !defined(HAVE_SOCKET) // for Windows (with MinGW) @@ -166,7 +154,9 @@ gr_udp_sink::open() gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function // create socket - if((d_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { + d_socket = socket(d_ip_src->ai_family, d_ip_src->ai_socktype, + d_ip_src->ai_protocol); + if(d_socket == -1) { report_error("socket open","can't open socket"); } @@ -187,12 +177,12 @@ gr_udp_sink::open() } // bind socket to an address and port number to listen on - if(bind (d_socket, (sockaddr*)&d_sockaddr_src, sizeof(struct sockaddr)) == -1) { + if(bind (d_socket, d_ip_src->ai_addr, d_ip_src->ai_addrlen) == -1) { report_error("socket bind","can't bind socket"); } // Not sure if we should throw here or allow retries - if(connect(d_socket, (sockaddr*)&d_sockaddr_dst, sizeof(struct sockaddr)) == -1) { + if(connect(d_socket, d_ip_dst->ai_addr, d_ip_dst->ai_addrlen) == -1) { report_error("socket connect","can't connect to socket"); } @@ -207,6 +197,11 @@ gr_udp_sink::close() if (d_socket){ shutdown(d_socket, SHUT_RDWR); +#if defined(USING_WINSOCK) + closesocket(d_socket); +#else + ::close(d_socket); +#endif d_socket = 0; } d_updated = true; diff --git a/gnuradio-core/src/lib/io/gr_udp_sink.h b/gnuradio-core/src/lib/io/gr_udp_sink.h index f22b92dd..9f50ed7f 100644 --- a/gnuradio-core/src/lib/io/gr_udp_sink.h +++ b/gnuradio-core/src/lib/io/gr_udp_sink.h @@ -24,16 +24,12 @@ #define INCLUDED_GR_UDP_SINK_H #include -#include -#if defined(HAVE_SOCKET) -#include -#include +#if defined(HAVE_NETDB_H) +#include +#include // usually #included by ? #elif defined(HAVE_WINDOWS_H) #include -#include -#endif -#if defined(HAVE_NETINET_IN_H) -#include +#include #endif #include @@ -75,13 +71,8 @@ class gr_udp_sink : public gr_sync_block int d_payload_size; // maximum transmission unit (packet length) int d_socket; // handle to socket - int d_socket_rcv; // handle to socket retuned in the accept call - struct in_addr d_ip_src; // store the source ip info - struct in_addr d_ip_dst; // store the destination ip info - unsigned short d_port_src; // the port number to open for connections to this service - unsigned short d_port_dst; // port number of the remove system - struct sockaddr_in d_sockaddr_src; // store the source sockaddr data (formatted IP address and port number) - struct sockaddr_in d_sockaddr_dst; // store the destination sockaddr data (formatted IP address and port number) + struct addrinfo *d_ip_src; // store the source ip info + struct addrinfo *d_ip_dst; // store the destination ip info protected: /*! diff --git a/gnuradio-core/src/lib/io/gr_udp_source.cc b/gnuradio-core/src/lib/io/gr_udp_source.cc index 9df47da2..f459e7f1 100755 --- a/gnuradio-core/src/lib/io/gr_udp_source.cc +++ b/gnuradio-core/src/lib/io/gr_udp_source.cc @@ -29,14 +29,12 @@ #include #include #include -#if defined(HAVE_SOCKET) -#include +#if defined(HAVE_NETDB_H) typedef void* optval_t; #else -// Not posix, assume winsock +// if not posix, assume winsock #define USING_WINSOCK #define SHUT_RDWR 2 -#define inet_aton(N,A) ( (A)->s_addr = inet_addr(N), ( (A)->s_addr != INADDR_NONE ) ) typedef char* optval_t; #define ENOPROTOOPT 109 #endif @@ -98,22 +96,17 @@ gr_udp_source::gr_udp_source(size_t itemsize, const char *src, // Set up the address stucture for the source address and port numbers // Get the source IP address from the host name - struct hostent *hsrc = gethostbyname(src); - if(hsrc) { // if the source was provided as a host namex - d_ip_src = *(struct in_addr*)hsrc->h_addr_list[0]; - } - else { // assume it was specified as an IP address - if((ret=inet_aton(src, &d_ip_src)) == 0) { // format IP address - report_error("Not a valid source IP address or host name", - "can't initialize source socket"); - } - } - - d_port_src = htons(port_src); // format port number - - d_sockaddr_src.sin_family = AF_INET; - d_sockaddr_src.sin_addr = d_ip_src; - d_sockaddr_src.sin_port = d_port_src; + struct addrinfo hints; + memset( (void*)&hints, 0, sizeof(hints) ); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + char port_str[7]; + sprintf( port_str, "%d", port_src ); + ret = getaddrinfo( src, port_str, &hints, &d_ip_src ); + if( ret != 0 ) + report_error("gr_udp_source/getaddrinfo", + "can't initialize source socket" ); d_temp_buff = new char[d_payload_size]; // allow it to hold up to payload_size bytes @@ -130,6 +123,7 @@ gr_make_udp_source (size_t itemsize, const char *ipaddr, gr_udp_source::~gr_udp_source () { + freeaddrinfo(d_ip_src); delete [] d_temp_buff; close(); @@ -144,7 +138,8 @@ gr_udp_source::open() { gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function // create socket - d_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + d_socket = socket(d_ip_src->ai_family, d_ip_src->ai_socktype, + d_ip_src->ai_protocol); if(d_socket == -1) { report_error("socket open","can't open socket"); } @@ -180,10 +175,10 @@ gr_udp_source::open() } // bind socket to an address and port number to listen on - if(bind (d_socket, (sockaddr*)&d_sockaddr_src, sizeof(struct sockaddr)) == -1) { + if(bind (d_socket, d_ip_src->ai_addr, d_ip_src->ai_addrlen) == -1) { report_error("socket bind","can't bind socket"); } - + d_updated = true; return d_socket != 0; } @@ -195,6 +190,11 @@ gr_udp_source::close() if (d_socket){ shutdown(d_socket, SHUT_RDWR); +#if defined(USING_WINSOCK) + closesocket(d_socket); +#else + ::close(d_socket); +#endif d_socket = 0; } d_updated = true; diff --git a/gnuradio-core/src/lib/io/gr_udp_source.h b/gnuradio-core/src/lib/io/gr_udp_source.h old mode 100644 new mode 100755 index 61d719e4..14d521da --- a/gnuradio-core/src/lib/io/gr_udp_source.h +++ b/gnuradio-core/src/lib/io/gr_udp_source.h @@ -24,15 +24,12 @@ #define INCLUDED_GR_UDP_SOURCE_H #include -#if defined(HAVE_SOCKET) -#include -#include +#if defined(HAVE_NETDB_H) +#include +#include // usually #included by ? #elif defined(HAVE_WINDOWS_H) #include -#include -#endif -#if defined(HAVE_NETINET_IN_H) -#include +#include #endif #include @@ -68,10 +65,7 @@ class gr_udp_source : public gr_sync_block int d_payload_size; // maximum transmission unit (packet length) int d_socket; // handle to socket - int d_socket_rcv; // handle to socket retuned in the accept call - struct in_addr d_ip_src; // store the source IP address to use - unsigned short d_port_src; // the port number to open for connections to this service - struct sockaddr_in d_sockaddr_src; // store the source sockaddr data (formatted IP address and port number) + struct addrinfo *d_ip_src; // store the source IP address to use char *d_temp_buff; // hold buffer between calls ssize_t d_residual; // hold information about number of bytes stored in the temp buffer size_t d_temp_offset; // point to temp buffer location offset -- 2.30.2