Skip to content
Snippets Groups Projects
Commit e46023f1 authored by Moe Jette's avatar Moe Jette
Browse files

Thread-safe versions of gethostbyname and gethostbyaddr added to slurm

from conman.
parent 1becdf97
No related branches found
No related tags found
No related merge requests found
...@@ -42,6 +42,7 @@ libcommon_la_SOURCES = \ ...@@ -42,6 +42,7 @@ libcommon_la_SOURCES = \
slurm_protocol_util.c \ slurm_protocol_util.c \
slurm_protocol_socket_implementation.c \ slurm_protocol_socket_implementation.c \
slurm_protocol_defs.c \ slurm_protocol_defs.c \
util-net.c \
$(elan_sources) \ $(elan_sources) \
$(auth_sources) $(auth_sources)
...@@ -72,7 +73,9 @@ noinst_HEADERS = \ ...@@ -72,7 +73,9 @@ noinst_HEADERS = \
slurm_protocol_socket_common.h \ slurm_protocol_socket_common.h \
slurm_protocol_mongo_common.h \ slurm_protocol_mongo_common.h \
slurm_protocol_interface.h \ slurm_protocol_interface.h \
slurm_errno.h \ slurm_errno.h \
util-net.h \
wrapper.h \
qsw.h qsw.h
libdaemonize_la_SOURCES = \ libdaemonize_la_SOURCES = \
......
...@@ -46,11 +46,12 @@ ...@@ -46,11 +46,12 @@
# endif # endif
#endif #endif
#include <src/common/slurm_protocol_interface.h> #include "src/common/slurm_protocol_interface.h"
#include <src/common/slurm_protocol_common.h> #include "src/common/slurm_protocol_common.h"
#include <src/common/slurm_protocol_defs.h> #include "src/common/slurm_protocol_defs.h"
#include <src/common/log.h> #include "src/common/log.h"
#include <src/common/pack.h> #include "src/common/pack.h"
#include "src/common/util-net.h"
#define TEMP_BUFFER_SIZE 1024 #define TEMP_BUFFER_SIZE 1024
...@@ -69,8 +70,9 @@ slurm_fd _slurm_open_msg_conn ( slurm_addr * slurm_address ) ...@@ -69,8 +70,9 @@ slurm_fd _slurm_open_msg_conn ( slurm_addr * slurm_address )
return _slurm_open_stream ( slurm_address ) ; return _slurm_open_stream ( slurm_address ) ;
} }
/* this should be a no-op that just returns open_fd in a message implementation */ /* this should be a no-op that just returns open_fd in a message
slurm_fd _slurm_accept_msg_conn ( slurm_fd open_fd , slurm_addr * slurm_address ) * implementation */
slurm_fd _slurm_accept_msg_conn (slurm_fd open_fd ,slurm_addr * slurm_address)
{ {
return _slurm_accept_stream ( open_fd , slurm_address ) ; return _slurm_accept_stream ( open_fd , slurm_address ) ;
} }
...@@ -80,13 +82,18 @@ int _slurm_close_accepted_conn ( slurm_fd open_fd ) ...@@ -80,13 +82,18 @@ int _slurm_close_accepted_conn ( slurm_fd open_fd )
return _slurm_close ( open_fd ) ; return _slurm_close ( open_fd ) ;
} }
ssize_t _slurm_msg_recvfrom ( slurm_fd open_fd, char *buffer , size_t size , uint32_t flags, slurm_addr * slurm_address ) ssize_t _slurm_msg_recvfrom ( slurm_fd open_fd, char *buffer , size_t size ,
uint32_t flags, slurm_addr * slurm_address )
{ {
return _slurm_msg_recvfrom_timeout ( open_fd , buffer , size , flags , return _slurm_msg_recvfrom_timeout ( open_fd , buffer , size , flags ,
slurm_address , SLURM_MESSGE_TIMEOUT_MSEC_STATIC ) ; slurm_address ,
SLURM_MESSGE_TIMEOUT_MSEC_STATIC ) ;
} }
ssize_t _slurm_msg_recvfrom_timeout ( slurm_fd open_fd, char *buffer , size_t size , uint32_t flags, slurm_addr * slurm_address , int timeout) ssize_t _slurm_msg_recvfrom_timeout ( slurm_fd open_fd, char *buffer ,
size_t size , uint32_t flags,
slurm_addr * slurm_address ,
int timeout)
{ {
size_t recv_len ; size_t recv_len ;
...@@ -102,9 +109,11 @@ ssize_t _slurm_msg_recvfrom_timeout ( slurm_fd open_fd, char *buffer , size_t si ...@@ -102,9 +109,11 @@ ssize_t _slurm_msg_recvfrom_timeout ( slurm_fd open_fd, char *buffer , size_t si
total_len = 0 ; total_len = 0 ;
while ( total_len < sizeof ( uint32_t ) ) while ( total_len < sizeof ( uint32_t ) )
{ {
if ( ( recv_len = _slurm_recv_timeout ( open_fd , moving_buffer , if ( ( recv_len = _slurm_recv_timeout ( open_fd ,
moving_buffer ,
(sizeof ( uint32_t ) - total_len), (sizeof ( uint32_t ) - total_len),
SLURM_PROTOCOL_NO_SEND_RECV_FLAGS , timeout ) ) == SLURM_SOCKET_ERROR ) SLURM_PROTOCOL_NO_SEND_RECV_FLAGS , timeout ) )
== SLURM_SOCKET_ERROR )
{ {
if ( errno == EINTR ) if ( errno == EINTR )
continue ; continue ;
...@@ -118,14 +127,16 @@ ssize_t _slurm_msg_recvfrom_timeout ( slurm_fd open_fd, char *buffer , size_t si ...@@ -118,14 +127,16 @@ ssize_t _slurm_msg_recvfrom_timeout ( slurm_fd open_fd, char *buffer , size_t si
} }
else if ( recv_len == 0 ) else if ( recv_len == 0 )
{ {
/*debug ( "Error receiving length of datagram. recv_len = 0 ") ; */ /*debug ( "Error datagram recv_len = 0 ") ; */
slurm_seterrno ( SLURM_PROTOCOL_SOCKET_IMPL_ZERO_RECV_LENGTH ) ; slurm_seterrno (
SLURM_PROTOCOL_SOCKET_IMPL_ZERO_RECV_LENGTH);
return SLURM_PROTOCOL_ERROR ; return SLURM_PROTOCOL_ERROR ;
} }
else else
{ {
/*debug ( "We don't handle negative return codes > -1") ;*/ /*debug ( "Error datagram recv_len < -1") ;*/
slurm_seterrno ( SLURM_PROTOCOL_SOCKET_IMPL_NEGATIVE_RECV_LENGTH ) ; slurm_seterrno (
SLURM_PROTOCOL_SOCKET_IMPL_NEGATIVE_RECV_LENGTH ) ;
return SLURM_PROTOCOL_ERROR ; return SLURM_PROTOCOL_ERROR ;
} }
} }
...@@ -143,7 +154,10 @@ ssize_t _slurm_msg_recvfrom_timeout ( slurm_fd open_fd, char *buffer , size_t si ...@@ -143,7 +154,10 @@ ssize_t _slurm_msg_recvfrom_timeout ( slurm_fd open_fd, char *buffer , size_t si
total_len = 0 ; total_len = 0 ;
while ( total_len < transmit_size ) while ( total_len < transmit_size )
{ {
if ( ( recv_len = _slurm_recv_timeout ( open_fd , moving_buffer , (transmit_size-total_len) , SLURM_PROTOCOL_NO_SEND_RECV_FLAGS , timeout ) ) == SLURM_SOCKET_ERROR ) if ( ( recv_len = _slurm_recv_timeout (open_fd, moving_buffer,
(transmit_size-total_len) ,
SLURM_PROTOCOL_NO_SEND_RECV_FLAGS ,
timeout ) ) == SLURM_SOCKET_ERROR )
{ {
if ( errno == EINTR ) if ( errno == EINTR )
{ {
...@@ -162,28 +176,32 @@ ssize_t _slurm_msg_recvfrom_timeout ( slurm_fd open_fd, char *buffer , size_t si ...@@ -162,28 +176,32 @@ ssize_t _slurm_msg_recvfrom_timeout ( slurm_fd open_fd, char *buffer , size_t si
} }
else if ( recv_len == 0 ) else if ( recv_len == 0 )
{ {
/*debug ( "Error receiving length of datagram. recv_len = 0 ") ; */ /*debug ( "Error datagram recv_len = 0 ") ; */
slurm_seterrno ( SLURM_PROTOCOL_SOCKET_IMPL_ZERO_RECV_LENGTH ) ; slurm_seterrno (
SLURM_PROTOCOL_SOCKET_IMPL_ZERO_RECV_LENGTH ) ;
return SLURM_PROTOCOL_ERROR ; return SLURM_PROTOCOL_ERROR ;
} }
else else
{ {
/*debug ( "We don't handle negative return codes > -1") ;*/ /*debug ( "Error datagram recv_len < -1") ;*/
slurm_seterrno ( SLURM_PROTOCOL_SOCKET_IMPL_NEGATIVE_RECV_LENGTH ) ; slurm_seterrno (
SLURM_PROTOCOL_SOCKET_IMPL_NEGATIVE_RECV_LENGTH ) ;
return SLURM_PROTOCOL_ERROR ; return SLURM_PROTOCOL_ERROR ;
} }
} }
if ( excess_len ) { if ( excess_len ) {
/* read and toss any data transmitted that we lack the buffer for */ /* read and toss any data transmitted over buffer size */
moving_buffer = size_buffer ; moving_buffer = size_buffer ;
size_buffer_len = TEMP_BUFFER_SIZE; size_buffer_len = TEMP_BUFFER_SIZE;
while ( excess_len ) while ( excess_len )
{ {
if (size_buffer_len > excess_len) if (size_buffer_len > excess_len)
size_buffer_len = excess_len; size_buffer_len = excess_len;
if ( ( recv_len = _slurm_recv_timeout ( open_fd , moving_buffer , size_buffer_len , if ( ( recv_len = _slurm_recv_timeout ( open_fd ,
SLURM_PROTOCOL_NO_SEND_RECV_FLAGS , timeout ) ) == SLURM_SOCKET_ERROR ) moving_buffer , size_buffer_len ,
SLURM_PROTOCOL_NO_SEND_RECV_FLAGS ,
timeout ) ) == SLURM_SOCKET_ERROR )
{ {
if ( errno == EINTR ) if ( errno == EINTR )
continue ; continue ;
...@@ -196,14 +214,16 @@ ssize_t _slurm_msg_recvfrom_timeout ( slurm_fd open_fd, char *buffer , size_t si ...@@ -196,14 +214,16 @@ ssize_t _slurm_msg_recvfrom_timeout ( slurm_fd open_fd, char *buffer , size_t si
} }
else if ( recv_len == 0 ) else if ( recv_len == 0 )
{ {
/*debug ( "Error receiving length of datagram. recv_len = 0 ") ; */ /*debug ( "Error datagram recv_len = 0 ") ; */
slurm_seterrno ( SLURM_PROTOCOL_SOCKET_IMPL_ZERO_RECV_LENGTH ) ; slurm_seterrno (
SLURM_PROTOCOL_SOCKET_IMPL_ZERO_RECV_LENGTH ) ;
return SLURM_PROTOCOL_ERROR ; return SLURM_PROTOCOL_ERROR ;
} }
else else
{ {
/*debug ( "We don't handle negative return codes > -1") ;*/ /*debug ( "Error datagram recv_len < -1") ;*/
slurm_seterrno ( SLURM_PROTOCOL_SOCKET_IMPL_NEGATIVE_RECV_LENGTH ) ; slurm_seterrno (
SLURM_PROTOCOL_SOCKET_IMPL_NEGATIVE_RECV_LENGTH ) ;
return SLURM_PROTOCOL_ERROR ; return SLURM_PROTOCOL_ERROR ;
} }
} }
...@@ -214,13 +234,17 @@ ssize_t _slurm_msg_recvfrom_timeout ( slurm_fd open_fd, char *buffer , size_t si ...@@ -214,13 +234,17 @@ ssize_t _slurm_msg_recvfrom_timeout ( slurm_fd open_fd, char *buffer , size_t si
return total_len ; return total_len ;
} }
ssize_t _slurm_msg_sendto ( slurm_fd open_fd, char *buffer , size_t size , uint32_t flags, slurm_addr * slurm_address ) ssize_t _slurm_msg_sendto ( slurm_fd open_fd, char *buffer , size_t size ,
uint32_t flags, slurm_addr * slurm_address )
{ {
return _slurm_msg_sendto_timeout ( open_fd, buffer , size , flags, return _slurm_msg_sendto_timeout ( open_fd, buffer , size , flags,
slurm_address , SLURM_MESSGE_TIMEOUT_MSEC_STATIC ) ; slurm_address ,
SLURM_MESSGE_TIMEOUT_MSEC_STATIC ) ;
} }
ssize_t _slurm_msg_sendto_timeout ( slurm_fd open_fd, char *buffer , size_t size , uint32_t flags, slurm_addr * slurm_address , int timeout ) ssize_t _slurm_msg_sendto_timeout ( slurm_fd open_fd, char *buffer ,
size_t size , uint32_t flags,
slurm_addr * slurm_address , int timeout )
{ {
size_t send_len ; size_t send_len ;
...@@ -231,7 +255,8 @@ ssize_t _slurm_msg_sendto_timeout ( slurm_fd open_fd, char *buffer , size_t size ...@@ -231,7 +255,8 @@ ssize_t _slurm_msg_sendto_timeout ( slurm_fd open_fd, char *buffer , size_t size
newaction . sa_handler = SIG_IGN ; newaction . sa_handler = SIG_IGN ;
/* ignore SIGPIPE so that send can return a error code if the other side closes the socket */ /* ignore SIGPIPE so that send can return a error code if the
* other side closes the socket */
sigaction(SIGPIPE, &newaction , & oldaction ); sigaction(SIGPIPE, &newaction , & oldaction );
usize = htonl(size); usize = htonl(size);
...@@ -240,8 +265,8 @@ ssize_t _slurm_msg_sendto_timeout ( slurm_fd open_fd, char *buffer , size_t size ...@@ -240,8 +265,8 @@ ssize_t _slurm_msg_sendto_timeout ( slurm_fd open_fd, char *buffer , size_t size
{ {
if ( ( send_len = _slurm_send_timeout ( open_fd , if ( ( send_len = _slurm_send_timeout ( open_fd ,
(char *) &usize , sizeof ( uint32_t ) , (char *) &usize , sizeof ( uint32_t ) ,
SLURM_PROTOCOL_NO_SEND_RECV_FLAGS , timeout ) ) == SLURM_PROTOCOL_NO_SEND_RECV_FLAGS ,
SLURM_PROTOCOL_ERROR ) timeout ) ) == SLURM_PROTOCOL_ERROR )
{ {
if ( errno == EINTR ) if ( errno == EINTR )
continue ; continue ;
...@@ -250,8 +275,10 @@ ssize_t _slurm_msg_sendto_timeout ( slurm_fd open_fd, char *buffer , size_t size ...@@ -250,8 +275,10 @@ ssize_t _slurm_msg_sendto_timeout ( slurm_fd open_fd, char *buffer , size_t size
} }
else if ( send_len != sizeof ( uint32_t ) ) else if ( send_len != sizeof ( uint32_t ) )
{ {
/*debug ( "_slurm_msg_sendto only transmitted %i of %i bytes", send_len , sizeof ( uint32_t ) ) ;*/ /*debug ( "_slurm_msg_sendto only transmitted %i of %i bytes",
slurm_seterrno ( SLURM_PROTOCOL_SOCKET_IMPL_NOT_ALL_DATA_SENT ) ; send_len , sizeof ( uint32_t ) ) ;*/
slurm_seterrno (
SLURM_PROTOCOL_SOCKET_IMPL_NOT_ALL_DATA_SENT ) ;
goto _slurm_msg_sendto_exit_error ; goto _slurm_msg_sendto_exit_error ;
} }
else else
...@@ -260,7 +287,8 @@ ssize_t _slurm_msg_sendto_timeout ( slurm_fd open_fd, char *buffer , size_t size ...@@ -260,7 +287,8 @@ ssize_t _slurm_msg_sendto_timeout ( slurm_fd open_fd, char *buffer , size_t size
while ( true ) while ( true )
{ {
if ( ( send_len = _slurm_send_timeout ( open_fd , buffer , size , if ( ( send_len = _slurm_send_timeout ( open_fd , buffer , size ,
SLURM_PROTOCOL_NO_SEND_RECV_FLAGS , timeout ) ) == SLURM_PROTOCOL_ERROR ) SLURM_PROTOCOL_NO_SEND_RECV_FLAGS ,
timeout ) ) == SLURM_PROTOCOL_ERROR )
{ {
if ( errno == EINTR ) if ( errno == EINTR )
continue ; continue ;
...@@ -269,8 +297,10 @@ ssize_t _slurm_msg_sendto_timeout ( slurm_fd open_fd, char *buffer , size_t size ...@@ -269,8 +297,10 @@ ssize_t _slurm_msg_sendto_timeout ( slurm_fd open_fd, char *buffer , size_t size
} }
else if ( send_len != size ) else if ( send_len != size )
{ {
/*debug ( "_slurm_msg_sendto only transmitted %i of %i bytes", send_len , size ) ;*/ /*debug ( "_slurm_msg_sendto only transmitted %i of %i bytes",
slurm_seterrno ( SLURM_PROTOCOL_SOCKET_IMPL_NOT_ALL_DATA_SENT ) ; send_len , size ) ;*/
slurm_seterrno (
SLURM_PROTOCOL_SOCKET_IMPL_NOT_ALL_DATA_SENT ) ;
goto _slurm_msg_sendto_exit_error ; goto _slurm_msg_sendto_exit_error ;
} }
else else
...@@ -326,7 +356,8 @@ int _slurm_send_timeout ( slurm_fd open_fd, char *buffer , size_t size , ...@@ -326,7 +356,8 @@ int _slurm_send_timeout ( slurm_fd open_fd, char *buffer , size_t size ,
} }
else if ( rc == 0 ) else if ( rc == 0 )
{ {
slurm_seterrno ( SLURM_PROTOCOL_SOCKET_ZERO_BYTES_SENT ) ; slurm_seterrno (
SLURM_PROTOCOL_SOCKET_ZERO_BYTES_SENT ) ;
goto _slurm_send_timeout_exit_error; goto _slurm_send_timeout_exit_error;
} }
else else
...@@ -393,7 +424,8 @@ int _slurm_recv_timeout ( slurm_fd open_fd, char *buffer , size_t size , ...@@ -393,7 +424,8 @@ int _slurm_recv_timeout ( slurm_fd open_fd, char *buffer , size_t size ,
} }
else if ( rc == 0 ) else if ( rc == 0 )
{ {
slurm_seterrno ( SLURM_PROTOCOL_SOCKET_ZERO_BYTES_SENT ) ; slurm_seterrno (
SLURM_PROTOCOL_SOCKET_ZERO_BYTES_SENT ) ;
goto _slurm_recv_timeout_exit_error; goto _slurm_recv_timeout_exit_error;
} }
else else
...@@ -427,25 +459,31 @@ slurm_fd _slurm_listen_stream ( slurm_addr * slurm_address ) ...@@ -427,25 +459,31 @@ slurm_fd _slurm_listen_stream ( slurm_addr * slurm_address )
int rc ; int rc ;
slurm_fd connection_fd ; slurm_fd connection_fd ;
const int one = 1; const int one = 1;
if ( ( connection_fd =_slurm_create_socket ( SLURM_STREAM ) ) == SLURM_SOCKET_ERROR ) if ( ( connection_fd =_slurm_create_socket ( SLURM_STREAM ) )
== SLURM_SOCKET_ERROR )
{ {
debug ( "Error creating slurm stream socket: %m" ) ; debug ( "Error creating slurm stream socket: %m" ) ;
return connection_fd ; return connection_fd ;
} }
if ( ( rc = _slurm_setsockopt(connection_fd , SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one) ) ) ) if ( ( rc = _slurm_setsockopt(connection_fd , SOL_SOCKET,
SO_REUSEADDR, &one, sizeof(one) ) ) )
{ {
debug ("setsockopt SO_REUSEADDR failed"); debug ("setsockopt SO_REUSEADDR failed");
goto error_cleanup ; goto error_cleanup ;
} }
if ( ( rc = _slurm_bind ( connection_fd , ( struct sockaddr const * ) slurm_address , sizeof ( slurm_addr ) ) ) == SLURM_SOCKET_ERROR ) if ( ( rc = _slurm_bind ( connection_fd ,
( struct sockaddr const * ) slurm_address ,
sizeof ( slurm_addr ) ) ) == SLURM_SOCKET_ERROR )
{ {
debug ( "Error binding slurm stream socket: %m" ) ; debug ( "Error binding slurm stream socket: %m" ) ;
goto error_cleanup ; goto error_cleanup ;
} }
if ( ( rc = _slurm_listen ( connection_fd , SLURM_PROTOCOL_DEFAULT_LISTEN_BACKLOG ) ) == SLURM_SOCKET_ERROR ) if ( ( rc = _slurm_listen ( connection_fd ,
SLURM_PROTOCOL_DEFAULT_LISTEN_BACKLOG ) )
== SLURM_SOCKET_ERROR )
{ {
debug ( "Error listening on slurm stream socket: %m" ) ; debug ( "Error listening on slurm stream socket: %m" ) ;
goto error_cleanup ; goto error_cleanup ;
...@@ -464,7 +502,9 @@ slurm_fd _slurm_accept_stream ( slurm_fd open_fd , slurm_addr * slurm_address ) ...@@ -464,7 +502,9 @@ slurm_fd _slurm_accept_stream ( slurm_fd open_fd , slurm_addr * slurm_address )
{ {
size_t addr_len = sizeof ( slurm_addr ) ; size_t addr_len = sizeof ( slurm_addr ) ;
slurm_fd connection_fd ; slurm_fd connection_fd ;
if ( ( connection_fd = _slurm_accept ( open_fd , ( struct sockaddr * ) slurm_address , & addr_len ) ) == SLURM_SOCKET_ERROR ) if ( ( connection_fd = _slurm_accept ( open_fd ,
( struct sockaddr * ) slurm_address ,
& addr_len ) ) == SLURM_SOCKET_ERROR )
{ {
debug ( "Error accepting slurm stream socket: %m" ) ; debug ( "Error accepting slurm stream socket: %m" ) ;
} }
...@@ -484,13 +524,17 @@ slurm_fd _slurm_open_stream ( slurm_addr * slurm_address ) ...@@ -484,13 +524,17 @@ slurm_fd _slurm_open_stream ( slurm_addr * slurm_address )
return SLURM_SOCKET_ERROR; return SLURM_SOCKET_ERROR;
} }
if ( ( connection_fd =_slurm_create_socket ( SLURM_STREAM ) ) == SLURM_SOCKET_ERROR ) if ( ( connection_fd =_slurm_create_socket ( SLURM_STREAM ) )
== SLURM_SOCKET_ERROR )
{ {
debug ( "Error creating slurm stream socket: %m" ) ; debug ( "Error creating slurm stream socket: %m" ) ;
return connection_fd ; return connection_fd ;
} }
if ( ( rc = _slurm_connect ( connection_fd , ( struct sockaddr const * ) slurm_address , sizeof ( slurm_addr ) ) ) == SLURM_SOCKET_ERROR ) if ( ( rc = _slurm_connect ( connection_fd ,
( struct sockaddr const * ) slurm_address ,
sizeof ( slurm_addr ) ) )
== SLURM_SOCKET_ERROR )
{ {
debug ( "Error connecting on slurm stream socket: %m" ) ; debug ( "Error connecting on slurm stream socket: %m" ) ;
goto error_cleanup ; goto error_cleanup ;
...@@ -508,7 +552,8 @@ int _slurm_get_stream_addr ( slurm_fd open_fd , slurm_addr * address ) ...@@ -508,7 +552,8 @@ int _slurm_get_stream_addr ( slurm_fd open_fd , slurm_addr * address )
int size ; int size ;
size = sizeof ( address ) ; size = sizeof ( address ) ;
return _slurm_getsockname ( open_fd , ( struct sockaddr * ) address , & size ) ; return _slurm_getsockname ( open_fd , ( struct sockaddr * ) address ,
& size ) ;
} }
int _slurm_close_stream ( slurm_fd open_fd ) int _slurm_close_stream ( slurm_fd open_fd )
...@@ -520,7 +565,8 @@ int _slurm_close_stream ( slurm_fd open_fd ) ...@@ -520,7 +565,8 @@ int _slurm_close_stream ( slurm_fd open_fd )
int _slurm_set_stream_non_blocking ( slurm_fd open_fd ) int _slurm_set_stream_non_blocking ( slurm_fd open_fd )
{ {
int flags ; int flags ;
if ( ( flags = _slurm_fcntl ( open_fd , F_GETFL ) ) == SLURM_SOCKET_ERROR ) if ( ( flags = _slurm_fcntl ( open_fd , F_GETFL ) )
== SLURM_SOCKET_ERROR )
{ {
return SLURM_SOCKET_ERROR ; return SLURM_SOCKET_ERROR ;
} }
...@@ -531,7 +577,8 @@ int _slurm_set_stream_non_blocking ( slurm_fd open_fd ) ...@@ -531,7 +577,8 @@ int _slurm_set_stream_non_blocking ( slurm_fd open_fd )
int _slurm_set_stream_blocking ( slurm_fd open_fd ) int _slurm_set_stream_blocking ( slurm_fd open_fd )
{ {
int flags ; int flags ;
if ( ( flags = _slurm_fcntl ( open_fd , F_GETFL ) ) == SLURM_SOCKET_ERROR ) if ( ( flags = _slurm_fcntl ( open_fd , F_GETFL ) )
== SLURM_SOCKET_ERROR )
{ {
return SLURM_SOCKET_ERROR ; return SLURM_SOCKET_ERROR ;
} }
...@@ -549,10 +596,12 @@ extern slurm_fd _slurm_create_socket ( slurm_socket_type_t type ) ...@@ -549,10 +596,12 @@ extern slurm_fd _slurm_create_socket ( slurm_socket_type_t type )
switch ( type ) switch ( type )
{ {
case SLURM_STREAM : case SLURM_STREAM :
return _slurm_socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP) ; return _slurm_socket ( AF_INET, SOCK_STREAM,
IPPROTO_TCP) ;
break; break;
case SLURM_MESSAGE : case SLURM_MESSAGE :
return _slurm_socket ( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ; return _slurm_socket ( AF_INET, SOCK_DGRAM,
IPPROTO_UDP ) ;
break; break;
default : default :
return SLURM_SOCKET_ERROR; return SLURM_SOCKET_ERROR;
...@@ -563,19 +612,22 @@ extern slurm_fd _slurm_create_socket ( slurm_socket_type_t type ) ...@@ -563,19 +612,22 @@ extern slurm_fd _slurm_create_socket ( slurm_socket_type_t type )
* protocol PROTOCOL, which are connected to each other, and put file * protocol PROTOCOL, which are connected to each other, and put file
* descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero, * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
* one will be chosen automatically. Returns 0 on success, -1 for errors. */ * one will be chosen automatically. Returns 0 on success, -1 for errors. */
extern int _slurm_socketpair (int __domain, int __type, int __protocol, int __fds[2]) extern int _slurm_socketpair (int __domain, int __type,
int __protocol, int __fds[2])
{ {
return SLURM_PROTOCOL_FUNCTION_NOT_IMPLEMENTED ; return SLURM_PROTOCOL_FUNCTION_NOT_IMPLEMENTED ;
} }
/* Give the socket FD the local address ADDR (which is LEN bytes long). */ /* Give the socket FD the local address ADDR (which is LEN bytes long). */
extern int _slurm_bind (int __fd, struct sockaddr const * __addr, socklen_t __len) extern int _slurm_bind (int __fd, struct sockaddr const * __addr,
socklen_t __len)
{ {
return bind ( __fd , __addr , __len ) ; return bind ( __fd , __addr , __len ) ;
} }
/* Put the local address of FD into *ADDR and its length in *LEN. */ /* Put the local address of FD into *ADDR and its length in *LEN. */
extern int _slurm_getsockname (int __fd, struct sockaddr * __addr, socklen_t *__restrict __len) extern int _slurm_getsockname (int __fd, struct sockaddr * __addr,
socklen_t *__restrict __len)
{ {
return getsockname ( __fd , __addr , __len ) ; return getsockname ( __fd , __addr , __len ) ;
} }
...@@ -584,20 +636,23 @@ extern int _slurm_getsockname (int __fd, struct sockaddr * __addr, socklen_t *__ ...@@ -584,20 +636,23 @@ extern int _slurm_getsockname (int __fd, struct sockaddr * __addr, socklen_t *__
* For connectionless socket types, just set the default address to send to * For connectionless socket types, just set the default address to send to
* and the only address from which to accept transmissions. * and the only address from which to accept transmissions.
* Return 0 on success, -1 for errors. */ * Return 0 on success, -1 for errors. */
extern int _slurm_connect (int __fd, struct sockaddr const * __addr, socklen_t __len) extern int _slurm_connect (int __fd, struct sockaddr const * __addr,
socklen_t __len)
{ {
return connect ( __fd , __addr , __len ) ; return connect ( __fd , __addr , __len ) ;
} }
/* Put the address of the peer connected to socket FD into *ADDR /* Put the address of the peer connected to socket FD into *ADDR
* (which is *LEN bytes long), and its actual length into *LEN. */ * (which is *LEN bytes long), and its actual length into *LEN. */
extern int _slurm_getpeername (int __fd, struct sockaddr * __addr, socklen_t *__restrict __len) extern int _slurm_getpeername (int __fd, struct sockaddr * __addr,
socklen_t *__restrict __len)
{ {
return getpeername ( __fd , __addr , __len ) ; return getpeername ( __fd , __addr , __len ) ;
} }
/* Send N bytes of BUF to socket FD. Returns the number sent or -1. */ /* Send N bytes of BUF to socket FD. Returns the number sent or -1. */
extern ssize_t _slurm_send (int __fd, __const void *__buf, size_t __n, int __flags) extern ssize_t _slurm_send (int __fd, __const void *__buf, size_t __n,
int __flags)
{ {
return send ( __fd , __buf , __n , __flags ) ; return send ( __fd , __buf , __n , __flags ) ;
} }
...@@ -611,7 +666,9 @@ extern ssize_t _slurm_recv (int __fd, void *__buf, size_t __n, int __flags) ...@@ -611,7 +666,9 @@ extern ssize_t _slurm_recv (int __fd, void *__buf, size_t __n, int __flags)
/* Send N bytes of BUF on socket FD to peer at address ADDR (which is /* Send N bytes of BUF on socket FD to peer at address ADDR (which is
* ADDR_LEN bytes long). Returns the number sent, or -1 for errors. */ * ADDR_LEN bytes long). Returns the number sent, or -1 for errors. */
extern ssize_t _slurm_sendto (int __fd, __const void *__buf, size_t __n, int __flags, struct sockaddr const * __addr, socklen_t __addr_len) extern ssize_t _slurm_sendto (int __fd, __const void *__buf, size_t __n,
int __flags, struct sockaddr const * __addr,
socklen_t __addr_len)
{ {
return sendto ( __fd , __buf , __n , __flags , __addr, __addr_len) ; return sendto ( __fd , __buf , __n , __flags , __addr, __addr_len) ;
} }
...@@ -619,14 +676,18 @@ extern ssize_t _slurm_sendto (int __fd, __const void *__buf, size_t __n, int __f ...@@ -619,14 +676,18 @@ extern ssize_t _slurm_sendto (int __fd, __const void *__buf, size_t __n, int __f
* If ADDR is not NULL, fill in *ADDR_LEN bytes of it with tha address of * If ADDR is not NULL, fill in *ADDR_LEN bytes of it with tha address of
* the sender, and store the actual size of the address in *ADDR_LEN. * the sender, and store the actual size of the address in *ADDR_LEN.
* Returns the number of bytes read or -1 for errors. */ * Returns the number of bytes read or -1 for errors. */
extern ssize_t _slurm_recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags, struct sockaddr * __addr, socklen_t *__restrict __addr_len) extern ssize_t _slurm_recvfrom (int __fd, void *__restrict __buf,
size_t __n, int __flags,
struct sockaddr * __addr,
socklen_t *__restrict __addr_len)
{ {
return recvfrom ( __fd , __buf , __n , __flags , __addr, __addr_len) ; return recvfrom ( __fd , __buf , __n , __flags , __addr, __addr_len) ;
} }
/* Send a msg described MESSAGE on socket FD. /* Send a msg described MESSAGE on socket FD.
* Returns the number of bytes sent, or -1 for errors. */ * Returns the number of bytes sent, or -1 for errors. */
extern ssize_t _slurm_sendmsg (int __fd, __const struct msghdr *__msg, int __flags) extern ssize_t _slurm_sendmsg (int __fd, __const struct msghdr *__msg,
int __flags)
{ {
return sendmsg ( __fd , __msg , __flags ) ; return sendmsg ( __fd , __msg , __flags ) ;
} }
...@@ -641,7 +702,9 @@ extern ssize_t _slurm_recvmsg (int __fd, struct msghdr *__msg, int __flags) ...@@ -641,7 +702,9 @@ extern ssize_t _slurm_recvmsg (int __fd, struct msghdr *__msg, int __flags)
/* Put the current value for socket FD's option OPTNAME at protocol level LEVEL /* Put the current value for socket FD's option OPTNAME at protocol level LEVEL
* into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's * into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's
* actual length. Returns 0 on success, -1 for errors. */ * actual length. Returns 0 on success, -1 for errors. */
extern int _slurm_getsockopt (int __fd, int __level, int __optname, void *__restrict __optval, socklen_t *__restrict __optlen) extern int _slurm_getsockopt (int __fd, int __level, int __optname,
void *__restrict __optval,
socklen_t *__restrict __optlen)
{ {
return getsockopt ( __fd , __level , __optname , __optval , __optlen ) ; return getsockopt ( __fd , __level , __optname , __optval , __optlen ) ;
} }
...@@ -649,7 +712,8 @@ extern int _slurm_getsockopt (int __fd, int __level, int __optname, void *__rest ...@@ -649,7 +712,8 @@ extern int _slurm_getsockopt (int __fd, int __level, int __optname, void *__rest
/* Set socket FD's option OPTNAME at protocol level LEVEL /* Set socket FD's option OPTNAME at protocol level LEVEL
* to *OPTVAL (which is OPTLEN bytes long). * to *OPTVAL (which is OPTLEN bytes long).
* Returns 0 on success, -1 for errors. */ * Returns 0 on success, -1 for errors. */
extern int _slurm_setsockopt (int __fd, int __level, int __optname, __const void *__optval, socklen_t __optlen) extern int _slurm_setsockopt (int __fd, int __level, int __optname,
__const void *__optval, socklen_t __optlen)
{ {
return setsockopt ( __fd , __level , __optname , __optval , __optlen ) ; return setsockopt ( __fd , __level , __optname , __optval , __optlen ) ;
} }
...@@ -668,7 +732,8 @@ extern int _slurm_listen (int __fd, int __n) ...@@ -668,7 +732,8 @@ extern int _slurm_listen (int __fd, int __n)
* set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting * set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting
* peer and *ADDR_LEN to the address's actual length, and return the * peer and *ADDR_LEN to the address's actual length, and return the
* new socket's descriptor, or -1 for errors. */ * new socket's descriptor, or -1 for errors. */
extern int _slurm_accept (int __fd, struct sockaddr * __addr, socklen_t *__restrict __addr_len) extern int _slurm_accept (int __fd, struct sockaddr * __addr,
socklen_t *__restrict __addr_len)
{ {
return accept ( __fd , __addr , __addr_len ) ; return accept ( __fd , __addr , __addr_len ) ;
} }
...@@ -689,7 +754,8 @@ extern int _slurm_close (int __fd ) ...@@ -689,7 +754,8 @@ extern int _slurm_close (int __fd )
return close ( __fd ) ; return close ( __fd ) ;
} }
extern int _slurm_select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) extern int _slurm_select(int n, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout)
{ {
assert (n <= FD_SETSIZE); /* select data structure overflows */; assert (n <= FD_SETSIZE); /* select data structure overflows */;
return select ( n , readfds , writefds , exceptfds , timeout ) ; return select ( n , readfds , writefds , exceptfds , timeout ) ;
...@@ -745,14 +811,15 @@ extern int _slurm_vfcntl(int fd, int cmd, va_list va ) ...@@ -745,14 +811,15 @@ extern int _slurm_vfcntl(int fd, int cmd, va_list va )
} }
/* sets the fields of a slurm_addr */ /* sets the fields of a slurm_addr */
void _slurm_set_addr_uint ( slurm_addr * slurm_address , uint16_t port , uint32_t ip_address ) void _slurm_set_addr_uint ( slurm_addr * slurm_address , uint16_t port ,
uint32_t ip_address )
{ {
slurm_address -> sin_family = AF_SLURM ; slurm_address -> sin_family = AF_SLURM ;
slurm_address -> sin_port = htons ( port ) ; slurm_address -> sin_port = htons ( port ) ;
slurm_address -> sin_addr.s_addr = htonl ( ip_address ) ; slurm_address -> sin_addr.s_addr = htonl ( ip_address ) ;
} }
/* resets the address field of a slurm_addr, port and family remain unchanged */ /* resets the address field of a slurm_addr, port and family are unchanged */
void _reset_slurm_addr ( slurm_addr * slurm_address , slurm_addr new_address ) void _reset_slurm_addr ( slurm_addr * slurm_address , slurm_addr new_address )
{ {
slurm_address -> sin_addr.s_addr = new_address.sin_addr.s_addr ; slurm_address -> sin_addr.s_addr = new_address.sin_addr.s_addr ;
...@@ -763,31 +830,49 @@ void _slurm_set_addr ( slurm_addr * slurm_address , uint16_t port , char * host ...@@ -763,31 +830,49 @@ void _slurm_set_addr ( slurm_addr * slurm_address , uint16_t port , char * host
{ {
_slurm_set_addr_char ( slurm_address , port , host ) ; _slurm_set_addr_char ( slurm_address , port , host ) ;
} }
void _slurm_set_addr_char ( slurm_addr * slurm_address , uint16_t port , char * host ) void _slurm_set_addr_char ( slurm_addr * slurm_address , uint16_t port ,
char * host )
{ {
/* If NULL hostname passed in, we only update the port /* If NULL hostname passed in, we only update the port
* of slurm_address * of slurm_address
*/ */
if (host != NULL) { if (host != NULL) {
struct hostent * host_info = gethostbyname( host ); struct hostent * host_info;
char hostent_buf[TEMP_BUFFER_SIZE];
host_info = get_host_by_name( host, (void *) &hostent_buf,
sizeof(hostent_buf), NULL );
if (host_info == NULL) { if (host_info == NULL) {
error ("gethostbyname failure on %s", host); fatal ("get_host_by_name failure on %s", host);
slurm_address->sin_family = 0; slurm_address->sin_family = 0;
slurm_address->sin_port = 0; slurm_address->sin_port = 0;
return; return;
} }
memcpy ( & slurm_address -> sin_addr . s_addr , memcpy ( & slurm_address -> sin_addr . s_addr ,
host_info -> h_addr , host_info -> h_length ) ; host_info -> h_addr , host_info -> h_length ) ;
} }
slurm_address -> sin_family = AF_SLURM ; slurm_address -> sin_family = AF_SLURM ;
slurm_address -> sin_port = htons ( port ) ; slurm_address -> sin_port = htons ( port ) ;
} }
void _slurm_get_addr ( slurm_addr * slurm_address , uint16_t * port , char * host , unsigned int buf_len ) void _slurm_get_addr ( slurm_addr * slurm_address , uint16_t * port ,
{ char * host , unsigned int buf_len )
struct hostent * host_info = gethostbyaddr ( ( char * ) &( slurm_address -> sin_addr . s_addr ) , sizeof ( slurm_address -> sin_addr . s_addr ) , AF_SLURM ) ; {
*port = slurm_address -> sin_port ; struct hostent * host_info;
strncpy ( host , host_info -> h_name , buf_len ) ; char hostent_buf[TEMP_BUFFER_SIZE];
host_info = get_host_by_addr (
( char * ) &( slurm_address -> sin_addr . s_addr ) ,
sizeof ( slurm_address -> sin_addr . s_addr ) ,
AF_SLURM,
(void *) &hostent_buf, sizeof(hostent_buf), NULL );
if (host_info == NULL) {
fatal ("get_host_by_addr failure");
*port = 0;
strncpy ( host, "", buf_len);
} else {
*port = slurm_address -> sin_port ;
strncpy ( host , host_info -> h_name , buf_len ) ;
}
} }
void _slurm_print_slurm_addr ( slurm_addr * address, char *buf, size_t n ) void _slurm_print_slurm_addr ( slurm_addr * address, char *buf, size_t n )
...@@ -808,7 +893,8 @@ int _slurm_unpack_slurm_addr_no_alloc ( slurm_addr * slurm_address , Buf buffer ...@@ -808,7 +893,8 @@ int _slurm_unpack_slurm_addr_no_alloc ( slurm_addr * slurm_address , Buf buffer
{ {
slurm_address -> sin_family = AF_SLURM ; slurm_address -> sin_family = AF_SLURM ;
safe_unpack32 ( & slurm_address -> sin_addr.s_addr , buffer ) ; safe_unpack32 ( & slurm_address -> sin_addr.s_addr , buffer ) ;
slurm_address -> sin_addr.s_addr = htonl ( slurm_address -> sin_addr.s_addr ); slurm_address -> sin_addr.s_addr =
htonl ( slurm_address -> sin_addr.s_addr );
safe_unpack16 ( & slurm_address -> sin_port , buffer ) ; safe_unpack16 ( & slurm_address -> sin_port , buffer ) ;
slurm_address -> sin_port = htons ( slurm_address -> sin_port ) ; slurm_address -> sin_port = htons ( slurm_address -> sin_port ) ;
return SLURM_SUCCESS; return SLURM_SUCCESS;
......
/*****************************************************************************\
* $Id$
*****************************************************************************
* Copyright (C) 2001-2002 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Chris Dunlap <cdunlap@llnl.gov>.
* UCRL-CODE-2002-009.
*
* This file is part of ConMan, a remote console management program.
* For details, see <http://www.llnl.gov/linux/conman/>.
*
* ConMan is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* ConMan is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along
* with ConMan; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*****************************************************************************
* Refer to "util-net.h" for documentation on public functions.
\*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include "strlcpy.h"
#include "util-net.h"
#include "wrapper.h"
#ifndef INET_ADDRSTRLEN
# define INET_ADDRSTRLEN 16
#endif /* !INET_ADDRSTRLEN */
static pthread_mutex_t hostentLock = PTHREAD_MUTEX_INITIALIZER;
static int copy_hostent(const struct hostent *src, char *dst, int len);
#ifndef NDEBUG
static int validate_hostent_copy(
const struct hostent *src, const struct hostent *dst);
#endif /* !NDEBUG */
struct hostent * get_host_by_name(const char *name,
void *buf, int buflen, int *h_err)
{
/* gethostbyname() is not thread-safe, and there is no frelling standard
* for gethostbyname_r() -- the arg list varies from system to system!
*/
struct hostent *hptr;
int n = 0;
assert(name != NULL);
assert(buf != NULL);
x_pthread_mutex_lock(&hostentLock);
if ((hptr = gethostbyname(name)))
n = copy_hostent(hptr, buf, buflen);
if (h_err)
*h_err = h_errno;
x_pthread_mutex_unlock(&hostentLock);
if (n < 0) {
errno = ERANGE;
return(NULL);
}
return(hptr ? (struct hostent *) buf : NULL);
}
struct hostent * get_host_by_addr(const char *addr, int len, int type,
void *buf, int buflen, int *h_err)
{
/* gethostbyaddr() is not thread-safe, and there is no frelling standard
* for gethostbyaddr_r() -- the arg list varies from system to system!
*/
struct hostent *hptr;
int n = 0;
assert(addr != NULL);
assert(buf != NULL);
x_pthread_mutex_lock(&hostentLock);
if ((hptr = gethostbyaddr(addr, len, type)))
n = copy_hostent(hptr, buf, buflen);
if (h_err)
*h_err = h_errno;
x_pthread_mutex_unlock(&hostentLock);
if (n < 0) {
errno = ERANGE;
return(NULL);
}
return(hptr ? (struct hostent *) buf : NULL);
}
const char * host_strerror(int h_err)
{
if (h_err == HOST_NOT_FOUND)
return("Unknown host");
else if (h_err == TRY_AGAIN)
return("Transient host name lookup failure");
else if (h_err == NO_RECOVERY)
return("Unknown server error");
else if ((h_err == NO_ADDRESS) || (h_err == NO_DATA))
return("No address associated with name");
return("Unknown error");
}
int host_name_to_addr4(const char *name, struct in_addr *addr)
{
struct hostent *hptr;
unsigned char buf[HOSTENT_SIZE];
assert(name != NULL);
assert(addr != NULL);
if (!(hptr = get_host_by_name(name, buf, sizeof(buf), NULL)))
return(-1);
if (hptr->h_length > 4) {
errno = ERANGE;
return(-1);
}
memcpy(addr, hptr->h_addr_list[0], hptr->h_length);
return(0);
}
char * host_addr4_to_name(const struct in_addr *addr, char *dst, int dstlen)
{
struct hostent *hptr;
unsigned char buf[HOSTENT_SIZE];
assert(addr != NULL);
assert(dst != NULL);
if (!(hptr = get_host_by_addr((char *) addr, 4, AF_INET,
buf, sizeof(buf), NULL)))
return(NULL);
if (strlen(hptr->h_name) >= dstlen) {
errno = ERANGE;
return(NULL);
}
strcpy(dst, hptr->h_name);
return(dst);
}
char * host_name_to_cname(const char *src, char *dst, int dstlen)
{
struct hostent *hptr;
unsigned char buf[HOSTENT_SIZE];
struct in_addr addr;
assert(src != NULL);
assert(dst != NULL);
if (!(hptr = get_host_by_name(src, buf, sizeof(buf), NULL)))
return(NULL);
/*
* If 'src' is an ip-addr string, it will simply be copied to h_name.
* So, we need to perform a reverse query based on the in_addr
* in order to obtain the canonical name of the host.
* Besides, this additional query helps protect against DNS spoofing.
*/
memcpy(&addr, hptr->h_addr_list[0], hptr->h_length);
if (!(hptr = get_host_by_addr((char *) &addr, 4, AF_INET,
buf, sizeof(buf), NULL)))
return(NULL);
if (strlen(hptr->h_name) >= dstlen) {
errno = ERANGE;
return(NULL);
}
strcpy(dst, hptr->h_name);
return(dst);
}
static int copy_hostent(const struct hostent *src, char *buf, int len)
{
/* Copies the (src) hostent struct (and all of its associated data)
* into the buffer (buf) of length (len).
* Returns 0 if the copy is successful, or -1 if the length of the buffer
* is not large enough to hold the result.
*
* Note that the order in which data is copied into (buf) is done
* in such a way as to ensure everything is properly word-aligned.
* There is a method to the madness.
*/
struct hostent *dst;
int n;
char **p, **q;
assert(src != NULL);
assert(buf != NULL);
dst = (struct hostent *) buf;
if ((len -= sizeof(struct hostent)) < 0)
return(-1);
dst->h_addrtype = src->h_addrtype;
dst->h_length = src->h_length;
buf += sizeof(struct hostent);
/* Reserve space for h_aliases[].
*/
dst->h_aliases = (char **) buf;
for (p=src->h_aliases, q=dst->h_aliases, n=0; *p; p++, q++, n++) {;}
if ((len -= ++n * sizeof(char *)) < 0)
return(-1);
buf = (char *) (q + 1);
/* Reserve space for h_addr_list[].
*/
dst->h_addr_list = (char **) buf;
for (p=src->h_addr_list, q=dst->h_addr_list, n=0; *p; p++, q++, n++) {;}
if ((len -= ++n * sizeof(char *)) < 0)
return(-1);
buf = (char *) (q + 1);
/* Copy h_addr_list[] in_addr structs.
*/
for (p=src->h_addr_list, q=dst->h_addr_list; *p; p++, q++) {
if ((len -= src->h_length) < 0)
return(-1);
memcpy(buf, *p, src->h_length);
*q = buf;
buf += src->h_length;
}
*q = NULL;
/* Copy h_aliases[] strings.
*/
for (p=src->h_aliases, q=dst->h_aliases; *p; p++, q++) {
n = strlcpy(buf, *p, len);
*q = buf;
buf += ++n; /* allow for trailing NUL char */
if ((len -= n) < 0)
return(-1);
}
*q = NULL;
/* Copy h_name string.
*/
dst->h_name = buf;
n = strlcpy(buf, src->h_name, len);
buf += ++n; /* allow for trailing NUL char */
if ((len -= n) < 0)
return(-1);
assert(validate_hostent_copy(src, dst) >= 0);
return(0);
}
#ifndef NDEBUG
static int validate_hostent_copy(
const struct hostent *src, const struct hostent *dst)
{
/* Validates the src hostent struct has been successfully copied into dst.
* Returns 0 if the copy is good; o/w, returns -1.
*/
char **p, **q;
assert(src != NULL);
assert(dst != NULL);
if (!dst->h_name)
return(-1);
if (src->h_name == dst->h_name)
return(-1);
if (strcmp(src->h_name, dst->h_name))
return(-1);
if (src->h_addrtype != dst->h_addrtype)
return(-1);
if (src->h_length != dst->h_length)
return(-1);
for (p=src->h_aliases, q=dst->h_aliases; *p; p++, q++)
if ((!q) || (p == q) || (strcmp(*p, *q)))
return(-1);
for (p=src->h_addr_list, q=dst->h_addr_list; *p; p++, q++)
if ((!q) || (p == q) || (memcmp(*p, *q, src->h_length)))
return(-1);
return(0);
}
#endif /* !NDEBUG */
#ifndef HAVE_INET_PTON
int inet_pton(int family, const char *str, void *addr)
{
/* cf. Stevens UNPv1 p72.
*/
struct in_addr tmpaddr;
if (family != AF_INET) {
errno = EAFNOSUPPORT;
return(-1);
}
#ifdef HAVE_INET_ATON
if (!inet_aton(str, &tmpaddr))
return(0);
#else /* !HAVE_INET_ATON */
if ((tmpaddr.s_addr = inet_addr(str)) == -1)
return(0);
#endif /* !HAVE_INET_ATON */
memcpy(addr, &tmpaddr, sizeof(struct in_addr));
return(1);
}
#endif /* !HAVE_INET_PTON */
#ifndef HAVE_INET_NTOP
const char * inet_ntop(int family, const void *addr, char *str, size_t len)
{
/* cf. Stevens UNPv1 p72.
*/
const unsigned char *p = (const unsigned char *) addr;
char tmpstr[INET_ADDRSTRLEN];
assert(str != NULL);
if (family != AF_INET) {
errno = EAFNOSUPPORT;
return(NULL);
}
snprintf(tmpstr, sizeof(tmpstr), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
if (strlen(tmpstr) >= len) {
errno = ENOSPC;
return(NULL);
}
strcpy(str, tmpstr);
return(str);
}
#endif /* !HAVE_INET_NTOP */
/*****************************************************************************\
* $Id$
*****************************************************************************
* Copyright (C) 2001-2002 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Chris Dunlap <cdunlap@llnl.gov>.
* UCRL-CODE-2002-009.
*
* This file is part of ConMan, a remote console management program.
* For details, see <http://www.llnl.gov/linux/conman/>.
*
* ConMan is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* ConMan is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along
* with ConMan; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#ifndef _UTIL_NET_H
#define _UTIL_NET_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#define HOSTENT_SIZE 8192 /* cf. Stevens UNPv1 11.15 p304 */
struct hostent * get_host_by_name(const char *name,
void *buf, int buflen, int *h_err);
/*
* A portable thread-safe alternative to be used in place of gethostbyname().
* The result is stored in the buffer (buf) of length (buflen); if the buffer
* is too small to hold the result, NULL is returned with errno = ERANGE.
* Returns a ptr into (buf) on success; returns NULL on error, setting the
* (h_err) variable reference (if not NULL) to indicate the h_error.
*/
struct hostent * get_host_by_addr(const char *addr, int len, int type,
void *buf, int buflen, int *h_err);
/*
* A portable thread-safe alternative to be used in place of gethostbyaddr().
* The result is stored in the buffer (buf) of length (buflen); if the buffer
* is too small to hold the result, NULL is returned with errno = ERANGE.
* Returns a ptr into (buf) on success; returns NULL on error, setting the
* (h_err) variable reference (if not NULL) to indicate the h_error.
*/
const char * host_strerror(int h_err);
/*
* Returns a string describing the error code (h_err) returned by
* get_host_by_name() or get_host_by_addr().
*/
int host_name_to_addr4(const char *name, struct in_addr *addr);
/*
* Converts the string (name) to an IPv4 address (addr).
* Returns 0 on success, or -1 on error.
* Note that this routine is thread-safe.
*/
char * host_addr4_to_name(const struct in_addr *addr, char *dst, int dstlen);
/*
* Converts an IPv4 address (addr) to a host name string residing in
* buffer (dst) of length (dstlen).
* Returns a ptr to the NULL-terminated string (dst) on success,
* or NULL on error.
* Note that this routine is thread-safe.
*/
char * host_name_to_cname(const char *src, char *dst, int dstlen);
/*
* Converts the hostname or IP address string (src) to the
* canonical name of the host residing in buffer (dst) of length (dstlen).
* Returns a ptr to the NULL-terminated string (dst) on success,
* or NULL on error.
* Note that this routine is thread-safe.
*/
#ifndef HAVE_INET_PTON
int inet_pton(int family, const char *str, void *addr);
/*
* Convert from presentation format of an internet number in (str)
* to the binary network format, storing the result for interface
* type (family) in the socket address structure specified by (addr).
* Returns 1 if OK, 0 if input not a valid presentation format, -1 on error.
*/
#endif /* !HAVE_INET_PTON */
#ifndef HAVE_INET_NTOP
const char * inet_ntop(int family, const void *addr, char *str, size_t len);
/*
* Convert an Internet address in binary network format for interface
* type (family) in the socket address structure specified by (addr),
* storing the result in the buffer (str) of length (len).
* Returns ptr to result buffer if OK, or NULL on error.
*/
#endif /* !HAVE_INET_NTOP */
#endif /* !_UTIL_NET_H */
/*****************************************************************************\
* $Id$
*****************************************************************************
* Copyright (C) 2001-2002 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Chris Dunlap <cdunlap@llnl.gov>.
* UCRL-CODE-2002-009.
*
* This file is part of ConMan, a remote console management program.
* For details, see <http://www.llnl.gov/linux/conman/>.
*
* ConMan is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* ConMan is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along
* with ConMan; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#ifndef _WRAPPER_H
#define _WRAPPER_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#include <errno.h>
#include "log.h"
#ifdef WITH_PTHREADS
# define x_pthread_mutex_init(MUTEX,ATTR) \
do { \
if ((errno = pthread_mutex_init((MUTEX), (ATTR))) != 0) \
error("pthread_mutex_init() failed: %m"); \
} while (0)
# define x_pthread_mutex_lock(MUTEX) \
do { \
if ((errno = pthread_mutex_lock(MUTEX)) != 0) \
error("pthread_mutex_lock() failed: %m"); \
} while (0)
# define x_pthread_mutex_unlock(MUTEX) \
do { \
if ((errno = pthread_mutex_unlock(MUTEX)) != 0) \
error("pthread_mutex_unlock() failed: %m"); \
} while (0)
# define x_pthread_mutex_destroy(MUTEX) \
do { \
if ((errno = pthread_mutex_destroy(MUTEX)) != 0) \
error("pthread_mutex_destroy() failed: %m"); \
} while (0)
# define x_pthread_detach(THREAD) \
do { \
if ((errno = pthread_detach(THREAD)) != 0) \
error("pthread_detach() failed: %m"); \
} while (0)
#else /* !WITH_PTHREADS */
# define x_pthread_mutex_init(MUTEX,ATTR)
# define x_pthread_mutex_lock(MUTEX)
# define x_pthread_mutex_unlock(MUTEX)
# define x_pthread_mutex_destroy(MUTEX)
# define x_pthread_detach(THREAD)
#endif /* !WITH_PTHREADS */
#endif /* !_WRAPPER_H */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment