28char* wchar_to_char(
const wchar_t* pwchar)
31 int currentCharIndex = 0;
32 char currentChar = pwchar[currentCharIndex];
33 char *filePathC = NULL ;
35 while (currentChar !=
'\0')
38 currentChar = pwchar[currentCharIndex];
41 const int charCount = currentCharIndex + 1;
44 Malloc( filePathC,
char, charCount );
47 for (
int i = 0; i < charCount; i++)
50 char character = pwchar[i];
52 *filePathC = character;
54 filePathC +=
sizeof(char);
59 filePathC -= (
sizeof(char) * charCount);
64#define neterrno WSAGetLastError()
66#define netstrerror( code )({ \
68 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, \
70 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), \
71 (LPWSTR)&s, 0, NULL); \
72 char *netstr = wchar_to_char( s ); \
78#if __GNUC__ <= 6 && __GNUC_MINOR__ <= 3
112size_t strlcpy(
char *dst,
const char *src,
size_t siz)
123 if ((*d++ = *s++) ==
'\0')
163static char *inet_ntop4(
const unsigned char *src,
char *dst, socklen_t size);
164static char *inet_ntop6(
const unsigned char *src,
char *dst, socklen_t size);
174char *inet_ntop(
int af,
const void *src,
char *dst, socklen_t size)
179 return (inet_ntop4((
const unsigned char*)src, dst, size));
181 return (inet_ntop6((
const unsigned char*)src, dst, size));
199static char *inet_ntop4(
const unsigned char *src,
char *dst, socklen_t size)
201 static const char fmt[] =
"%u.%u.%u.%u";
202 char tmp[
sizeof "255.255.255.255"];
205 l = snprintf(tmp,
sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
206 if (l <= 0 || (socklen_t) l >= size)
210 strlcpy(dst, tmp, size);
220static char *inet_ntop6(
const unsigned char *src,
char *dst, socklen_t size)
229 char tmp[
sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
234#define NS_IN6ADDRSZ 16
236 u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
244 memset(words,
'\0',
sizeof words);
245 for (i = 0; i < NS_IN6ADDRSZ; i++)
246 words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
251 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
256 cur.base = i, cur.len = 1;
264 if (best.base == -1 || cur.len > best.len)
272 if (best.base == -1 || cur.len > best.len)
275 if (best.base != -1 && best.len < 2)
282 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
285 if (best.base != -1 && i >= best.base &&
286 i < (best.base + best.len))
296 if (i == 6 && best.base == 0 && (best.len == 6 ||
297 (best.len == 7 && words[7] != 0x0001) ||
298 (best.len == 5 && words[5] == 0xffff)))
300 if (!inet_ntop4(src+12, tp,
sizeof tmp - (tp - tmp)))
305 tp += sprintf(tp,
"%x", words[i]);
308 if (best.base != -1 && (best.base + best.len) ==
309 (NS_IN6ADDRSZ / NS_INT16SZ))
316 if ((socklen_t)(tp - tmp) > size)
346static int inet_pton4(
const char *src, u_char *dst);
347static int inet_pton6(
const char *src, u_char *dst);
360int inet_pton(
int af,
const char *src,
void *dst)
365 return (inet_pton4(src, (
unsigned char *)dst));
367 return (inet_pton6(src, (
unsigned char *)dst));
384static int inet_pton4(
const char *src, u_char *dst)
386 static const char digits[] =
"0123456789";
387 int saw_digit, octets, ch;
389 u_char tmp[NS_INADDRSZ], *tp;
394 while ((ch = *src++) !=
'\0')
398 if ((pch = strchr(digits, ch)) != NULL)
400 u_int uiNew = *tp * 10 + (pch - digits);
402 if (saw_digit && *tp == 0)
414 else if (ch ==
'.' && saw_digit)
426 memcpy(dst, tmp, NS_INADDRSZ);
443static int inet_pton6(
const char *src, u_char *dst)
445 static const char xdigits_l[] =
"0123456789abcdef",
446 xdigits_u[] =
"0123456789ABCDEF";
447#define NS_IN6ADDRSZ 16
449 u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
451 int ch, seen_xdigits;
454 memset((tp = tmp),
'\0', NS_IN6ADDRSZ);
455 endp = tp + NS_IN6ADDRSZ;
464 while ((ch = *src++) !=
'\0')
466 const char *xdigits :
469 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
470 pch = strchr((xdigits = xdigits_u), ch);
474 val |= (pch - xdigits);
475 if (++seen_xdigits > 4)
489 else if (*src ==
'\0')
493 if (tp + NS_INT16SZ > endp)
495 *tp++ = (u_char) (val >> 8) & 0xff;
496 *tp++ = (u_char) val & 0xff;
501 if (ch ==
'.' && ((tp + NS_INADDRSZ) <= endp) &&
502 inet_pton4(curtok, tp) > 0)
512 if (tp + NS_INT16SZ > endp)
514 *tp++ = (u_char) (val >> 8) & 0xff;
515 *tp++ = (u_char) val & 0xff;
523 const int n = tp - colonp;
528 for (i = 1; i <= n; i++)
530 endp[- i] = colonp[n - i];
537 memcpy(dst, tmp, NS_IN6ADDRSZ);
545#include <sys/types.h>
550#define neterrno errno
565#define netstrerror( code )({ \
566 char *errmsg = NULL ; \
568 errmsg = strdup( strerror( code ) ); \
569 if( errno == ENOMEM ) \
584 int saved_errno = errno;
585 while(waitpid(-1, NULL, WNOHANG) > 0);
606 netw -> nb_pending = -1 ;
608 netw -> user_id = -1 ;
609 netw -> nb_running_threads = 0 ;
610 netw -> state = NETW_EXITED ;
611 netw -> threaded_engine_status = NETW_THR_ENGINE_STOPPED ;
614 netw -> link . sock = -1 ;
615 netw -> link . port =
616 netw -> link . ip = NULL ;
617 memset( &netw -> link . hints, 0,
sizeof(
struct addrinfo ) );
618 memset( &netw -> link . raddr, 0,
sizeof(
struct sockaddr_storage ) );
621 if ( pthread_mutex_init( &netw -> sendbolt, NULL ) != 0 )
623 n_log(
LOG_ERR,
"Error initializing netw -> sendbolt" );
628 if ( pthread_mutex_init( &netw -> recvbolt, NULL ) != 0 )
630 n_log(
LOG_ERR,
"Error initializing netw -> recvbolt" );
631 pthread_mutex_destroy( &netw -> sendbolt );
636 if ( pthread_mutex_init( &netw -> eventbolt, NULL ) != 0 )
638 n_log(
LOG_ERR,
"Error initializing netw -> eventbolt" );
639 pthread_mutex_destroy( &netw -> sendbolt );
640 pthread_mutex_destroy( &netw -> recvbolt );
645 if( sem_init(&netw -> send_blocker, 0, 0 ) != 0 )
647 n_log(
LOG_ERR,
"Error initializing netw -> eventbolt" );
648 pthread_mutex_destroy( &netw -> eventbolt );
649 pthread_mutex_destroy( &netw -> sendbolt );
650 pthread_mutex_destroy( &netw -> recvbolt );
656 if( ! netw -> recv_buf )
658 n_log(
LOG_ERR,
"Error when creating receive list with %d item limit", recv_list_limit );
663 if( !netw -> send_buf )
665 n_log(
LOG_ERR,
"Error when creating send list with %d item limit", send_list_limit );
676 netw -> addr_infos_loaded = 0 ;
677 netw -> send_queue_consecutive_wait = 0 ;
678 netw -> so_reuseaddr = -1 ;
679 netw -> tcpnodelay = -1 ;
680 netw -> so_sndbuf = -1 ;
681 netw -> so_rcvbuf = -1 ;
682 netw -> so_rcvtimeo = -1 ;
683 netw -> so_sndtimeo = -1 ;
684 netw -> so_linger = -1 ;
685 netw -> deplete_timeout = 0 ;
686 netw -> crypto_mode = NETW_CRYPTO_NONE ;
687 netw -> crypto_algo = NETW_ENCRYPT_NONE ;
692 netw -> link . is_blocking = 0 ;
706 return sa->sa_family == AF_INET
707 ? (
char *)&(((
struct sockaddr_in *)sa)->sin_addr)
708 : (
char *)&(((
struct sockaddr_in6 *)sa)->sin6_addr);
721 int compiler_warning_suppressor = 0 ;
722#if !defined( __linux__ ) && !defined( __sun ) && !defined( _AIX )
723 static WSADATA WSAdata;
724 static int WSA_IS_INITIALIZED = 0;
731 return WSA_IS_INITIALIZED;
735 if ( WSA_IS_INITIALIZED == 1 )
737 if ( ( WSAStartup( MAKEWORD( v1, v2 ), &WSAdata ) ) != 0 )
739 WSA_IS_INITIALIZED = 0;
744 WSA_IS_INITIALIZED = 1 ;
750 if ( WSA_IS_INITIALIZED == 0 )
752 if ( WSACleanup() == 0 )
754 WSA_IS_INITIALIZED = 0;
760 compiler_warning_suppressor = mode + v1 + v2 ;
761 compiler_warning_suppressor = TRUE ;
762 return compiler_warning_suppressor ;
778 char *errmsg = NULL ;
780#if defined(__linux__) || defined(__sun)
781 int flags = fcntl( netw -> link . sock, F_GETFL, 0 );
782 if ( (flags &O_NONBLOCK) && !is_blocking )
784 n_log(
LOG_DEBUG,
"socket %d was already in non-blocking mode", netw -> link . sock );
786 netw -> link. is_blocking = 0 ;
789 if (!(flags &O_NONBLOCK) && is_blocking )
792 netw -> link. is_blocking = 1 ;
793 n_log(
LOG_DEBUG,
"socket %d was already in blocking mode", netw -> link . sock );
796 if( fcntl(netw -> link . sock, F_SETFL, is_blocking ? flags ^ O_NONBLOCK : flags | O_NONBLOCK) == -1 )
800 n_log(
LOG_ERR,
"couldn't set blocking mode %d on %d: %s", is_blocking, netw -> link . sock,
_str( errmsg ) );
805 unsigned long int blocking = 1 - is_blocking ;
806 int res = ioctlsocket( netw -> link . sock, FIONBIO, &blocking );
808 if( res != NO_ERROR )
811 n_log(
LOG_ERR,
"ioctlsocket failed with error: %ld , neterrno: %s", res,
_str( errmsg ) );
817 netw -> link. is_blocking = is_blocking ;
835 char *errmsg = NULL ;
843 if ( setsockopt( netw -> link . sock, IPPROTO_TCP, TCP_NODELAY, (
const char * ) &value,
sizeof( value ) ) == -1 )
847 n_log(
LOG_ERR,
"Error from setsockopt(TCP_NODELAY) on socket %d. neterrno: %s", netw -> link . sock,
_str( errmsg ) );
852 netw -> tcpnodelay = value ;
858 if ( setsockopt ( netw -> link . sock, SOL_SOCKET, SO_SNDBUF, (
const char * ) &value,
sizeof( value ) ) == -1 )
862 n_log(
LOG_ERR,
"Error from setsockopt(SO_SNDBUF) on socket %d. neterrno: %s", netw -> link . sock,
_str( errmsg ) );
866 netw -> so_sndbuf = value ;
872 if ( setsockopt ( netw -> link . sock, SOL_SOCKET, SO_RCVBUF, (
const char * ) &value,
sizeof( value ) ) == -1 )
876 n_log(
LOG_ERR,
"Error from setsockopt(SO_RCVBUF) on socket %d. neterrno: %s", netw -> link . sock,
_str( errmsg ) );
881 netw -> so_rcvbuf = value ;
886 if ( setsockopt( netw -> link . sock, SOL_SOCKET, SO_REUSEADDR, (
char *)&value,
sizeof( value ) ) == -1 )
890 n_log(
LOG_ERR,
"Error from setsockopt(SO_REUSEADDR) on socket %d. neterrno: %s", netw -> link . sock,
_str( errmsg ) );
894 netw -> so_reuseaddr = value ;
904 else if( value == 0 )
915 if( setsockopt(netw -> link . sock, SOL_SOCKET, SO_LINGER, &ling,
sizeof( ling ) ) == -1 )
919 n_log(
LOG_ERR,
"Error from setsockopt(SO_LINGER) on socket %d. neterrno: %s", netw -> link . sock,
_str( errmsg ) );
924 if( setsockopt(netw -> link . sock, SOL_SOCKET, SO_LINGER, (
const char *)&ling,
sizeof( ling ) ) == -1 )
928 n_log(
LOG_ERR,
"Error from setsockopt(SO_LINGER) on socket %d. neterrno: %s", netw -> link . sock,
_str( errmsg ) );
933 netw -> so_linger = value ;
944 if( setsockopt(netw -> link . sock, SOL_SOCKET, SO_RCVTIMEO, (
const char*)&tv,
sizeof tv) == -1 )
948 n_log(
LOG_ERR,
"Error from setsockopt(SO_RCVTIMEO) on socket %d. neterrno: %s", netw -> link . sock,
_str( errmsg ) );
954 if( setsockopt(netw -> link . sock, SOL_SOCKET, SO_RCVTIMEO, (
const char*)&value,
sizeof value ) == -1 )
958 n_log(
LOG_ERR,
"Error from setsockopt(SO_RCVTIMEO) on socket %d. neterrno: %s", netw -> link . sock,
_str( errmsg ) );
964 netw -> so_rcvtimeo = value ;
975 if( setsockopt(netw -> link . sock, SOL_SOCKET, SO_SNDTIMEO, (
const char*)&tv,
sizeof tv) == -1 )
979 n_log(
LOG_ERR,
"Error from setsockopt(SO_SNDTIMEO) on socket %d. neterrno: %s", netw -> link . sock,
_str( errmsg ) );
985 if( setsockopt(netw -> link . sock, SOL_SOCKET, SO_SNDTIMEO, (
const char*)&value,
sizeof value ) == -1 )
989 n_log(
LOG_ERR,
"Error from setsockopt(SO_SNDTIMEO) on socket %d. neterrno: %s", netw -> link . sock,
_str( errmsg ) );
995 netw -> so_sndtimeo = value ;
998 netw -> deplete_timeout = value ;
1001 netw -> send_queue_consecutive_wait = value ;
1004 case TCP_USER_TIMEOUT:
1006 unsigned int timeout = 1000 * value ;
1007 if( setsockopt(netw -> link . sock, SOL_SOCKET, TCP_USER_TIMEOUT, (
const char*)&timeout,
sizeof timeout) == -1 )
1011 n_log(
LOG_ERR,
"Error from setsockopt(TCP_USER_TIMEOUT) on socket %d. neterrno: %s", netw -> link . sock,
_str( errmsg ) );
1019 if( setsockopt(netw -> link . sock, SOL_SOCKET, SO_KEEPALIVE, (
const char*)&value,
sizeof value) == -1 )
1023 n_log(
LOG_ERR,
"Error from setsockopt(SO_KEEPALIVE) on socket %d. neterrno: %s", netw -> link . sock,
_str( errmsg ) );
1030 n_log(
LOG_ERR,
"%d is not a supported setsockopt", optname );
1076static pthread_mutex_t *lockarray;
1078static void lock_callback(
int mode,
int type,
char *file,
int line)
1082 if(mode & CRYPTO_LOCK)
1084 pthread_mutex_lock(&(lockarray[type]));
1088 pthread_mutex_unlock(&(lockarray[type]));
1092static unsigned long thread_id(
void)
1096 ret = (
unsigned long)pthread_self();
1100static void init_locks(
void)
1104 lockarray = (pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() *
1105 sizeof(pthread_mutex_t));
1106 for(i = 0; i<CRYPTO_num_locks(); i++)
1108 pthread_mutex_init(&(lockarray[i]), NULL);
1111 CRYPTO_set_id_callback((
unsigned long (*)())thread_id);
1112 CRYPTO_set_locking_callback((
void (*)())lock_callback);
1115static void kill_locks(
void)
1119 CRYPTO_set_locking_callback(NULL);
1120 for(i = 0; i<CRYPTO_num_locks(); i++)
1121 pthread_mutex_destroy(&(lockarray[i]));
1123 OPENSSL_free(lockarray);
1131int netw_init_openssl(
void )
1133 static int OPENSSL_IS_INITIALIZED = 0;
1135 if ( OPENSSL_IS_INITIALIZED == 1 )
1140 SSL_load_error_strings();
1141 ERR_load_BIO_strings();
1142 OpenSSL_add_all_algorithms();
1143 OpenSSL_add_all_algorithms();
1147 OPENSSL_IS_INITIALIZED = 1 ;
1156int netw_init_openssl(
void )
1158 static int OPENSSL_IS_INITIALIZED = 0;
1160 if ( OPENSSL_IS_INITIALIZED == 1 )
1164 SSL_load_error_strings();
1166 ERR_load_BIO_strings();
1167 OpenSSL_add_all_algorithms();
1168 OpenSSL_add_all_algorithms();
1172 OPENSSL_IS_INITIALIZED = 1 ;
1177int netw_set_crypto(
NETWORK *netw,
char *key,
char *certificat,
char *vigenere )
1181 if( key && strlen( key ) > 0 )
1183 netw -> key = strdup( key );
1185 if( certificat && strlen( certificat ) > 0 )
1187 netw -> certificat = strdup( certificat );
1189 if( vigenere && strlen( vigenere ) > 0 )
1191 netw -> vigenere = strdup( vigenere );
1194 netw_init_openssl();
1196 netw -> method = TLSv1_2_method();
1197 netw -> ctx = SSL_CTX_new(method);
1200 unsigned long error = 0 ;
1201 while( error = ERR_get_error() )
1203 n_log(
LOG_ERR,
"%s on socket %d", ERR_reason_error_string( ERR_get_error(), NULL ) );
1206 EVP_CIPHER_CTX_free( netw -> ctx );
1228 int error = 0, net_status = 0;
1229 char *errmsg = NULL ;
1234 n_log(
LOG_ERR,
"Unable to allocate (*netw), already existing. You must use empty NETWORK *structs." );
1239 (*netw) =
netw_new( send_list_limit, recv_list_limit );
1253 (*netw) -> link . hints . ai_family = AF_INET ;
1257 (*netw) -> link . hints . ai_family = AF_INET6 ;
1262 (*netw) -> link . hints . ai_family = AF_UNSPEC;
1265 (*netw) -> link . hints . ai_socktype = SOCK_STREAM;
1266 (*netw) -> link . hints . ai_protocol = IPPROTO_TCP;
1267 (*netw) -> link . hints . ai_flags = AI_PASSIVE;
1268 (*netw) -> link . hints . ai_canonname = NULL;
1269 (*netw) -> link . hints . ai_next = NULL;
1274 error = getaddrinfo( host, port, &(*netw) -> link . hints, &(*netw) -> link . rhost );
1277 n_log(
LOG_ERR,
"Error when resolving %s:%s getaddrinfo: %s", host, port, gai_strerror( error ) );
1281 (*netw) -> addr_infos_loaded = 1 ;
1282 Malloc( (*netw) -> link . ip,
char, 64 );
1286 struct addrinfo *rp = NULL ;
1287 for( rp = (*netw) -> link . rhost ; rp != NULL ; rp = rp -> ai_next )
1289 int sock = socket( rp -> ai_family, rp -> ai_socktype, rp->ai_protocol );
1294 n_log(
LOG_ERR,
"Error while trying to make a socket: %s",
_str( errmsg ) );
1299 (*netw) -> link . sock = sock ;
1301 net_status = connect( sock, rp -> ai_addr, rp -> ai_addrlen );
1302 if( net_status == -1 )
1308 closesocket( sock );
1309 (*netw) -> link . sock = -1 ;
1315 if(!inet_ntop( rp->ai_family,
get_in_addr( rp -> ai_addr ), (*netw) -> link . ip, 64 ) )
1328 n_log(
LOG_ERR,
"Couldn't connect to %s:%s : no adress succeeded", host, port );
1333 (*netw)->link . port = strdup( port );
1337 (*netw) -> key = NULL ;
1338 (*netw) -> certificat = NULL ;
1341 (*netw) -> vigenere_key = NULL ;
1344 n_log(
LOG_DEBUG,
"Connected to %s:%s", (*netw) -> link . ip, (*netw) -> link . port );
1346 netw_set( (*netw), NETW_CLIENT|NETW_RUN|NETW_THR_ENGINE_STOPPED );
1380 pthread_mutex_lock( &netw -> sendbolt );
1382 (*state) = netw -> state ;
1383 if( thr_engine_status )
1384 (*thr_engine_status) = netw -> threaded_engine_status ;
1385 pthread_mutex_unlock( &netw -> sendbolt );
1390 n_log(
LOG_ERR,
"Can't get status of a NULL network" );
1405 if( flag & NETW_EMPTY_SENDBUF )
1407 pthread_mutex_lock( &netw -> sendbolt );
1408 if( netw -> send_buf )
1410 pthread_mutex_unlock( &netw -> sendbolt );
1412 if( flag & NETW_EMPTY_RECVBUF )
1414 pthread_mutex_lock( &netw -> recvbolt );
1415 if( netw -> recv_buf )
1417 pthread_mutex_unlock( &netw -> recvbolt );
1419 if( flag & NETW_DESTROY_SENDBUF )
1421 pthread_mutex_lock( &netw -> sendbolt );
1422 if( netw -> send_buf )
1424 pthread_mutex_unlock( &netw -> sendbolt );
1426 if( flag & NETW_DESTROY_RECVBUF )
1428 pthread_mutex_lock( &netw -> recvbolt );
1429 if( netw -> recv_buf )
1431 pthread_mutex_unlock( &netw -> recvbolt );
1433 pthread_mutex_lock( &netw -> eventbolt );
1434 if( flag & NETW_CLIENT )
1436 netw -> mode = NETW_CLIENT ;
1438 if( flag & NETW_SERVER )
1440 netw -> mode = NETW_SERVER ;
1442 if( flag & NETW_RUN )
1444 netw -> state = NETW_RUN ;
1446 if( flag & NETW_EXITED )
1448 netw -> state = NETW_EXITED ;
1450 if( flag & NETW_ERROR )
1452 netw -> state = NETW_ERROR ;
1454 if( flag & NETW_EXIT_ASKED )
1456 netw -> state = NETW_EXIT_ASKED ;
1458 if( flag & NETW_THR_ENGINE_STARTED )
1460 netw -> threaded_engine_status = NETW_THR_ENGINE_STARTED ;
1462 if( flag & NETW_THR_ENGINE_STOPPED )
1464 netw -> threaded_engine_status = NETW_THR_ENGINE_STOPPED ;
1466 pthread_mutex_unlock( &netw -> eventbolt );
1468 sem_post( &netw -> send_blocker );
1482 int state = 0, thr_engine_status = 0 ;
1494 if( thr_engine_status == NETW_THR_ENGINE_STARTED )
1501 if( (*netw) -> link . sock != INVALID_SOCKET )
1503 closesocket( (*netw) -> link . sock );
1515 if( (*netw) -> link . rhost )
1517 freeaddrinfo( (*netw) -> link . rhost );
1521 netw_set( (*netw), NETW_DESTROY_SENDBUF|NETW_DESTROY_RECVBUF );
1523 pthread_mutex_destroy( &(*netw) -> recvbolt );
1524 pthread_mutex_destroy( &(*netw) -> sendbolt );
1525 pthread_mutex_destroy( &(*netw) -> eventbolt );
1526 sem_destroy( &(*netw) -> send_blocker );
1543#if defined( __linux__ )
1544 int outstanding = 0 ;
1549 for(
size_t it = 0 ; it < timeout ; it += 100 )
1552 ioctl(fd, SIOCOUTQ, &outstanding);
1559 return outstanding ;
1591 int state = 0, thr_engine_status = 0 ;
1595 size_t countdown = timeout * 1000000 ;
1596 char *errmsg = NULL ;
1597 int nb_running = 0 ;
1600 if( thr_engine_status == NETW_THR_ENGINE_STARTED )
1604 pthread_mutex_lock( &(*netw) -> eventbolt );
1605 nb_running = (*netw) -> nb_running_threads ;
1606 pthread_mutex_unlock( &(*netw) -> eventbolt );
1608 countdown -= 100000 ;
1610 while( nb_running > 0 && countdown > 0 );
1612 if( countdown == 0 && nb_running > 0 )
1614 n_log(
LOG_ERR,
"netw %d: %d threads are still running after %d seconds, netw is in state %s (%d)", (*netw) -> link . sock, nb_running, timeout,
N_ENUM_ENTRY(__netw_code_type,toString)(state), state );
1619 if( (*netw) -> link . sock != INVALID_SOCKET )
1622 shutdown( (*netw) -> link . sock, SHUT_WR );
1623 int remaining =
deplete_send_buffer( (*netw) -> link . sock, (*netw) -> deplete_timeout );
1626 n_log(
LOG_ERR,
"socket %d (%s:%s) %d octets still in send buffer before closing after a wait of %d seconds", (*netw) -> link . sock, (*netw) -> link . ip, (*netw) -> link . port, remaining, (
int)(*netw) -> deplete_timeout );
1629 char buffer[ 4096 ] =
"" ;
1630 for(
size_t it = 0 ; it < (timeout*1000000) ; it += 100000 )
1633 res = recv( (*netw) -> link . sock, buffer, 4096, NETFLAGS );
1639 if( error != ENOTCONN && error != 10057 && error != EINTR && error != ECONNRESET )
1642 n_log(
LOG_ERR,
"read returned error %d when closing socket %d (%s:%s): %s", error, (*netw) -> link . sock,
_str( (*netw) -> link . ip ), (*netw) -> link . port,
_str( errmsg ) );
1670 char *errmsg = NULL ;
1674 n_log(
LOG_ERR,
"Cannot use an allocated network. Please pass a NULL network to modify" );
1686 (*netw) -> link . port = strdup( port );
1690 (*netw) -> link . hints . ai_family = AF_INET ;
1694 (*netw) -> link . hints . ai_family = AF_INET6 ;
1699 (*netw) -> link . hints . ai_family = AF_UNSPEC;
1703 (*netw) -> link . hints . ai_flags = AI_PASSIVE;
1705 (*netw) -> link . hints . ai_socktype = SOCK_STREAM;
1706 (*netw) -> link . hints . ai_protocol = IPPROTO_TCP;
1707 (*netw) -> link . hints . ai_canonname = NULL;
1708 (*netw) -> link . hints . ai_next = NULL;
1710 error = getaddrinfo( addr, port, &(*netw) -> link . hints, &(*netw) -> link . rhost );
1713 n_log(
LOG_ERR,
"Error when resolving %s:%s getaddrinfo: %s",
_str( addr ), port, gai_strerror( error ) );
1717 (*netw) -> addr_infos_loaded = 1 ;
1723 struct addrinfo *rp = NULL ;
1724 for( rp = (*netw) -> link . rhost ; rp != NULL ; rp = rp -> ai_next )
1726 (*netw) -> link . sock = socket( rp -> ai_family, rp -> ai_socktype, rp->ai_protocol );
1727 if( (*netw) -> link . sock == INVALID_SOCKET )
1731 n_log(
LOG_ERR,
"Error while trying to make a socket: %s",
_str( errmsg ) );
1736 if( bind( (*netw) -> link . sock, rp -> ai_addr, rp -> ai_addrlen ) == 0 )
1746 if( !inet_ntop( rp -> ai_family,
get_in_addr( rp -> ai_addr ), ip, 64 ) )
1750 n_log(
LOG_ERR,
"inet_ntop: %p , %s", (*netw) -> link . raddr,
_str( errmsg ) );
1754 (*netw) -> link . ip = ip ;
1761 closesocket( (*netw) -> link .sock );
1766 n_log(
LOG_ERR,
"Couldn't get a socket for listening on port %s", port );
1772 ( *netw ) -> nb_pending = nbpending ;
1773 listen( ( *netw ) -> link . sock, ( *netw ) -> nb_pending );
1775 netw_set( (*netw), NETW_SERVER|NETW_RUN|NETW_THR_ENGINE_STOPPED );
1793 int tmp = 0, error = 0;
1794 char *errmsg = NULL ;
1796#if defined( __linux__ ) || defined( __sun ) || defined( _AIX )
1797 socklen_t sin_size = 0 ;
1813 netw =
netw_new( send_list_limit, recv_list_limit );
1815 sin_size =
sizeof( netw -> link . raddr );
1817 if( non_blocking > 0 )
1819 int secs = non_blocking/1000 ;
1820 int usecs = (non_blocking%1000)*1000;
1821 struct timeval select_timeout = { secs, usecs };
1824 FD_SET( from -> link . sock, &accept_set );
1825 FD_ZERO( &accept_set );
1827 int ret = select( from -> link . sock + 1, &accept_set, NULL, NULL, &select_timeout );
1832 if( retval != NULL )
1834 n_log(
LOG_ERR,
"Error on select with timeout %ds (%d.%ds), neterrno: %s", non_blocking, secs, usecs,
_str( errmsg ) );
1846 if( FD_ISSET( from -> link . sock, &accept_set ) )
1849 tmp = accept( from -> link . sock, (
struct sockaddr * )&netw -> link . raddr, &sin_size );
1854 if( retval != NULL )
1856 n_log(
LOG_DEBUG,
"error accepting on %d, %s", netw -> link . sock,
_str( errmsg ) );
1867 netw -> link . is_blocking = 0 ;
1869 else if( non_blocking == -1 )
1871 if( from -> link . is_blocking == 1 )
1874 n_log(
LOG_INFO,
"changed to non blocking accept call on %d", from -> link . sock );
1876 tmp = accept( from -> link . sock, (
struct sockaddr *)&netw -> link . raddr, &sin_size );
1878 if( retval != NULL )
1886 netw -> link . is_blocking = 0 ;
1890 if( from -> link . is_blocking == 0 )
1893 n_log(
LOG_DEBUG,
"(default) blocking accept call on socket %d", from -> link . sock );
1895 tmp = accept( from -> link . sock, (
struct sockaddr *)&netw -> link . raddr, &sin_size );
1900 n_log(
LOG_ERR,
"error accepting on socket %d, %s", netw -> link . sock,
_str( errmsg ) );
1905 netw -> link . is_blocking = 0 ;
1907 netw -> link . sock = tmp ;
1908 netw -> link . port = strdup( from -> link . port );
1909 Malloc( netw -> link . ip,
char, 64 );
1910 if( !netw -> link . ip )
1916 if( !inet_ntop( netw -> link . raddr . ss_family,
get_in_addr( ((
struct sockaddr *)&netw -> link . raddr) ), netw -> link . ip, 64 ) )
1920 n_log(
LOG_ERR,
"inet_ntop: %p , %s", netw -> link . raddr,
_str( errmsg ) );
1925 netw_set( netw, NETW_SERVER|NETW_RUN|NETW_THR_ENGINE_STOPPED );
1926 n_log(
LOG_DEBUG,
"Connection accepted from %s:%s socket %d", netw-> link . ip, netw -> link . port , netw -> link . sock );
1971 if( msg -> length <= 0 )
1973 n_log(
LOG_ERR,
"Empty messages are not supported. msg(%p)->lenght=%d", msg, msg -> length );
1977 pthread_mutex_lock( &netw -> sendbolt );
1981 pthread_mutex_unlock( &netw -> sendbolt );
1985 pthread_mutex_unlock( &netw -> sendbolt );
1987 sem_post( &netw -> send_blocker );
2010 N_STR *nstr = NULL ;
2016 n_log(
LOG_ERR,
"Empty messages are not supported. msg(%p)->lenght=%d", str, length );
2020 nstr -> data = str ;
2021 nstr -> written = nstr -> length = length ;
2023 pthread_mutex_lock( &netw -> sendbolt );
2026 pthread_mutex_unlock( &netw -> sendbolt );
2029 pthread_mutex_unlock( &netw -> sendbolt );
2031 sem_post( &netw -> send_blocker );
2046 N_STR * ptr = NULL ;
2050 pthread_mutex_lock( &netw -> recvbolt );
2054 pthread_mutex_unlock( &netw -> recvbolt );
2070 N_STR *nstrptr = NULL ;
2078 if( refresh > 999999 )
2080 secs = refresh / 1000000 ;
2081 usecs = refresh % 1000000 ;
2087 int state = NETW_RUN, thr_state = 0 ;
2096 if( timed >= refresh )
2098 if( timed == 0 || timed < refresh )
2100 n_log(
LOG_ERR,
"netw %d, status: %s (%d), timeouted after waiting %zu msecs", netw -> link . sock,
N_ENUM_ENTRY(__netw_code_type,toString)(state), state, timeout );
2111 while( state != NETW_EXITED && state != NETW_ERROR );
2113 n_log(
LOG_ERR,
"got no answer and netw %d is no more running, state: %s (%d)" , netw -> link . sock,
N_ENUM_ENTRY(__netw_code_type,toString)(state), state);
2129 pthread_mutex_lock( &netw -> eventbolt );
2130 if( netw -> threaded_engine_status == NETW_THR_ENGINE_STARTED )
2132 n_log(
LOG_ERR,
"THR Engine already started for network %p (%s)", netw,
_str( netw -> link . ip ) );
2133 pthread_mutex_unlock( &netw -> eventbolt );
2137 if( pthread_create( &netw -> recv_thr, NULL,
netw_recv_func, (
void *) netw ) != 0 )
2139 n_log(
LOG_ERR,
"Unable to create recv_thread for network %p (%s)", netw,
_str( netw -> link . ip ) );
2140 pthread_mutex_unlock( &netw -> eventbolt );
2143 netw -> nb_running_threads ++ ;
2144 if( pthread_create( &netw -> send_thr, NULL,
netw_send_func, (
void *) netw ) != 0 )
2146 n_log(
LOG_ERR,
"Unable to create send_thread for network %p (%s)", netw,
_str( netw -> link . ip ) );
2147 pthread_mutex_unlock( &netw -> eventbolt );
2150 netw -> nb_running_threads ++ ;
2152 netw -> threaded_engine_status = NETW_THR_ENGINE_STARTED ;
2154 pthread_mutex_unlock( &netw -> eventbolt );
2172 int32_t nboctet = 0 ;
2174 char nboct[ 5 ] =
"" ;
2185 sem_wait( &netw -> send_blocker );
2186 int message_sent = 0 ;
2187 while( message_sent == 0 && !DONE )
2190 if( state&NETW_ERROR )
2194 else if( state&NETW_EXITED )
2198 else if( state&NETW_EXIT_ASKED )
2202 nboctet = htonl( NETW_EXIT_ASKED );
2203 memcpy( nboct, &nboctet,
sizeof( int32_t ) );
2205 net_status = netw->
send_data( netw -> link . sock, nboct,
sizeof( int32_t ) );
2206 if( net_status < 0 )
2212 pthread_mutex_lock( &netw -> sendbolt );
2214 pthread_mutex_unlock( &netw -> sendbolt );
2215 if( ptr && ptr -> length > 0 && ptr -> data )
2217 n_log(
LOG_DEBUG,
"Sending ptr size %d written %d", ptr -> length, ptr -> written );
2220 nboctet = htonl( state );
2221 memcpy( nboct, &nboctet,
sizeof( int32_t ) );
2225 net_status = netw->
send_data( netw -> link . sock, nboct,
sizeof( int32_t ) );
2226 if( net_status < 0 )
2232 nboctet = htonl( ptr -> written );
2233 memcpy( nboct, &nboctet,
sizeof( int32_t ) );
2235 net_status = netw->
send_data( netw -> link . sock, nboct,
sizeof( int32_t ) );
2236 if( net_status < 0 )
2242 net_status = netw->
send_data( netw -> link . sock, ptr -> data, ptr -> written );
2243 if( net_status < 0 )
2247 u_sleep( netw -> send_queue_consecutive_wait );
2256 n_log(
LOG_ERR,
"Error when sending state %d on socket %d (%s), network: %s", netw -> state, netw -> link . sock,
_str( netw -> link . ip ), (net_status==-2)?
"disconnected":
"socket error" );
2257 else if( DONE == 2 )
2258 n_log(
LOG_ERR,
"Error when sending number of octet to socket %d (%s), network: %s", netw -> link . sock,
_str( netw -> link . ip ), (net_status==-2)?
"disconnected":
"socket error" );
2259 else if( DONE == 3 )
2260 n_log(
LOG_DEBUG,
"Error when sending data on socket %d (%s), network: %s", netw -> link . sock,
_str( netw -> link . ip ), (net_status==-2)?
"disconnected":
"socket error" );
2261 else if( DONE == 4 )
2262 n_log(
LOG_ERR,
"Error when sending state QUIT on socket %d (%s), network: %s", netw -> link . sock,
_str( netw -> link . ip ), (net_status==-2)?
"disconnected":
"socket error" );
2263 else if( DONE == 5 )
2264 n_log(
LOG_ERR,
"Error when sending state QUIT number of octet (0) on socket %d (%s), network: %s", netw -> link . sock,
_str( netw -> link . ip ), (net_status==-2)?
"disconnected":
"socket error" );
2268 n_log(
LOG_DEBUG,
"Socket %d: Sending thread exiting correctly", netw -> link . sock );
2273 n_log(
LOG_ERR,
"Socket %d (%s): Sending thread exiting with error %d !", netw -> link . sock,
_str( netw -> link . ip ),DONE );
2277 pthread_mutex_lock( &netw -> eventbolt );
2278 netw -> nb_running_threads -- ;
2279 pthread_mutex_unlock( &netw -> eventbolt );
2284#if !defined( __linux__ )
2303 int32_t nboctet = 0 ;
2305 char nboct[ 5 ]=
"" ;
2307 N_STR *recvdmsg = NULL ;
2317 if( state&NETW_EXIT_ASKED || state&NETW_EXITED )
2321 if( state&NETW_ERROR )
2331 net_status = netw->
recv_data( netw -> link . sock, nboct,
sizeof( int32_t ) );
2332 if( net_status < 0 )
2338 memcpy( &nboctet, nboct,
sizeof( int32_t ) );
2339 tmpstate = ntohl( nboctet );
2340 nboctet = tmpstate ;
2341 if( tmpstate==NETW_EXIT_ASKED )
2343 n_log(
LOG_DEBUG,
"%d receiving order to QUIT, nboctet %d NETW_EXIT_ASKED %d !", netw -> link . sock, nboctet, NETW_EXIT_ASKED );
2349 net_status = netw->
recv_data( netw -> link . sock, nboct,
sizeof( int32_t ) );
2350 if( net_status < 0 )
2356 memcpy( &nboctet, nboct,
sizeof( int32_t ) );
2357 tmpstate = ntohl( nboctet );
2358 nboctet = tmpstate ;
2368 Malloc( recvdmsg -> data,
char, nboctet + 1 );
2369 if( !recvdmsg -> data )
2375 recvdmsg -> length = nboctet + 1 ;
2376 recvdmsg -> written = nboctet ;
2379 net_status = netw->
recv_data( netw -> link . sock, recvdmsg -> data, nboctet );
2380 if( net_status < 0 )
2386 pthread_mutex_lock( &netw -> recvbolt );
2389 pthread_mutex_unlock( &netw -> recvbolt );
2403 n_log(
LOG_ERR,
"Error when receiving state from socket %d (%s), net_status: %s", netw -> link . sock,
_str( netw -> link . ip ), (net_status==-2)?
"disconnected":
"socket error" );
2404 else if( DONE == 2 )
2405 n_log(
LOG_ERR,
"Error when receiving nboctet from socket %d (%s), net_status: %s", netw -> link . sock,
_str( netw -> link . ip ), (net_status==-2)?
"disconnected":
"socket error" );
2406 else if( DONE == 3 )
2407 n_log(
LOG_ERR,
"Error when receiving data from socket %d (%s), net_status: %s", netw -> link . sock,
_str( netw -> link . ip ), (net_status==-2)?
"disconnected":
"socket error" );
2408 else if( DONE == 4 )
2409 n_log(
LOG_ERR,
"Error allocating received message struct from socket %d (%s), net_status: %s", netw -> link . sock,
_str( netw -> link . ip ), (net_status==-2)?
"disconnected":
"socket error" );
2410 else if( DONE == 5 )
2411 n_log(
LOG_ERR,
"Error allocating received messages data array from socket %d (%s), net_status: %s", netw -> link . sock,
_str( netw -> link . ip ), (net_status==-2)?
"disconnected":
"socket error" );
2412 else if( DONE == 6 )
2413 n_log(
LOG_ERR,
"Error adding receved message from socket %d (%s), net_status: %s", netw -> link . sock,
_str( netw -> link . ip ), (net_status==-2)?
"disconnected":
"socket error" );
2418 n_log(
LOG_DEBUG,
"Socket %d (%s): Receive thread exiting correctly", netw -> link . sock,
_str( netw -> link . ip ) );
2423 n_log(
LOG_ERR,
"Socket %d (%s): Receive thread exiting with code %d !", netw -> link . sock,
_str( netw -> link . ip ), DONE );
2427 pthread_mutex_lock( &netw -> eventbolt );
2428 netw -> nb_running_threads -- ;
2429 pthread_mutex_unlock( &netw -> eventbolt );
2434#if !defined( __linux__ )
2449 int state = 0, thr_engine_status = 0 ;
2451 n_log(
LOG_DEBUG,
"Network %d stop threads event", netw -> link . sock );
2455 if( thr_engine_status != NETW_THR_ENGINE_STARTED )
2457 n_log(
LOG_ERR,
"Thread engine status already stopped for network %p", netw );
2463 n_log(
LOG_DEBUG,
"Network %d waits for send threads to stop", netw -> link . sock );
2464 for(
int it = 0 ; it < 10 ; it ++ )
2466 sem_post( &netw -> send_blocker );
2469 pthread_join( netw -> send_thr, NULL );
2470 n_log(
LOG_DEBUG,
"Network %d waits for recv threads to stop", netw -> link . sock );
2471 pthread_join( netw -> recv_thr, NULL );
2473 netw_set( netw, NETW_EXITED|NETW_THR_ENGINE_STOPPED );
2475 n_log(
LOG_DEBUG,
"Network %d threads Stopped !", netw -> link . sock );
2496 char *errmsg = NULL ;
2507 br = send( s, buf, n - bcount, NETFLAGS );
2516 if( error == ECONNRESET || error == ENOTCONN )
2547 char *errmsg = NULL ;
2559 CALL_RETRY( br, recv( s, buf, n - bcount, NETFLAGS ) );
2576 n_log(
LOG_ERR,
"socket %d recv returned %d, error: %s", s, br,
_str( errmsg ) );
2602 char *errmsg = NULL ;
2610 snprintf( head,
HEAD_SIZE + 1, tmpstr, n );
2612 snprintf( code,
HEAD_CODE + 1, tmpstr, _code );
2630 n_log(
LOG_ERR,
"Socket %d sending Error %d when sending head size, neterrno: %s", s, br,
_str( errmsg ) );
2641 br = send( s, code,
HEAD_CODE - bcount, NETFLAGS );
2651 n_log(
LOG_ERR,
"Socket %d sending Error %d when sending head code, neterrno: %s", s, br,
_str( errmsg ) );
2660 while ( bcount < n )
2662 br = send( s, buf, n - bcount, NETFLAGS );
2673 n_log(
LOG_ERR,
"Socket %d sending Error %d when sending message of size %d, neterrno: %S", s, br, n,
_str( errmsg ) );
2699 long int tmpnb = 0, size = 0 ;
2703 char *errmsg = NULL ;
2714 br = recv( s, ptr,
HEAD_SIZE - bcount, NETFLAGS );
2723 if( br == 0 && bcount == (
HEAD_SIZE - bcount ) )
2733 tmpnb = strtol( head, NULL, 10 );
2734 if( tmpnb == LONG_MIN || tmpnb == LONG_MAX )
2736 n_log(
LOG_ERR,
"Size received ( %ld ) can not be determined on socket %d", tmpnb, s );
2748 br = recv( s, ptr,
HEAD_CODE - bcount, NETFLAGS );
2757 if( br == 0 && bcount == (
HEAD_CODE - bcount ) )
2761 n_log(
LOG_ERR,
"Socket %d receive %d Error , neterrno: %s", s, br,
_str( errmsg ) );
2767 tmpnb = strtol( code, NULL, 10 );
2768 if( tmpnb == LONG_MIN || tmpnb == LONG_MAX )
2770 n_log(
LOG_ERR,
"Code received ( %ld ) can not be determined on socket %d\n", tmpnb, s );
2781 Malloc( (*buf),
char, (size+1) );
2784 n_log(
LOG_ERR,
"Could not allocate PHP receive buf" );
2791 while ( bcount < size )
2794 br = recv( s, ptr, size - bcount, NETFLAGS );
2803 if( br == 0 && bcount == ( size - bcount ) )
2807 n_log(
LOG_ERR,
"Socket %d receive %d Error neterrno: %s", s, br,
_str( errmsg ) );
2829 pthread_mutex_lock( &netw -> sendbolt );
2830 (*nb_to_send) = netw -> send_buf -> nb_items ;
2831 pthread_mutex_unlock( &netw -> sendbolt );
2833 pthread_mutex_lock( &netw -> recvbolt );
2834 (*nb_to_read) = netw -> recv_buf -> nb_items ;
2835 pthread_mutex_unlock( &netw -> recvbolt );
2854 netw_pool -> pool =
new_ht( nb_min_element );
2855 __n_assert( netw_pool -> pool,
Free( netw_pool ) ;
return NULL );
2871 __n_assert( netw_pool&&(*netw_pool),
return FALSE );
2874 if( (*netw_pool) -> pool )
2876 unlock( (*netw_pool) -> rwlock );
2880 Free( (*netw_pool) );
2895 n_log(
LOG_DEBUG,
"Network pool %p: network id %d still active !!", netw, netw -> link . sock );
2912 n_log(
LOG_DEBUG,
"Trying to add %lld to %p", (
unsigned long long)netw -> link . sock, netw_pool -> pool );
2918 nstrprintf( key,
"%lld", (
unsigned long long)netw -> link . sock );
2920 if(
ht_get_ptr( netw_pool -> pool,
_nstr( key ), (
void *)&node ) == TRUE )
2922 n_log(
LOG_ERR,
"Network id %d already added !", netw -> link . sock );
2924 unlock( netw_pool -> rwlock );
2927 int retval = FALSE ;
2931 if( ( retval =
list_push( netw -> pools, netw_pool, NULL ) ) == TRUE )
2933 n_log(
LOG_DEBUG,
"added netw %d to pool %p", netw -> link . sock, netw_pool );
2937 n_log(
LOG_ERR,
"could not add netw %d to pool %p", netw -> link . sock, netw_pool );
2942 n_log(
LOG_ERR,
"could not add netw %d to pool %p", netw -> link . sock, netw_pool );
2947 unlock( netw_pool -> rwlock );
2969 nstrprintf( key,
"%lld", (
unsigned long long int)netw -> link . sock );
2977 n_log(
LOG_ERR,
"Network id %d could not be removed !", netw -> link . sock );
2980 unlock( netw_pool -> rwlock );
2981 n_log(
LOG_DEBUG,
"Network id %d removed !", netw -> link . sock );
2986 n_log(
LOG_ERR,
"Network id %d already removed !", netw -> link . sock );
2988 unlock( netw_pool -> rwlock );
3013 if( netw -> link . sock != from -> link . sock )
3021 unlock( netw_pool -> rwlock );
3038 nb = netw_pool -> pool -> nb_keys ;
3039 unlock( netw_pool -> rwlock );
3055 netw -> user_id = id ;
3072 N_STR *tmpstr = NULL ;
3094 N_STR *tmpstr = NULL ;
3121 N_STR *tmpstr = NULL ;
3146 N_STR *tmpstr = NULL ;
3169 N_STR *tmpstr = NULL ;
3190 N_STR *tmpstr = NULL ;
#define init_lock(__rwlock_mutex)
Macro for initializing a rwlock.
#define FreeNoLog(__ptr)
Free Handler without log.
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
#define __n_assert(__ptr, __ret)
macro to assert things
#define _str(__PTR)
define true
#define rw_lock_destroy(__rwlock_mutex)
Macro to destroy rwlock mutex.
#define unlock(__rwlock_mutex)
Macro for releasing read/write lock a rwlock mutex.
#define write_lock(__rwlock_mutex)
Macro for acquiring a write lock on a rwlock mutex.
#define Free(__ptr)
Free Handler to get errors.
#define read_lock(__rwlock_mutex)
Macro for acquiring a read lock on a rwlock mutex.
#define _nstr(__PTR)
N_STR or "NULL" string for logging purposes.
#define CALL_RETRY(retvar, expression)
TEMP_FAILURE gnu macro portable version.
#define N_ENUM_DEFINE(MACRO_DEFINITION, enum_name)
Macro to define an N_ENUM.
#define N_ENUM_ENTRY(class, method)
helper to build an N_ENUM
int ht_get_ptr(HASH_TABLE *table, const char *key, void **val)
get pointer at 'key' from 'table'
#define ht_foreach(__ITEM_, __HASH_)
ForEach macro helper (classic / old)
int destroy_ht(HASH_TABLE **table)
empty a table and destroy it
int ht_remove(HASH_TABLE *table, const char *key)
remove and delete node at key in table
HASH_TABLE * new_ht(size_t size)
Create a hash table with the given size.
int ht_put_ptr(HASH_TABLE *table, const char *key, void *ptr, void(*destructor)(void *ptr))
put a pointer to the string value with given key in the targeted hash table
#define hash_val(node, type)
Cast a HASH_NODE element.
structure of a hash table node
#define list_shift(__LIST_, __TYPE_)
Shift macro helper for void pointer casting.
int list_empty(LIST *list)
Empty a LIST list of pointers.
#define remove_list_node(__LIST_,__NODE_, __TYPE_)
Remove macro helper for void pointer casting.
int list_push(LIST *list, void *ptr, void(*destructor)(void *ptr))
Add a pointer to the end of the list.
#define list_foreach(__ITEM_, __LIST_)
ForEach macro helper.
int list_destroy(LIST **list)
Empty and Free a list container.
LIST * new_generic_list(int max_items)
Initialiaze a generic list container to max_items pointers.
LIST_NODE * list_search(LIST *list, void *ptr)
search ptr in list
Structure of a generic list node.
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
#define LOG_ERR
error conditions
#define LOG_INFO
informational
void free_nstr_ptr(void *ptr)
Free a N_STR pointer structure.
size_t NSTRBYTE
N_STR base unit.
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
#define nstrprintf(__nstr_var,...)
Macro to quickly allocate and sprintf to N_STR *.
N_STR * nstrdup(N_STR *str)
Duplicate a N_STR.
A box including a string and his lenght.
void u_sleep(unsigned int usec)
wrapper around usleep for API consistency
N_STR * netmsg_make_position_msg(int id, double X, double Y, double vx, double vy, double acc_x, double acc_y, int time_stamp)
make a network NETMSG_POSITION message with given parameters
N_STR * netmsg_make_ident(int type, int id, N_STR *name, N_STR *passwd)
Add a formatted NETWMSG_IDENT message to the specified network.
N_STR * netmsg_make_quit_msg(void)
make a generic network NETMSG_QUIT message
N_STR * netmsg_make_ping(int type, int id_from, int id_to, int time)
Make a ping message to send to a network.
N_STR * netmsg_make_string_msg(int id_from, int id_to, N_STR *name, N_STR *chan, N_STR *txt, int color)
make a network NETMSG_STRING message with given parameters
netw_func send_data
send func ptr
netw_func recv_data
receive func ptr
int netw_send_string_to_all(NETWORK *netw, N_STR *name, N_STR *chan, N_STR *txt, int color)
Add a string to the network, aiming all server-side users.
int netw_pool_broadcast(NETWORK_POOL *netw_pool, NETWORK *from, N_STR *net_msg)
add net_msg to all network in netork pool
N_STR * netw_get_msg(NETWORK *netw)
Get a message from aimed NETWORK.
int send_php(SOCKET s, int _code, char *buf, int n)
send data onto the socket
int netw_add_msg(NETWORK *netw, N_STR *msg)
Add a message to send in aimed NETWORK.
N_STR * netw_wait_msg(NETWORK *netw, size_t refresh, size_t timeout)
Wait a message from aimed NETWORK.
int netw_pool_nbclients(NETWORK_POOL *netw_pool)
return the number of networks in netw_pool
int recv_data(SOCKET s, char *buf, NSTRBYTE n)
recv data from the socket
int netw_init_wsa(int mode, int v1, int v2)
Do not directly use, internal api.
int netw_stop_thr_engine(NETWORK *netw)
Stop a NETWORK connection sending and receing thread.
void * netw_send_func(void *NET)
Thread send function.
NETWORK * netw_accept_nonblock_from(NETWORK *from, int blocking)
make a normal blocking 'accept' .
#define NETWORK_IPV6
Flag to force IPV6
int netw_connect_ex(NETWORK **netw, char *host, char *port, int send_list_limit, int recv_list_limit, int ip_version)
Use this to connect a NETWORK to any listening one.
int netw_set_user_id(NETWORK *netw, int id)
associate an id and a network
int netw_make_listening(NETWORK **netw, char *addr, char *port, int nbpending, int ip_version)
Make a NETWORK be a Listening network.
#define HEAD_SIZE
Size of a HEAD message.
int netw_start_thr_engine(NETWORK *netw)
Start the NETWORK netw Threaded Engine.
int netw_destroy_pool(NETWORK_POOL **netw_pool)
free a NETWORK_POOL *pool
#define NETWORK_IPV4
Flag to force IPV4
int netw_wait_close(NETWORK **netw)
Wait for peer closing a specified Network, destroy queues, free the structure.
void * netw_recv_func(void *NET)
To Thread Receiving function.
#define HEAD_CODE
Code of a HEAD message.
int netw_get_queue_status(NETWORK *netw, int *nb_to_send, int *nb_to_read)
retrieve network send queue status
NETWORK * netw_accept_from_ex(NETWORK *from, int send_list_limit, int recv_list_limit, int non_blocking, int *retval)
make a normal 'accept' .
int netw_setsockopt(NETWORK *netw, int optname, int value)
Modify common socket options on the given netw.
int netw_set(NETWORK *netw, int flag)
Restart or reset the specified network ability.
void netw_pool_netw_close(void *netw_ptr)
close a network from a network pool
NETWORK * netw_accept_from(NETWORK *from)
make a normal blocking 'accept' .
int netw_close(NETWORK **netw)
Closing a specified Network, destroy queues, free the structure.
int netw_send_quit(NETWORK *netw)
Add a formatted NETMSG_QUIT message to the specified network.
int netw_set_blocking(NETWORK *netw, unsigned long int is_blocking)
Modify blocking socket mode.
int netw_send_string_to(NETWORK *netw, int id_to, N_STR *name, N_STR *chan, N_STR *txt, int color)
Add a string to the network, aiming a specific user.
int netw_send_ping(NETWORK *netw, int type, int id_from, int id_to, int time)
Add a ping reply to the network.
NETWORK_POOL * netw_new_pool(int nb_min_element)
return a new network pool of nb_min_element
#define NETWORK_CONSECUTIVE_SEND_TIMEOUT
Flag to set consecutive send waiting timeout
int netw_connect(NETWORK **netw, char *host, char *port, int ip_version)
Use this to connect a NETWORK to any listening one, unrestricted send/recv lists.
#define NETWORK_DEPLETE_TIMEOUT
Flag to set send buffer depletion timeout
int netw_send_ident(NETWORK *netw, int type, int id, N_STR *name, N_STR *passwd)
Add a formatted NETWMSG_IDENT message to the specified network.
int netw_pool_add(NETWORK_POOL *netw_pool, NETWORK *netw)
add a NETWORK *netw to a NETWORK_POOL *pool
int netw_get_state(NETWORK *netw, int *state, int *thr_engine_status)
Get the state of a network.
int send_data(SOCKET s, char *buf, NSTRBYTE n)
send data onto the socket
int recv_php(SOCKET s, int *_code, char **buf)
recv data from the socket
int netw_send_position(NETWORK *netw, int id, double X, double Y, double vx, double vy, double acc_x, double acc_y, int time_stamp)
Add a formatted NETWMSG_IDENT message to the specified network.
int netw_pool_remove(NETWORK_POOL *netw_pool, NETWORK *netw)
remove a NETWORK *netw to a NETWORK_POOL *pool
int netw_add_msg_ex(NETWORK *netw, char *str, unsigned int length)
Add a message to send in aimed NETWORK.
int netw_wait_close_timed(NETWORK **netw, size_t timeout)
Wait for peer closing a specified Network, destroy queues, free the structure.
#define SOCKET
socket macro shortcut
structure of a network pool
Hash functions and table.
int deplete_send_buffer(int fd, size_t timeout)
wait until the socket is empty or timeout, checking each 100 msec.
void netw_sigchld_handler(int sig)
signal handler to reap zombies when forking
N_ENUM_netw_code_type
network erro code
NETWORK * netw_new(int send_list_limit, int recv_list_limit)
Return an empty allocated network ready to be netw_closed.
#define netstrerror(code)
BSD style errno string NO WORKING ON REDHAT.
#define neterrno
Keep it compatible with bsd like.
char * get_in_addr(struct sockaddr *sa)
get sockaddr, IPv4 or IPv6
Network messages , serialization tools.