/* WARNING: This file was generated by dkct. Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk4socka07.ctr */ /* Copyright (C) 2015-2017, Dirk Krause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file dk4socka07.c The dk4socka07 module. */ #line 9 "dk4socka07.ctr" #include "dk4sock.h" #include "dk4socka.h" #include "dk4mem.h" #if DK4_HAVE_GETADDRINFO #include "dk4mao8d.h" #else #if DK4_CHAR_SIZE > 1 #include "dk4maiwdus.h" #include "dk4rec24.h" #endif #include "dk4mai8dus.h" #endif #include "dk4maiddus.h" #include "dk4maodd.h" #include "dk4maodh.h" #line 32 "dk4socka07.ctr" /** Constant texts used by module, not localized. */ static const dkChar * const dk4socket_03_kwnl[] = { /* 0 */ dkT("\n\t"), /* 1 */ dkT(": "), /* 2 */ dkT("@"), NULL #line 52 "dk4socka07.ctr" }; /* Internal tool functions ----------------------- */ /** Report error from dk4socket_tcp_client_for_addr(). @param app Application structure for logging. @param hostname Host name to connect to. @param afam Address family. @param sremote Pointer to remote address buffer. @param szremote Remote address size. @param slocal Pointer to local address buffer. @param szlocal Local address size. @param erp Error report, required. */ static void dk4socket_report_connection_error( dk4_app_t *app, const dkChar *hostname, int afam, const struct sockaddr *sremote, size_t szremote, const struct sockaddr *slocal, size_t szlocal, dk4_er_t *erp ) { const dkChar * msgt[32]; /* Message components */ dkChar bdec[16*sizeof(dk4_um_t)]; /* Decimal */ dkChar bhex[16*sizeof(dk4_um_t)]; /* Hexadecimal */ dkChar bloc[128]; /* Local address */ dkChar brem[128]; /* Remote address */ const dkChar * const *msga = NULL; /* Localized texts */ const dkChar *fctname = NULL; /* Name of failed function */ const dkChar *msgtext = NULL; /* Text why fct failed */ #if VERSION_BEFORE_20150821 size_t szmsga = 0; /* Number of elems in msga */ #endif size_t used = 0; /* No used elems in msgt */ int res = 0; /* Conversion result */ int bothbuf = 0; /* Flag: Have bdec and bhex */ int fctnmsg = 0; /* Flag: Use fct name */ #line 100 "dk4socka07.ctr" if (NULL != app) { if (dk4app_log_do(app, DK4_LL_ERROR)) { #if VERSION_BEFORE_20150821 szmsga = dk4socket_log_num_texts(); #endif msga = dk4socket_log_texts(app); dk4socket_log_fctname_msg(&fctname, &msgtext, app, erp); if (NULL == msgtext) { res = dk4ma_write_decimal_signed( bdec, DK4_SIZEOF(bdec,dkChar), (dk4_im_t)(erp->dt.iDetails1), 0, NULL ); if (0 != res) { res = dk4ma_write_hex_signed( bhex,DK4_SIZEOF(bhex,dkChar),(dk4_im_t)(erp->dt.iDetails1),0,NULL ); if (0 != res) { bothbuf = 1; } } } msgt[used++] = msga[41]; if ((NULL != slocal) && (0 < szlocal)) { res = dk4socket_addr_port_to_text( bloc, DK4_SIZEOF(bloc,dkChar), afam, slocal, szlocal, NULL ); if (DK4_SOCKET_RESULT_SUCCESS == res) { msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[42]; msgt[used++] = bloc; } } if ((NULL != sremote) && (0 < szremote)) { res = dk4socket_addr_port_to_text( brem, DK4_SIZEOF(brem,dkChar), afam, sremote, szremote, NULL ); if (DK4_SOCKET_RESULT_SUCCESS == res) { msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[43]; msgt[used++] = brem; } } switch (erp->ec) { case DK4_E_INVALID_ARGUMENTS : { msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[45]; } break; case DK4_E_SOCKET_SOCKET : { fctnmsg = 1; msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[2]; } break; case DK4_E_SOCKET_BIND : { fctnmsg = 1; msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[4]; } break; case DK4_E_SOCKET_FCNTL : { fctnmsg = 1; msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[9]; } break; case DK4_E_SOCKET_IOCTLSOCKET : { fctnmsg = 1; msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[9]; } break; case DK4_E_SOCKET_CONNECT : { fctnmsg = 1; msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[7]; } break; case DK4_E_SOCKET_TIMEOUT : { msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[44]; } break; case DK4_E_SOCKET_SELECT : { fctnmsg = 1; msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[44]; } break; case DK4_E_SOCKET_GETSOCKOPT : { fctnmsg = 1; msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[8]; } break; case DK4_E_SOCKET_SETSOCKOPT : { fctnmsg = 1; msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[8]; } break; } if (0 != fctnmsg) { if ((NULL != fctname) && ((NULL != msgtext) || (0 != bothbuf))) { msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = fctname; msgt[used++] = dk4socket_03_kwnl[1]; if (NULL != msgtext) { msgt[used++] = msgtext; } else { #if DK4_ON_WINDOWS msgt[used++] = msga[40]; #else msgt[used++] = msga[37]; #endif msgt[used++] = bdec; msgt[used++] = msga[38]; msgt[used++] = bhex; msgt[used++] = msga[39]; } } } dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); } } #line 213 "dk4socka07.ctr" } /** Report error from dk4socket_tcp_client_for_addr(). @param app Application structure for logging. @param hostname Host name to connect to. @param afam Address family. @param sremote Pointer to remote address buffer. @param szremote Remote address size. @param slocal Pointer to local address buffer. @param szlocal Local address size. @param erp Error report, required. */ static void dk4socket_report_connection_established( dk4_app_t *app, const dkChar *hostname, int afam, const struct sockaddr *sremote, size_t szremote, const struct sockaddr *slocal, size_t szlocal ) { const dkChar * msgt[32]; /* Message components */ dkChar bloc[128]; /* Local address */ dkChar brem[128]; /* Remote address */ const dkChar * const *msga = NULL; /* Localized texts */ #if VERSION_BEFORE_20150821 size_t szmsga = 0; /* Number of elems in msga */ #endif size_t used = 0; /* No used elems in msgt */ int res = 0; /* Conversion result */ if (NULL != app) { if (0 != dk4app_log_do(app, DK4_LL_PROGRESS)) { #if VERSION_BEFORE_20150821 szmsga = dk4socket_log_num_texts(); #endif msga = dk4socket_log_texts(app); msgt[used++] = msga[30]; if ((NULL != slocal) && (0 < szlocal)) { res = dk4socket_addr_port_to_text( bloc, DK4_SIZEOF(bloc,dkChar), afam, slocal, szlocal, NULL ); if (DK4_SOCKET_RESULT_SUCCESS == res) { msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[42]; msgt[used++] = bloc; } } if ((NULL != sremote) && (0 < szremote)) { res = dk4socket_addr_port_to_text( brem, DK4_SIZEOF(brem,dkChar), afam, sremote, szremote, NULL ); if (DK4_SOCKET_RESULT_SUCCESS == res) { msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[43]; msgt[used++] = brem; } } dk4app_log_msg(app, DK4_LL_PROGRESS, msgt, used); } } } static void dk4socket_report_invalid_arguments( dk4_app_t *app ) { const dkChar * msgt[16]; const dkChar * const *msga; #if VERSION_BEFORE_20150821 size_t szmsga; #endif size_t used = 0; if (NULL != app) { if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { #if VERSION_BEFORE_20150821 szmsga = dk4socket_log_num_texts(); #endif msga = dk4socket_log_texts(app); msgt[used++] = msga[41]; msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[45]; dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); } } } #if DK4_HAVE_GETADDRINFO /* +++++ +getaddrinfo +++++ */ static void dk4socket_report_no_matching_addresses( const dkChar *hostname, dk4_app_t *app ) { const dkChar *msgt[16]; const dkChar * const *msga; #if VERSION_BEFORE_20150821 size_t szmsga; #endif if (NULL != app) { if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { #if VERSION_BEFORE_20150821 szmsga = dk4socket_log_num_texts(); #endif msga = dk4socket_log_texts(app); msgt[0] = msga[41]; msgt[1] = dk4socket_03_kwnl[0]; msgt[2] = msga[43]; msgt[4] = hostname; msgt[5] = dk4socket_03_kwnl[0]; msgt[6] = msga[46]; dk4app_log_msg(app, DK4_LL_ERROR, msgt, 7); } } } static void dk4socket_report_gai( const dkChar *hostname, const dkChar *lsvcname, int res, int local, dk4_app_t *app, dk4_er_t *erp ) { dkChar bdec[16*sizeof(dk4_um_t)]; dkChar bhex[16*sizeof(dk4_um_t)]; const dkChar *msgt[16]; const dkChar * const *msga; const dkChar *fctname = NULL; const dkChar *msgtext = NULL; #if VERSION_BEFORE_20150821 size_t szmsga; #endif size_t used = 0; if (NULL != app) { if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { #if VERSION_BEFORE_20150821 szmsga = dk4socket_log_num_texts(); #endif msga = dk4socket_log_texts(app); dk4socket_log_fctname_msg(&fctname, &msgtext, app, erp); msgt[used++] = msga[41]; if ((NULL != hostname) && (0 == local)) { msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[20]; msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[21]; msgt[used++] = hostname; if (NULL != lsvcname) { msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[22]; msgt[used++] = lsvcname; } } else { msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[18]; msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[19]; msgt[used++] = lsvcname; } if (NULL != fctname) { if (NULL != msgtext) { msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = fctname; msgt[used++] = dk4socket_03_kwnl[1]; msgt[used++] = msgtext; } else { res = dk4ma_write_decimal_signed( bdec,DK4_SIZEOF(bdec,dkChar),(dk4_im_t)(erp->dt.iDetails1),0,NULL ); if (0 != res) { res = dk4ma_write_hex_signed( bhex,DK4_SIZEOF(bhex,dkChar),(dk4_im_t)(erp->dt.iDetails1),0,NULL ); if (0 != res) { msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = fctname; msgt[used++] = dk4socket_03_kwnl[1]; #if DK4_ON_WINDOWS msgt[used++] = msga[40]; #else msgt[used++] = msga[37]; #endif msgt[used++] = bdec; msgt[used++] = msga[38]; msgt[used++] = bhex; msgt[used++] = msga[39]; } } } } else { } dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); } } } #if DK4_CHAR_SIZE > 1 /** Create a socket using remote and optionally local address lists. @param hostname Remote host name. @param rast List of remote addresses. @param last List of local addresses, may be NULL. @param secs Seconds for timeout. @param usecs Microseconds for timeout. @param app Application structure for diagnostics, may be NULL. @return Valid socket on success, INVALID_SOCKET on error. */ static dk4_socket_t dk4socket_tcp_client_addresses_app( const dkChar *hostname, ADDRINFOW *rast, ADDRINFOW *last, long secs, long usecs, dk4_app_t *app ) { dk4_er_t er; ADDRINFOW *ra; ADDRINFOW *la; dk4_socket_t back = INVALID_SOCKET; int mpf = 0; #line 457 "dk4socka07.ctr" ra = rast; while ((INVALID_SOCKET == back) && (NULL != ra)) { if (NULL != last) { la = last; while ((INVALID_SOCKET == back) && (NULL != la)) { if (ra->ai_family == la->ai_family) { mpf = 1; #line 464 "dk4socka07.ctr" dk4error_init(&er); back = dk4socket_tcp_client_for_addr( ra->ai_family, ra->ai_addr, ra->ai_addrlen, la->ai_addr, la->ai_addrlen, secs, usecs, &er ); if (INVALID_SOCKET != back) { dk4socket_report_connection_established( app, hostname, ra->ai_family, ra->ai_addr, ra->ai_addrlen, la->ai_addr, la->ai_addrlen ); ra = NULL; la = NULL; } else { #line 479 "dk4socka07.ctr" /* ERROR: Failed */ dk4socket_report_connection_error( app, hostname, ra->ai_family, ra->ai_addr, ra->ai_addrlen, la->ai_addr, la->ai_addrlen, &er ); } } if (NULL != la) { la = la->ai_next; } } } else { mpf = 1; dk4error_init(&er); back = dk4socket_tcp_client_for_addr( ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0, secs, usecs, &er ); if (INVALID_SOCKET != back) { dk4socket_report_connection_established( app, hostname, ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0 ); ra = NULL; } else { #line 504 "dk4socka07.ctr" /* ERROR: Failed */ dk4socket_report_connection_error( app,hostname,ra->ai_family,ra->ai_addr,ra->ai_addrlen,NULL,0,&er ); } } if (NULL != ra) { ra = ra->ai_next; } } if (INVALID_SOCKET == back) { if (0 == mpf) { #line 514 "dk4socka07.ctr" /* ERROR: No matching address pair found (27) */ dk4socket_report_no_matching_addresses(hostname, app); } } #line 519 "dk4socka07.ctr" return back; } #else /** Create a socket using remote and optionally local address lists. @param hostname Remote host name. @param rast List of remote addresses. @param last List of local addresses, may be NULL. @param secs Seconds for timeout. @param usecs Microseconds for timeout. @param app Application structure for diagnostics, may be NULL. @return Valid socket on success, INVALID_SOCKET on error. */ static dk4_socket_t dk4socket_tcp_client_addresses_app( const dkChar *hostname, struct addrinfo *rast, struct addrinfo *last, long secs, long usecs, dk4_app_t *app ) { dk4_er_t er; struct addrinfo *ra; struct addrinfo *la; dk4_socket_t back = INVALID_SOCKET; int mpf = 0; #line 550 "dk4socka07.ctr" ra = rast; while ((INVALID_SOCKET == back) && (NULL != ra)) { if (NULL != last) { la = last; while ((INVALID_SOCKET == back) && (NULL != la)) { if (ra->ai_family == la->ai_family) { mpf = 1; dk4error_init(&er); back = dk4socket_tcp_client_for_addr( ra->ai_family, ra->ai_addr, ra->ai_addrlen, la->ai_addr, la->ai_addrlen, secs, usecs, &er ); if (INVALID_SOCKET != back) { dk4socket_report_connection_established( app, hostname, ra->ai_family, ra->ai_addr, ra->ai_addrlen, la->ai_addr, la->ai_addrlen ); ra = NULL; la = NULL; } else { #line 572 "dk4socka07.ctr" /* ERROR: Failed */ dk4socket_report_connection_error( app, hostname, ra->ai_family, ra->ai_addr, ra->ai_addrlen, la->ai_addr, la->ai_addrlen, &er ); } } if (NULL != la) { la = la->ai_next; } } } else { mpf = 1; dk4error_init(&er); back = dk4socket_tcp_client_for_addr( ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0, secs, usecs, &er ); if (INVALID_SOCKET != back) { dk4socket_report_connection_established( app, hostname, ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0 ); ra = NULL; } else { #line 597 "dk4socka07.ctr" /* ERROR: Failed */ dk4socket_report_connection_error( app,hostname,ra->ai_family,ra->ai_addr,ra->ai_addrlen,NULL,0,&er ); } } if (NULL != ra) { ra = ra->ai_next; } } if (INVALID_SOCKET == back) { if (0 == mpf) { /* ERROR: No matching address pair found (27) */ dk4socket_report_no_matching_addresses(hostname, app); } } #line 612 "dk4socka07.ctr" return back; } #endif /* ----- +getaddrinfo ----- */ #else /* +++++ -getaddrinfo +++++ */ #if DK4_HAVE_STRUCT_SOCKADDR_IN6 /** used to initialize IPv6 address for binding local ports. */ static const IN6_ADDR dk4socket_any6 = IN6ADDR_ANY_INIT; #endif static void dk4socket_report_invalid_port_number(dk4_app_t *app, size_t i) { const dkChar * msgt[16]; const dkChar * const *msga; size_t szmsga; size_t used = 0; if (NULL != app) { if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { szmsga = dk4socket_log_num_texts(); msga = dk4socket_log_texts(app); msgt[used++] = msga[41]; msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[i]; dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); } } } static void dk4socket_report_service_not_found(dk4_app_t *app, const dkChar *svcname) { const dkChar * msgt[16]; const dkChar * const *msga; size_t szmsga; size_t used = 0; if (NULL != app) { if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { szmsga = dk4socket_log_num_texts(); msga = dk4socket_log_texts(app); msgt[used++] = msga[23]; msgt[used++] = svcname; msgt[used++] = msga[24]; dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); } } } #if DK4_CHAR_SIZE > 1 static void dk4socket_report_service_not_ascii(dk4_app_t *app, const dkChar *svcname) { const dkChar * msgt[16]; const dkChar * const *msga; size_t szmsga; size_t used = 0; if (NULL != app) { if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { szmsga = dk4socket_log_num_texts(); msga = dk4socket_log_texts(app); msgt[used++] = msga[25]; msgt[used++] = svcname; msgt[used++] = msga[26]; dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); } } } #endif static void dk4socket_report_illegal_address_part( dk4_app_t *app, const dkChar *hostname, size_t i ) { const dkChar * msgt[16]; const dkChar * const *msga; size_t szmsga; size_t used = 0; if (NULL != app) { if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { szmsga = dk4socket_log_num_texts(); msga = dk4socket_log_texts(app); msgt[used++] = msga[i]; if (NULL != hostname) { msgt[used++] = dk4socket_03_kwnl[0]; msgt[used++] = msga[43]; msgt[used++] = hostname; } dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); } } } static void dk4socket_report_host_name_problem( dk4_app_t *app, const dkChar *hostname, size_t i1, size_t i2 ) { const dkChar * msgt[16]; const dkChar * const *msga; size_t szmsga; size_t used = 0; if (NULL != app) { if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { szmsga = dk4socket_log_num_texts(); msga = dk4socket_log_texts(app); if (NULL != hostname) { msgt[used++] = msga[i1]; msgt[used++] = hostname; msgt[used++] = msga[i2]; } dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); } } } /* ----- -getaddrinfo ----- */ #endif /* Exported functions ------------------ */ #if DK4_CHAR_SIZE > 1 #if DK4_ON_WINDOWS #if DK4_HAVE_GETADDRINFO /* +++++ wchar_t (Windows), +getaddrinfo +++++ */ dk4_socket_t dk4socket_tcp_client_for_host_num_service_app( const dkChar *hostname, const dkChar *svcname, const dkChar *lsvcname, long secs, long usecs, int nsrv, dk4_app_t *app ) { ADDRINFOW rhints; ADDRINFOW lhints; dk4_er_t er; ADDRINFOW *rast = NULL; ADDRINFOW *last = NULL; dk4_socket_t back = INVALID_SOCKET; int res; #line 793 "dk4socka07.ctr" if ((NULL != hostname) && (NULL != svcname)) { #line 794 "dk4socka07.ctr" DK4_MEMRES(&rhints, sizeof(rhints)); rhints.ai_family = AF_UNSPEC; rhints.ai_socktype = SOCK_STREAM; if (0 != nsrv) { rhints.ai_flags = AI_NUMERICSERV; } rhints.ai_protocol = 0; dk4error_init(&er); res = GetAddrInfoW(hostname, svcname, &rhints, &rast); if ((0 == res) && (NULL != rast)) { #line 802 "dk4socka07.ctr" if (NULL != lsvcname) { #line 803 "dk4socka07.ctr" DK4_MEMRES(&lhints, sizeof(lhints)); lhints.ai_family = AF_UNSPEC; lhints.ai_socktype = SOCK_STREAM; lhints.ai_flags = AI_PASSIVE; if (0 != nsrv) { lhints.ai_flags |= AI_NUMERICSERV; } lhints.ai_protocol = 0; dk4error_init(&er); res = GetAddrInfoW(NULL, lsvcname, &lhints, &last); if ((0 == res) && (NULL != last)) { #line 812 "dk4socka07.ctr" back = dk4socket_tcp_client_addresses_app( hostname, rast, last, secs, usecs, app ); FreeAddrInfoW(last); } else { #line 817 "dk4socka07.ctr" /* ERROR: Failed to obtain local addresses to bind (18, 19) */ dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res); dk4socket_report_gai(NULL, lsvcname, res, 1, app, &er); } } else { #line 822 "dk4socka07.ctr" back = dk4socket_tcp_client_addresses_app( hostname, rast, NULL, secs, usecs, app ); } FreeAddrInfoW(rast); } else { #line 828 "dk4socka07.ctr" /* ERROR: Failed to obtain remote addresses (20, 21, 22) */ dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res); dk4socket_report_gai(hostname, svcname, res, 0, app, &er); } } else { #line 833 "dk4socka07.ctr" /* ERROR: Invalid arguments (bug) */ dk4socket_report_invalid_arguments(app); } #line 837 "dk4socka07.ctr" return back; } dk4_socket_t dk4socket_tcp_client_for_host_service_app( const dkChar *hostname, const dkChar *svcname, const dkChar *lsvcname, long secs, long usecs, dk4_app_t *app ) { return ( dk4socket_tcp_client_for_host_num_service_app( hostname, svcname, lsvcname, secs, usecs, 0, app ) ); } dk4_socket_t dk4socket_tcp_client_for_host_port_app( const dkChar *hostname, unsigned short portno, unsigned short lportno, long secs, long usecs, dk4_app_t *app ) { dkChar rpnb[16*sizeof(dk4_um_t)]; dkChar lpnb[16*sizeof(dk4_um_t)]; dk4_er_t er; dk4_socket_t back = INVALID_SOCKET; int res; #line 877 "dk4socka07.ctr" if ((NULL != hostname) && (0 < portno)) { #line 878 "dk4socka07.ctr" dk4error_init(&er); res = dk4ma_write_decimal_unsigned( rpnb, DK4_SIZEOF(rpnb,dkChar), (dk4_um_t)portno, 0, &er ); if (0 != res) { #line 883 "dk4socka07.ctr" if (0 < lportno) { #line 884 "dk4socka07.ctr" dk4error_init(&er); res = dk4ma_write_decimal_unsigned( lpnb, DK4_SIZEOF(lpnb,dkChar), (dk4_um_t)lportno, 0, &er ); if (0 != res) { #line 889 "dk4socka07.ctr" back = dk4socket_tcp_client_for_host_num_service_app( hostname, rpnb, lpnb, secs, usecs, 0, app ); } else { #line 893 "dk4socka07.ctr" /* ERROR: Failed to convert local port number to text, bug */ } } else { #line 896 "dk4socka07.ctr" back = dk4socket_tcp_client_for_host_num_service_app( hostname, rpnb, NULL, secs, usecs, 0, app ); } } else { #line 901 "dk4socka07.ctr" /* ERROR: Failed to convert port number to text, bug */ } } else { #line 904 "dk4socka07.ctr" /* ERROR: Invalid arguments (bug) */ dk4socket_report_invalid_arguments(app); } #line 908 "dk4socka07.ctr" return back; } /* ----- wchar_t (Windows), +getaddrinfo ----- */ #else /* +++++ wchar_t (Windows), -getaddrinfo +++++ */ dk4_socket_t dk4socket_tcp_client_for_host_num_service_app( const dkChar *hostname, const dkChar *svcname, const dkChar *lsvcname, long secs, long usecs, int nsrv, dk4_app_t *app ) { char cppt[48]; char cplp[48]; dk4_er_t er; struct servent *serv = NULL; const dkChar *endptr = NULL; dk4_socket_t back = INVALID_SOCKET; int res = 0; unsigned short rport = 0U; unsigned short lport = 0U; unsigned short iport = 0U; #line 941 "dk4socka07.ctr" if ((NULL != hostname) && (NULL != svcname)) { dk4error_init(&er); res = dk4ma_input_dk_dec_ushort(&rport, svcname, &endptr, 1, NULL); if (0 == res) { if (0 != dk4recode_wchar_t_to_char(cppt, sizeof(cppt), svcname, &er)) { dk4socket_error_reset(); serv = getservbyname(cppt, NULL); if (NULL != serv) { iport = serv->s_port; dk4socket_swap_bytes_if_not_bigendian((void *)(&iport),sizeof(iport)); rport = (unsigned short)iport; } else { dk4socket_error_report(&er, DK4_E_SOCKET_GETSERVBYNAME); /* ERROR: Service not found (23, 24) */ dk4socket_report_service_not_found(app, svcname); } } else { /* ERROR: Failed to convert service name (25, 26) */ dk4socket_report_service_not_ascii(app, svcname); } } if (0 < rport) { if (NULL != lsvcname) { endptr = NULL; dk4error_init(&er); res = dk4ma_input_dk_dec_ushort(&lport, lsvcname, &endptr, 1, NULL); if (0 == res) { dk4error_init(&er); if (0 != dk4recode_wchar_t_to_char(cplp,sizeof(cplp),lsvcname,&er)) { dk4socket_error_reset(); serv = getservbyname(cplp, NULL); if (NULL != serv) { iport = serv->s_port; dk4socket_swap_bytes_if_not_bigendian( (void *)(&iport), sizeof(iport) ); lport = (unsigned short)iport; } else { dk4socket_error_report(&er, DK4_E_SOCKET_GETSERVBYNAME); /* Service not found (23, 24) */ dk4socket_report_service_not_found(app, lsvcname); } } else { /* ERROR: Text conversion failed (25, 26) */ dk4socket_report_service_not_ascii(app, lsvcname); } } if (0 < lport) { back = dk4socket_tcp_client_for_host_port_app( hostname, rport, lport, secs, usecs, app ); } else { /* ERROR: Illegal local port number (28) */ dk4socket_report_invalid_port_number(app, 28); } } else { back = dk4socket_tcp_client_for_host_port_app( hostname, rport, 0, secs, usecs, app ); } } else { /* ERROR: Illegal remote port number (29) */ dk4socket_report_invalid_port_number(app, 29); } } else { /* ERROR: Invalid arguments (bug) */ dk4socket_report_invalid_arguments(app); } #line 1010 "dk4socka07.ctr" return back; } dk4_socket_t dk4socket_tcp_client_for_host_service_app( const dkChar *hostname, const dkChar *svcname, const dkChar *lsvcname, long secs, long usecs, dk4_app_t *app ) { return ( dk4socket_tcp_client_for_host_num_service_app( hostname, svcname, lsvcname, secs, usecs, 0, app ) ); } dk4_socket_t dk4socket_tcp_client_for_host_port_app( const dkChar *hostname, unsigned short portno, unsigned short lportno, long secs, long usecs, dk4_app_t *app ) { char hona[1040]; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 struct sockaddr_in6 sr6; struct sockaddr_in6 sl6; #endif struct sockaddr_in sr4; struct sockaddr_in sl4; dk4_er_t er; char **addrptr; struct hostent *hep; dk4_socket_t back = INVALID_SOCKET; #line 1057 "dk4socka07.ctr" if ((NULL != hostname) && (0 < portno)) { dk4error_init(&er); if (0 != dk4recode_wchar_t_to_char(hona, sizeof(hona), hostname, &er)) { dk4socket_error_reset(); hep = gethostbyname(hona); if (NULL != hep) { if (NULL != hep->h_addr_list) { switch (hep->h_addrtype) { case AF_INET : { if (4 == hep->h_length) { addrptr = hep->h_addr_list; while ((INVALID_SOCKET == back) && (NULL != *addrptr)) { DK4_MEMRES(&sr4, sizeof(sr4)); sr4.sin_family = AF_INET; sr4.sin_port = dk4socket_htons(portno); DK4_MEMCPY(&(sr4.sin_addr), *addrptr, sizeof(IN_ADDR)); dk4error_init(&er); if (0 != lportno) { DK4_MEMRES(&sl4, sizeof(sl4)); sl4.sin_family = AF_INET; sl4.sin_port = dk4socket_htons(lportno); sl4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY); back = dk4socket_tcp_client_for_addr( AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4), (struct sockaddr *)(&sl4), sizeof(sl4), secs, usecs, &er ); } else { back = dk4socket_tcp_client_for_addr( AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4), NULL, 0, secs, usecs, &er ); } if (INVALID_SOCKET == back) { #line 1090 "dk4socka07.ctr" /* ERROR: Failed */ dk4socket_report_connection_error( app, hostname, AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4), ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL), ((0 < lportno) ? (sizeof(sl4)) : 0), &er ); } else { /* DEBUG: Connection established (30) */ dk4socket_report_connection_established( app, hostname, AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4), ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL), ((0 < lportno) ? (sizeof(sl4)) : 0) ); } addrptr++; } } else { /* ERROR: Illegal address length, bug (31) */ dk4socket_report_illegal_address_part(app, hostname, 31); } } break; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 case AF_INET6 : { if (16 == hep->h_length) { addrptr = hep->h_addr_list; while ((INVALID_SOCKET == back) && (NULL != *addrptr)) { DK4_MEMRES(&sr6, sizeof(sr6)); sr6.sin6_family = AF_INET6; sr6.sin6_port = dk4socket_htons(portno); DK4_MEMCPY(&(sr6.sin6_addr), *addrptr, sizeof(IN6_ADDR)); dk4error_init(&er); if (0 < lportno) { DK4_MEMRES(&sl6, sizeof(sl6)); sl6.sin6_family = AF_INET6; sl6.sin6_port = dk4socket_htons(lportno); DK4_MEMCPY(&(sl6.sin6_addr),&dk4socket_any6,sizeof(IN6_ADDR)); back = dk4socket_tcp_client_for_addr( AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6), (struct sockaddr *)(&sl6), sizeof(sl6), secs, usecs, &er ); } else { back = dk4socket_tcp_client_for_addr( AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6), NULL, 0, secs, usecs, &er ); } if (INVALID_SOCKET == back) { #line 1140 "dk4socka07.ctr" /* ERROR: Failed */ dk4socket_report_connection_error( app, hostname, AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6), ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL), ((0 < lportno) ? (sizeof(sl6)) : 0), &er ); } else { /* DEBUG: Connection established (30) */ dk4socket_report_connection_established( app, hostname, AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6), ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL), ((0 < lportno) ? (sizeof(sl6)) : 0) ); } addrptr++; } } else { /* ERROR: Illegal address length, bug (31) */ dk4socket_report_illegal_address_part(app, hostname, 31); } } break; #endif default : { /* ERROR: Illegal address family (32) */ dk4socket_report_illegal_address_part(app, hostname, 32); } break; } } else { /* ERROR: Host not found (33, 34) */ dk4socket_report_host_name_problem(app, hostname, 33, 34); } } else { dk4socket_error_report(&er, DK4_E_SOCKET_GETHOSTBYNAME); /* ERROR: Host not found (33, 34) */ dk4socket_report_host_name_problem(app, hostname, 33, 34); } } else { /* ERROR: Failed to convert host name to ASCII (35, 36) */ dk4socket_report_host_name_problem(app, hostname, 35, 36); } } else { /* ERROR: Invalid arguments (bug) */ dk4socket_report_invalid_arguments(app); } #line 1188 "dk4socka07.ctr" return back; } /* ----- wchar_t (Windows), -getaddrinfo ----- */ #endif #else #error No support for networking with wchar_t strings! #endif #else #if DK4_HAVE_GETADDRINFO /* +++++ char, +getaddrinfo +++++ */ dk4_socket_t dk4socket_tcp_client_for_host_num_service_app( const dkChar *hostname, const dkChar *svcname, const dkChar *lsvcname, long secs, long usecs, int nsrv, dk4_app_t *app ) { struct addrinfo rhints; struct addrinfo lhints; dk4_er_t er; struct addrinfo *raddrst = NULL; struct addrinfo *laddrst = NULL; dk4_socket_t back = INVALID_SOCKET; int res; #line 1221 "dk4socka07.ctr" #line 1222 "dk4socka07.ctr" #line 1223 "dk4socka07.ctr" if ((NULL != hostname) && (NULL != svcname)) { #line 1224 "dk4socka07.ctr" DK4_MEMRES(&rhints, sizeof(rhints)); rhints.ai_family = AF_UNSPEC; rhints.ai_socktype = SOCK_STREAM; if (0 != nsrv) { rhints.ai_flags = AI_NUMERICSERV; } rhints.ai_protocol = 0; dk4error_init(&er); res = getaddrinfo(hostname, svcname, &rhints, &raddrst); if ((0 == res) && (NULL != raddrst)) { #line 1232 "dk4socka07.ctr" if (NULL != lsvcname) { #line 1233 "dk4socka07.ctr" DK4_MEMRES(&lhints, sizeof(lhints)); lhints.ai_family = AF_UNSPEC; lhints.ai_socktype = SOCK_STREAM; lhints.ai_flags = AI_PASSIVE; if (0 != nsrv) { lhints.ai_flags |= AI_NUMERICSERV; } lhints.ai_protocol = 0; dk4error_init(&er); res = getaddrinfo(NULL, lsvcname, &lhints, &laddrst); if ((0 == res) && (NULL != laddrst)) { #line 1242 "dk4socka07.ctr" back = dk4socket_tcp_client_addresses_app( hostname, raddrst, laddrst, secs, usecs, app ); freeaddrinfo(laddrst); } else { #line 1247 "dk4socka07.ctr" /* ERROR: Failed to obtain local addresses (18, 19) */ dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res); dk4socket_report_gai(NULL, lsvcname, res, 1, app, &er); } } else { #line 1252 "dk4socka07.ctr" back = dk4socket_tcp_client_addresses_app( hostname, raddrst, NULL, secs, usecs, app ); } freeaddrinfo(raddrst); } else { #line 1258 "dk4socka07.ctr" /* ERROR: Failed to obtain remote addresses (20, 21, 22) */ dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res); dk4socket_report_gai(hostname, svcname, res, 0, app, &er); } } else { #line 1263 "dk4socka07.ctr" /* ERROR: Invalid arguments (bug) */ dk4socket_report_invalid_arguments(app); } #line 1267 "dk4socka07.ctr" return back; } dk4_socket_t dk4socket_tcp_client_for_host_service_app( const dkChar *hostname, const dkChar *svcname, const dkChar *lsvcname, long secs, long usecs, dk4_app_t *app ) { return ( dk4socket_tcp_client_for_host_num_service_app( hostname, svcname, lsvcname, secs, usecs, 0, app ) ); } dk4_socket_t dk4socket_tcp_client_for_host_port_app( const dkChar *hostname, unsigned short portno, unsigned short lportno, long secs, long usecs, dk4_app_t *app ) { char rpn[16*sizeof(dk4_um_t)]; char lpn[16*sizeof(dk4_um_t)]; dk4_socket_t back = INVALID_SOCKET; int res; #line 1306 "dk4socka07.ctr" if ((NULL != hostname) && (0 < portno)) { res = dk4ma_write_c8_decimal_unsigned( rpn, sizeof(rpn), (dk4_um_t)portno, 0, NULL ); if (0 != res) { if (0 < lportno) { res = dk4ma_write_c8_decimal_unsigned( lpn, sizeof(lpn), (dk4_um_t)lportno, 0, NULL ); if (0 != res) { back = dk4socket_tcp_client_for_host_num_service_app( hostname, rpn, lpn, secs, usecs, 1, app ); } else { /* ERROR: Failed to convert port number to text, bug */ } } else { back = dk4socket_tcp_client_for_host_num_service_app( hostname, rpn, NULL, secs, usecs, 1, app ); } } else { /* ERROR: Failed to convert port number to text, bug */ } } else { /* ERROR: Invalid arguments (bug) */ dk4socket_report_invalid_arguments(app); } #line 1335 "dk4socka07.ctr" return back; } /* ----- char, +getaddrinfo ----- */ #else /* +++++ char, -getaddrinfo ----- */ dk4_socket_t dk4socket_tcp_client_for_host_num_service_app( const dkChar *hostname, const dkChar *svcname, const dkChar *lsvcname, long secs, long usecs, int nsrv, dk4_app_t *app ) { const char *endptr = NULL; struct servent *serv = NULL; dk4_socket_t back = INVALID_SOCKET; int res = 0; int iport = 0; unsigned short rport = 0; unsigned short lport = 0; #line 1365 "dk4socka07.ctr" if ((NULL != hostname) && (NULL != svcname)) { res = dk4ma_input_c8_dec_ushort(&rport, svcname, &endptr, 1, NULL); if (0 == res) { dk4socket_error_reset(); serv = getservbyname(svcname, NULL); if (NULL != serv) { iport = serv->s_port; dk4socket_swap_bytes_if_not_bigendian((void *)(&iport), sizeof(iport)); rport = (unsigned short)iport; } else { /* ERROR: Service name for remote port not found (23, 24) */ dk4socket_report_service_not_found(app, svcname); } } if (0 != rport) { if (NULL != lsvcname) { endptr = NULL; res = dk4ma_input_c8_dec_ushort(&lport, lsvcname, &endptr, 1, NULL); if (0 == res) { dk4socket_error_reset(); serv = getservbyname(lsvcname, NULL); if (NULL != serv) { iport = serv->s_port; dk4socket_swap_bytes_if_not_bigendian( (void *)(&iport), sizeof(iport) ); lport = (unsigned short)iport; } else { /* ERROR: Service name for local port not found (23, 24) */ dk4socket_report_service_not_found(app, lsvcname); } } if (0 != lport) { back = dk4socket_tcp_client_for_host_port_app( hostname, rport, lport, secs, usecs, app ); } else { /* ERROR: Illegal local port number (28) */ dk4socket_report_invalid_port_number(app, 28); } } else { back = dk4socket_tcp_client_for_host_port_app( hostname, rport, 0, secs, usecs, app ); } } else { /* ERROR: Illegal remote port number (29) */ dk4socket_report_invalid_port_number(app, 29); } } else { /* ERROR: Invalid arguments (bug) */ dk4socket_report_invalid_arguments(app); } #line 1419 "dk4socka07.ctr" return back; } dk4_socket_t dk4socket_tcp_client_for_host_service_app( const dkChar *hostname, const dkChar *svcname, const dkChar *lsvcname, long secs, long usecs, dk4_app_t *app ) { return ( dk4socket_tcp_client_for_host_num_service_app( hostname, svcname, lsvcname, secs, usecs, 0, app ) ); } dk4_socket_t dk4socket_tcp_client_for_host_port_app( const dkChar *hostname, unsigned short portno, unsigned short lportno, long secs, long usecs, dk4_app_t *app ) { dk4_er_t er; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 struct sockaddr_in6 sr6; struct sockaddr_in6 sl6; #endif struct sockaddr_in sr4; struct sockaddr_in sl4; char **addrptr; struct hostent *hep = NULL; dk4_socket_t back = INVALID_SOCKET; #line 1464 "dk4socka07.ctr" if ((NULL != hostname) && (0 < portno)) { dk4error_init(&er); dk4socket_error_reset(); hep = gethostbyname(hostname); if (NULL != hep) { if (NULL != hep->h_addr_list) { switch (hep->h_addrtype) { case AF_INET : { if (4 == hep->h_length) { addrptr = hep->h_addr_list; while ((INVALID_SOCKET == back) && (NULL != *addrptr)) { DK4_MEMRES(&sr4, sizeof(sr4)); sr4.sin_family = AF_INET; sr4.sin_port = dk4socket_htons(portno); DK4_MEMCPY(&(sr4.sin_addr), *addrptr, sizeof(IN_ADDR)); dk4error_init(&er); if (0 != lportno) { DK4_MEMRES(&sl4, sizeof(sl4)); sl4.sin_family = AF_INET; sl4.sin_port = dk4socket_htons(lportno); sl4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY); back = dk4socket_tcp_client_for_addr( AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4), (struct sockaddr *)(&sl4), sizeof(sl4), secs, usecs, &er ); } else { back = dk4socket_tcp_client_for_addr( AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4), NULL, 0, secs, usecs, &er ); } if (INVALID_SOCKET == back) { #line 1496 "dk4socka07.ctr" /* ERROR: Failed */ dk4socket_report_connection_error( app, hostname, AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4), ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL), ((0 < lportno) ? (sizeof(sl4)) : 0), &er ); } else { /* DEBUG: Connection established (30) */ dk4socket_report_connection_established( app, hostname, AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4), ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL), ((0 < lportno) ? (sizeof(sl4)) : 0) ); } addrptr++; } } else { /* ERROR: Illegal address length (31) */ dk4socket_report_illegal_address_part(app, hostname, 31); } } break; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 case AF_INET6 : { if (16 == hep->h_length) { addrptr = hep->h_addr_list; while ((INVALID_SOCKET == back) && (NULL != *addrptr)) { DK4_MEMRES(&sr6, sizeof(sr6)); sr6.sin6_family = AF_INET6; sr6.sin6_port = dk4socket_htons(portno); DK4_MEMCPY(&(sr6.sin6_addr), *addrptr, sizeof(IN6_ADDR)); dk4error_init(&er); if (0 != lportno) { DK4_MEMRES(&sl6, sizeof(sl6)); sl6.sin6_family = AF_INET6; sl6.sin6_port = dk4socket_htons(lportno); DK4_MEMCPY(&(sl6.sin6_addr),&dk4socket_any6,sizeof(IN6_ADDR)); back = dk4socket_tcp_client_for_addr( AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6), (struct sockaddr *)(&sl6), sizeof(sl6), secs, usecs, &er ); } else { back = dk4socket_tcp_client_for_addr( AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6), NULL, 0, secs, usecs, &er ); } if (INVALID_SOCKET == back) { #line 1547 "dk4socka07.ctr" /* ERROR: Failed */ dk4socket_report_connection_error( app, hostname, AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6), ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL), ((0 < lportno) ? (sizeof(sl6)) : 0), &er ); } else { /* DEBUG: Connection established (30) */ dk4socket_report_connection_established( app, hostname, AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6), ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL), ((0 < lportno) ? (sizeof(sl6)) : 0) ); } addrptr++; } } else { /* ERROR: Illegal address length (31) */ dk4socket_report_illegal_address_part(app, hostname, 31); } } break; #endif default : { /* ERROR: Illegal address family (32) */ dk4socket_report_illegal_address_part(app, hostname, 32); } break; } } else { /* ERROR: Remote host address not found! (33, 34) */ dk4socket_report_host_name_problem(app, hostname, 33, 34); } } else { dk4socket_error_report(&er, DK4_E_SOCKET_GETHOSTBYNAME); /* ERROR: Remote host address not found! (33, 34) */ dk4socket_report_host_name_problem(app, hostname, 33, 34); } } else { /* ERROR: Invalid arguments (bug) */ dk4socket_report_invalid_arguments(app); } #line 1591 "dk4socka07.ctr" return back; } /* ----- char, -getaddrinfo ----- */ #endif #endif