[Opensrf-commits] r1819 - trunk/src/libopensrf (scottmk)
svn at svn.open-ils.org
svn at svn.open-ils.org
Tue Oct 13 19:07:01 EDT 2009
Author: scottmk
Date: 2009-10-13 19:07:01 -0400 (Tue, 13 Oct 2009)
New Revision: 1819
Modified:
trunk/src/libopensrf/socket_bundle.c
Log:
1. In socket_open_tcp_client(): use getaddrinfo() instead of gethostbyname().
The latter is obsolete, according to the man page and other sources.
2. Add doxygen-style comments to document several more functions.
M src/libopensrf/socket_bundle.c
Modified: trunk/src/libopensrf/socket_bundle.c
===================================================================
--- trunk/src/libopensrf/socket_bundle.c 2009-10-13 01:51:34 UTC (rev 1818)
+++ trunk/src/libopensrf/socket_bundle.c 2009-10-13 23:07:01 UTC (rev 1819)
@@ -276,61 +276,77 @@
@param dest_addr Host name or IP address of the server to which we are connecting.
@return The socket fd if successful; otherwise -1.
- Calls: gethostbyname(), socket(), connect().
+ Calls: getaddrinfo(), socket(), connect().
*/
int socket_open_tcp_client(socket_manager* mgr, int port, const char* dest_addr) {
struct sockaddr_in remoteAddr;
- struct hostent *hptr;
int sock_fd;
// ------------------------------------------------------------------
- // Get the hostname
+ // Get the IP address of the hostname (for TCP only)
// ------------------------------------------------------------------
+ struct addrinfo hints = { 0, 0, 0, 0, 0, NULL, NULL, NULL };
+ hints.ai_socktype = SOCK_STREAM;
+ struct addrinfo* addr_info = NULL;
errno = 0;
- if( (hptr = gethostbyname( dest_addr ) ) == NULL ) {
- osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_client(): Unknown Host => %s: %s",
- dest_addr, strerror( errno ) );
+ int rc = getaddrinfo( dest_addr, NULL, &hints, &addr_info );
+ if( rc || ! addr_info ) {
+ osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_client(): No Such Host => %s: %s",
+ dest_addr, gai_strerror( rc ) );
return -1;
}
- // ------------------------------------------------------------------
- // Create the socket
- // ------------------------------------------------------------------
- errno = 0;
- if( (sock_fd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
- osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_client(): Cannot create TCP socket: %s",
+ // Look for an address supporting IPv4. Someday we'll look for
+ // either IPv4 or IPv6, and branch according to what we find.
+ while( addr_info && addr_info->ai_family != PF_INET ) {
+ addr_info = addr_info->ai_next;
+ }
+
+ if( ! addr_info ) {
+ osrfLogWarning( OSRF_LOG_MARK,
+ "socket_open_tcp_client(): Host %s does not support IPV4", dest_addr );
+ return -1;
+ }
+
+ // ------------------------------------------------------------------
+ // Create the socket
+ // ------------------------------------------------------------------
+ errno = 0;
+ if( (sock_fd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
+ osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_client(): Cannot create TCP socket: %s",
strerror( errno ) );
- return -1;
- }
+ return -1;
+ }
int i = 1;
- //osrfLogDebug( OSRF_LOG_MARK, "Setting TCP_NODELAY");
setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i));
- // ------------------------------------------------------------------
- // Construct server info struct
- // ------------------------------------------------------------------
- memset( &remoteAddr, 0, sizeof(remoteAddr));
- remoteAddr.sin_family = AF_INET;
- remoteAddr.sin_port = htons( port );
- memcpy( (char*) &remoteAddr.sin_addr.s_addr,
- hptr->h_addr_list[0], hptr->h_length );
+ // ------------------------------------------------------------------
+ // Construct server info struct
+ // ------------------------------------------------------------------
+ memset( &remoteAddr, 0, sizeof(remoteAddr));
+ remoteAddr.sin_family = AF_INET;
+ remoteAddr.sin_port = htons( port );
+ struct sockaddr_in* ai_addr_in = (struct sockaddr_in*) addr_info->ai_addr;
+ remoteAddr.sin_addr.s_addr = ai_addr_in->sin_addr.s_addr;
- // ------------------------------------------------------------------
- // Connect to server
- // ------------------------------------------------------------------
- errno = 0;
- if( connect( sock_fd, (struct sockaddr*) &remoteAddr, sizeof( struct sockaddr_in ) ) < 0 ) {
- osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_client(): Cannot connect to server %s: %s",
- dest_addr, strerror(errno) );
- close( sock_fd );
- return -1;
- }
+ freeaddrinfo( addr_info );
+ // ------------------------------------------------------------------
+ // Connect to server
+ // ------------------------------------------------------------------
+ errno = 0;
+ if( connect( sock_fd, (struct sockaddr*) &remoteAddr, sizeof( struct sockaddr_in ) ) < 0 ) {
+ osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_client(): Cannot connect to server %s: %s",
+ dest_addr, strerror(errno) );
+ close( sock_fd );
+ return -1;
+ }
+
_socket_add_node(mgr, CLIENT_SOCKET, INET, sock_fd, -1 );
- return sock_fd;
+ return sock_fd;
}
@@ -403,7 +419,14 @@
}
-/* returns the socket_node with the given sock_fd */
+/**
+ @brief Search a socket_manager's list for a socket node for a given file descriptor.
+ @param mgr Pointer to the socket manager.
+ @param sock_fd The file descriptor to be sought.
+ @return A pointer to the socket_node if found; otherwise NULL.
+
+ Traverse a linked list owned by the socket_manager.
+*/
static socket_node* socket_find_node(socket_manager* mgr, int sock_fd) {
if(mgr == NULL) return NULL;
socket_node* node = mgr->socket;
@@ -416,6 +439,14 @@
}
/* removes the node with the given sock_fd from the list and frees it */
+/**
+ @brief Remove a socket node for a given fd from a socket_manager's list.
+ @param mgr Pointer to the socket_manager.
+ @param sock_fd The file descriptor whose socket_node is to be removed.
+
+ This function does @em not close the socket. It just removes a node from the list, and
+ frees it. It is the responsibility of the calling code to close the socket.
+*/
static void socket_remove_node(socket_manager* mgr, int sock_fd) {
if(mgr == NULL) return;
@@ -448,6 +479,14 @@
}
+/**
+ @brief Write to the log: a list of socket_nodes in a socket_manager's list.
+ @param mgr Pointer to the socket_manager.
+
+ For testing and debugging.
+
+ The messages are issued as DEBG messages, and show each file descriptor and its parent.
+*/
void _socket_print_list(socket_manager* mgr) {
if(mgr == NULL) return;
socket_node* node = mgr->socket;
More information about the opensrf-commits
mailing list