Use getaddrinfo in gr_udp_{source,sink}
authorDon Ward <don2387ward@sprynet.com>
Sun, 18 Apr 2010 23:01:56 +0000 (19:01 -0400)
committerDon Ward <don2387ward@sprynet.com>
Sun, 18 Apr 2010 23:01:56 +0000 (19:01 -0400)
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
gnuradio-core/src/lib/io/gr_udp_sink.h
gnuradio-core/src/lib/io/gr_udp_source.cc
gnuradio-core/src/lib/io/gr_udp_source.h [changed mode: 0644->0755]

index dff066288c44f8133286d23929e2a9775d47e8e0..3d8d65145b4078dcaf3d0c5a80d76b863b1231e8 100755 (executable)
 #include <gr_udp_sink.h>
 #include <gr_io_signature.h>
 #include <stdexcept>
-#if defined(HAVE_SOCKET)
-#include <netdb.h>
+#include <errno.h>
 #include <stdio.h>
+#include <string.h>
+#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;
index f22b92dd035dd5e17f78c37ef3b9686486f61257..9f50ed7f03c23aa05f79f1d1cc983e4caf212c37 100644 (file)
 #define INCLUDED_GR_UDP_SINK_H
 
 #include <gr_sync_block.h>
-#include <boost/thread.hpp>
-#if defined(HAVE_SOCKET)
-#include <sys/socket.h>
-#include <arpa/inet.h>
+#if defined(HAVE_NETDB_H)
+#include <netdb.h>
+#include <sys/socket.h>  // usually #included by <netdb.h>?
 #elif defined(HAVE_WINDOWS_H)
 #include <winsock2.h>
-#include <windows.h>
-#endif
-#if defined(HAVE_NETINET_IN_H)
-#include <netinet/in.h>
+#include <ws2tcpip.h>
 #endif
 
 #include <gruel/thread.h>
@@ -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:
   /*!
index 9df47da2e65bf4816701bcdcd8bbbaf2c6bb9474..f459e7f1302fa7ba529fddf8248073953c814c51 100755 (executable)
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
-#if defined(HAVE_SOCKET)
-#include <netdb.h>
+#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;
old mode 100644 (file)
new mode 100755 (executable)
index 61d719e..14d521d
 #define INCLUDED_GR_UDP_SOURCE_H
 
 #include <gr_sync_block.h>
-#if defined(HAVE_SOCKET)
-#include <sys/socket.h>
-#include <arpa/inet.h>
+#if defined(HAVE_NETDB_H)
+#include <netdb.h>
+#include <sys/socket.h>  // usually #included by <netdb.h>?
 #elif defined(HAVE_WINDOWS_H)
 #include <winsock2.h>
-#include <windows.h>
-#endif
-#if defined(HAVE_NETINET_IN_H)
-#include <netinet/in.h>
+#include <ws2tcpip.h>
 #endif
 
 #include <gruel/thread.h>
@@ -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