1%% options 2 3copyright owner = Dirk Krause 4copyright year = 2015-xxxx 5SPDX-License-Identifier: BSD-3-Clause 6 7 8%% module 9 10 11#include "dk4conf.h" 12#include <libdk4sock/dk4sock.h> 13#include <libdk4socka/dk4socka.h> 14#include <libdk4base/dk4mem.h> 15 16#if DK4_HAVE_GETADDRINFO 17#include <libdk4maio8d/dk4mao8d.h> 18#else 19#if DK4_CHAR_SIZE > 1 20#include <libdk4maiowd/dk4maiwdus.h> 21#include <libdk4c/dk4rec24.h> 22#endif 23#include <libdk4maio8d/dk4mai8dus.h> 24#endif 25 26#include <libdk4maiodd/dk4maiddus.h> 27#include <libdk4maiodd/dk4maodd.h> 28#include <libdk4maiodh/dk4maodh.h> 29 30#if DK4_HAVE_ASSERT_H 31#ifndef ASSERT_H_INCLUDED 32#include <assert.h> 33#define ASSERT_H_INCLUDED 1 34#endif 35#endif 36 37 38$!trace-include 39 40 41 42/** Constant texts used by module, not localized. 43*/ 44static const dkChar * const dk4socket_03_kwnl[] = { 45$!string-table macro=dkT 46# 47# 0 Separator to switch to next line. 48# 49\n\t 50# 51# 1 Separator between function name and message text 52# 53: 54# 55# 2 Separator between service and host name 56# 57@ 58$!end 59}; 60 61 62 63/* 64 Internal tool functions 65 ----------------------- 66*/ 67 68/** Report error from dk4socket_tcp_client_for_addr(). 69 @param app Application structure for logging. 70 @param afam Address family. 71 @param sremote Pointer to remote address buffer. 72 @param szremote Remote address size. 73 @param slocal Pointer to local address buffer. 74 @param szlocal Local address size. 75 @param erp Error report, required. 76*/ 77static 78void 79dk4socket_report_connection_error( 80 dk4_app_t *app, 81 int afam, 82 const struct sockaddr *sremote, 83 size_t szremote, 84 const struct sockaddr *slocal, 85 size_t szlocal, 86 dk4_er_t *erp 87) 88{ 89 const dkChar * msgt[32]; /* Message components */ 90 dkChar bdec[16*sizeof(dk4_um_t)]; /* Decimal */ 91 dkChar bhex[16*sizeof(dk4_um_t)]; /* Hexadecimal */ 92 dkChar bloc[128]; /* Local address */ 93 dkChar brem[128]; /* Remote address */ 94 const dkChar * const *msga = NULL; /* Localized texts */ 95 const dkChar *fctname = NULL; /* Name of failed function */ 96 const dkChar *msgtext = NULL; /* Text why fct failed */ 97#if VERSION_BEFORE_20150821 98 size_t szmsga = 0; /* Number of elems in msga */ 99#endif 100 size_t used = 0; /* No used elems in msgt */ 101 int res = 0; /* Conversion result */ 102 int bothbuf = 0; /* Flag: Have bdec and bhex */ 103 int fctnmsg = 0; /* Flag: Use fct name */ 104 $? "+ dk4socket_report_connection_error" 105 if (NULL != app) { 106 if (dk4app_log_do(app, DK4_LL_ERROR)) { 107#if VERSION_BEFORE_20150821 108 szmsga = dk4socket_log_num_texts(); 109#endif 110 msga = dk4socket_log_texts(app); 111 dk4socket_log_fctname_msg(&fctname, &msgtext, app, erp); 112 if (NULL == msgtext) { 113 res = dk4ma_write_decimal_signed( 114 bdec, DK4_SIZEOF(bdec,dkChar), (dk4_im_t)(erp->dt.iDetails1), 0, NULL 115 ); 116 if (0 != res) { 117 res = dk4ma_write_hex_signed( 118 bhex,DK4_SIZEOF(bhex,dkChar),(dk4_im_t)(erp->dt.iDetails1),0,NULL 119 ); 120 if (0 != res) { bothbuf = 1; } 121 } 122 } 123 msgt[used++] = msga[41]; 124 if ((NULL != slocal) && (0 < szlocal)) { 125 res = dk4socket_addr_port_to_text( 126 bloc, DK4_SIZEOF(bloc,dkChar), afam, slocal, szlocal, NULL 127 ); 128 if (DK4_SOCKET_RESULT_SUCCESS == res) { 129 msgt[used++] = dk4socket_03_kwnl[0]; 130 msgt[used++] = msga[42]; 131 msgt[used++] = bloc; 132 } 133 } 134 if ((NULL != sremote) && (0 < szremote)) { 135 res = dk4socket_addr_port_to_text( 136 brem, DK4_SIZEOF(brem,dkChar), afam, sremote, szremote, NULL 137 ); 138 if (DK4_SOCKET_RESULT_SUCCESS == res) { 139 msgt[used++] = dk4socket_03_kwnl[0]; 140 msgt[used++] = msga[43]; 141 msgt[used++] = brem; 142 } 143 } 144 switch (erp->ec) { 145 case DK4_E_INVALID_ARGUMENTS : { 146 msgt[used++] = dk4socket_03_kwnl[0]; 147 msgt[used++] = msga[45]; 148 } break; 149 case DK4_E_SOCKET_SOCKET : { 150 fctnmsg = 1; 151 msgt[used++] = dk4socket_03_kwnl[0]; 152 msgt[used++] = msga[2]; 153 } break; 154 case DK4_E_SOCKET_BIND : { 155 fctnmsg = 1; 156 msgt[used++] = dk4socket_03_kwnl[0]; 157 msgt[used++] = msga[4]; 158 } break; 159 case DK4_E_SOCKET_FCNTL : { 160 fctnmsg = 1; 161 msgt[used++] = dk4socket_03_kwnl[0]; 162 msgt[used++] = msga[9]; 163 } break; 164 case DK4_E_SOCKET_IOCTLSOCKET : { 165 fctnmsg = 1; 166 msgt[used++] = dk4socket_03_kwnl[0]; 167 msgt[used++] = msga[9]; 168 } break; 169 case DK4_E_SOCKET_CONNECT : { 170 fctnmsg = 1; 171 msgt[used++] = dk4socket_03_kwnl[0]; 172 msgt[used++] = msga[7]; 173 } break; 174 case DK4_E_SOCKET_TIMEOUT : { 175 msgt[used++] = dk4socket_03_kwnl[0]; 176 msgt[used++] = msga[44]; 177 } break; 178 case DK4_E_SOCKET_SELECT : { 179 fctnmsg = 1; 180 msgt[used++] = dk4socket_03_kwnl[0]; 181 msgt[used++] = msga[44]; 182 } break; 183 case DK4_E_SOCKET_GETSOCKOPT : { 184 fctnmsg = 1; 185 msgt[used++] = dk4socket_03_kwnl[0]; 186 msgt[used++] = msga[8]; 187 } break; 188 case DK4_E_SOCKET_SETSOCKOPT : { 189 fctnmsg = 1; 190 msgt[used++] = dk4socket_03_kwnl[0]; 191 msgt[used++] = msga[8]; 192 } break; 193 } 194 if (0 != fctnmsg) { 195 if ((NULL != fctname) && ((NULL != msgtext) || (0 != bothbuf))) { 196 msgt[used++] = dk4socket_03_kwnl[0]; 197 msgt[used++] = fctname; 198 msgt[used++] = dk4socket_03_kwnl[1]; 199 if (NULL != msgtext) { 200 msgt[used++] = msgtext; 201 } else { 202#if DK4_ON_WINDOWS 203 msgt[used++] = msga[40]; 204#else 205 msgt[used++] = msga[37]; 206#endif 207 msgt[used++] = bdec; 208 msgt[used++] = msga[38]; 209 msgt[used++] = bhex; 210 msgt[used++] = msga[39]; 211 } 212 } 213 } 214 dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); 215 } 216 } 217 $? "- dk4socket_report_connection_error" 218} 219 220 221 222/** Report error from dk4socket_tcp_client_for_addr(). 223 @param app Application structure for logging. 224 @param afam Address family. 225 @param sremote Pointer to remote address buffer. 226 @param szremote Remote address size. 227 @param slocal Pointer to local address buffer. 228 @param szlocal Local address size. 229 @param erp Error report, required. 230*/ 231static 232void 233dk4socket_report_connection_established( 234 dk4_app_t *app, 235 int afam, 236 const struct sockaddr *sremote, 237 size_t szremote, 238 const struct sockaddr *slocal, 239 size_t szlocal 240) 241{ 242 const dkChar * msgt[32]; /* Message components */ 243 dkChar bloc[128]; /* Local address */ 244 dkChar brem[128]; /* Remote address */ 245 const dkChar * const *msga = NULL; /* Localized texts */ 246#if VERSION_BEFORE_20150821 247 size_t szmsga = 0; /* Number of elems in msga */ 248#endif 249 size_t used = 0; /* No used elems in msgt */ 250 int res = 0; /* Conversion result */ 251 252 if (NULL != app) { 253 if (0 != dk4app_log_do(app, DK4_LL_PROGRESS)) { 254#if VERSION_BEFORE_20150821 255 szmsga = dk4socket_log_num_texts(); 256#endif 257 msga = dk4socket_log_texts(app); 258 msgt[used++] = msga[30]; 259 if ((NULL != slocal) && (0 < szlocal)) { 260 res = dk4socket_addr_port_to_text( 261 bloc, DK4_SIZEOF(bloc,dkChar), afam, slocal, szlocal, NULL 262 ); 263 if (DK4_SOCKET_RESULT_SUCCESS == res) { 264 msgt[used++] = dk4socket_03_kwnl[0]; 265 msgt[used++] = msga[42]; 266 msgt[used++] = bloc; 267 } 268 } 269 if ((NULL != sremote) && (0 < szremote)) { 270 res = dk4socket_addr_port_to_text( 271 brem, DK4_SIZEOF(brem,dkChar), afam, sremote, szremote, NULL 272 ); 273 if (DK4_SOCKET_RESULT_SUCCESS == res) { 274 msgt[used++] = dk4socket_03_kwnl[0]; 275 msgt[used++] = msga[43]; 276 msgt[used++] = brem; 277 } 278 } 279 dk4app_log_msg(app, DK4_LL_PROGRESS, msgt, used); 280 } 281 } 282} 283 284 285 286static 287void 288dk4socket_report_invalid_arguments( 289 dk4_app_t *app 290) 291{ 292 const dkChar * msgt[16]; 293 const dkChar * const *msga; 294#if VERSION_BEFORE_20150821 295 size_t szmsga; 296#endif 297 size_t used = 0; 298 if (NULL != app) { 299 if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { 300#if VERSION_BEFORE_20150821 301 szmsga = dk4socket_log_num_texts(); 302#endif 303 msga = dk4socket_log_texts(app); 304 msgt[used++] = msga[41]; 305 msgt[used++] = dk4socket_03_kwnl[0]; 306 msgt[used++] = msga[45]; 307 dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); 308 } 309 } 310} 311 312 313#if DK4_HAVE_GETADDRINFO 314/* +++++ +getaddrinfo +++++ */ 315 316static 317void 318dk4socket_report_no_matching_addresses( 319 const dkChar *hostname, 320 dk4_app_t *app 321) 322{ 323 const dkChar *msgt[16]; 324 const dkChar * const *msga; 325#if VERSION_BEFORE_20150821 326 size_t szmsga; 327#endif 328 if (NULL != app) { 329 if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { 330#if VERSION_BEFORE_20150821 331 szmsga = dk4socket_log_num_texts(); 332#endif 333 msga = dk4socket_log_texts(app); 334 msgt[0] = msga[41]; 335 msgt[1] = dk4socket_03_kwnl[0]; 336 msgt[2] = msga[43]; 337 msgt[4] = hostname; 338 msgt[5] = dk4socket_03_kwnl[0]; 339 msgt[6] = msga[46]; 340 dk4app_log_msg(app, DK4_LL_ERROR, msgt, 7); 341 } 342 } 343} 344 345 346 347static 348void 349dk4socket_report_gai( 350 const dkChar *hostname, 351 const dkChar *lsvcname, 352 int res, 353 int local, 354 dk4_app_t *app, 355 dk4_er_t *erp 356) 357{ 358 dkChar bdec[16*sizeof(dk4_um_t)]; 359 dkChar bhex[16*sizeof(dk4_um_t)]; 360 const dkChar *msgt[16]; 361 const dkChar * const *msga; 362 const dkChar *fctname = NULL; 363 const dkChar *msgtext = NULL; 364#if VERSION_BEFORE_20150821 365 size_t szmsga; 366#endif 367 size_t used = 0; 368 369 if (NULL != app) { 370 if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { 371#if VERSION_BEFORE_20150821 372 szmsga = dk4socket_log_num_texts(); 373#endif 374 msga = dk4socket_log_texts(app); 375 dk4socket_log_fctname_msg(&fctname, &msgtext, app, erp); 376 msgt[used++] = msga[41]; 377 if ((NULL != hostname) && (0 == local)) { 378 msgt[used++] = dk4socket_03_kwnl[0]; 379 msgt[used++] = msga[20]; 380 msgt[used++] = dk4socket_03_kwnl[0]; 381 msgt[used++] = msga[21]; 382 msgt[used++] = hostname; 383 if (NULL != lsvcname) { 384 msgt[used++] = dk4socket_03_kwnl[0]; 385 msgt[used++] = msga[22]; 386 msgt[used++] = lsvcname; 387 } 388 } else { 389 msgt[used++] = dk4socket_03_kwnl[0]; 390 msgt[used++] = msga[18]; 391 msgt[used++] = dk4socket_03_kwnl[0]; 392 msgt[used++] = msga[19]; 393 msgt[used++] = lsvcname; 394 } 395 if (NULL != fctname) { 396 if (NULL != msgtext) { 397 msgt[used++] = dk4socket_03_kwnl[0]; 398 msgt[used++] = fctname; 399 msgt[used++] = dk4socket_03_kwnl[1]; 400 msgt[used++] = msgtext; 401 } else { 402 res = dk4ma_write_decimal_signed( 403 bdec,DK4_SIZEOF(bdec,dkChar),(dk4_im_t)(erp->dt.iDetails1),0,NULL 404 ); 405 if (0 != res) { 406 res = dk4ma_write_hex_signed( 407 bhex,DK4_SIZEOF(bhex,dkChar),(dk4_im_t)(erp->dt.iDetails1),0,NULL 408 ); 409 if (0 != res) { 410 msgt[used++] = dk4socket_03_kwnl[0]; 411 msgt[used++] = fctname; 412 msgt[used++] = dk4socket_03_kwnl[1]; 413#if DK4_ON_WINDOWS 414 msgt[used++] = msga[40]; 415#else 416 msgt[used++] = msga[37]; 417#endif 418 msgt[used++] = bdec; 419 msgt[used++] = msga[38]; 420 msgt[used++] = bhex; 421 msgt[used++] = msga[39]; 422 } 423 } 424 } 425 } else { 426 } 427 dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); 428 } 429 } 430} 431 432#if DK4_CHAR_SIZE > 1 433 434/** Create a socket using remote and optionally local address lists. 435 @param hostname Remote host name. 436 @param rast List of remote addresses. 437 @param last List of local addresses, may be NULL. 438 @param secs Seconds for timeout. 439 @param usecs Microseconds for timeout. 440 @param app Application structure for diagnostics, may be NULL. 441 @return Valid socket on success, INVALID_SOCKET on error. 442*/ 443static 444dk4_socket_t 445dk4socket_tcp_client_addresses_app( 446 const dkChar *hostname, 447 ADDRINFOW *rast, 448 ADDRINFOW *last, 449 long secs, 450 long usecs, 451 dk4_app_t *app 452) 453{ 454 dk4_er_t er; 455 ADDRINFOW *ra; 456 ADDRINFOW *la; 457 dk4_socket_t back = INVALID_SOCKET; 458 int mpf = 0; 459 $? "+ dk4socket_tcp_client_addresses_app %d %d", TR_IPTR(rast), TR_IPTR(last) 460 ra = rast; 461 while ((INVALID_SOCKET == back) && (NULL != ra)) { 462 if (NULL != last) { 463 la = last; 464 while ((INVALID_SOCKET == back) && (NULL != la)) { 465 if (ra->ai_family == la->ai_family) { 466 mpf = 1; $? ". families match, attempt to connect" 467 dk4error_init(&er); 468 back = dk4socket_tcp_client_for_addr( 469 ra->ai_family, 470 ra->ai_addr, ra->ai_addrlen, 471 la->ai_addr, la->ai_addrlen, 472 secs, usecs, &er 473 ); 474 if (INVALID_SOCKET != back) { 475 dk4socket_report_connection_established( 476 app, ra->ai_family, 477 ra->ai_addr, ra->ai_addrlen, 478 la->ai_addr, la->ai_addrlen 479 ); 480 ra = NULL; la = NULL; 481 } else { $? "! report failure" 482 /* ERROR: Failed */ 483 dk4socket_report_connection_error( 484 app, ra->ai_family, 485 ra->ai_addr, ra->ai_addrlen, 486 la->ai_addr, la->ai_addrlen, 487 &er 488 ); 489 } 490 } 491 if (NULL != la) { la = la->ai_next; } 492 } 493 } else { 494 mpf = 1; 495 dk4error_init(&er); 496 back = dk4socket_tcp_client_for_addr( 497 ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0, secs, usecs, &er 498 ); 499 if (INVALID_SOCKET != back) { 500 dk4socket_report_connection_established( 501 app, ra->ai_family, 502 ra->ai_addr, ra->ai_addrlen, 503 NULL, 0 504 ); 505 ra = NULL; 506 } else { $? "! report failure" 507 /* ERROR: Failed */ 508 dk4socket_report_connection_error( 509 app,ra->ai_family,ra->ai_addr,ra->ai_addrlen,NULL,0,&er 510 ); 511 } 512 } 513 if (NULL != ra) { ra = ra->ai_next; } 514 } 515 if (INVALID_SOCKET == back) { 516 if (0 == mpf) { $? ". report no matching families" 517 /* ERROR: No matching address pair found (27) */ 518 dk4socket_report_no_matching_addresses(hostname, app); 519 } 520 } 521 $? "- dk4socket_tcp_client_addresses_app %d", (int)back 522 return back; 523} 524 525#else 526 527/** Create a socket using remote and optionally local address lists. 528 @param hostname Remote host name. 529 @param rast List of remote addresses. 530 @param last List of local addresses, may be NULL. 531 @param secs Seconds for timeout. 532 @param usecs Microseconds for timeout. 533 @param app Application structure for diagnostics, may be NULL. 534 @return Valid socket on success, INVALID_SOCKET on error. 535*/ 536static 537dk4_socket_t 538dk4socket_tcp_client_addresses_app( 539 const dkChar *hostname, 540 struct addrinfo *rast, 541 struct addrinfo *last, 542 long secs, 543 long usecs, 544 dk4_app_t *app 545) 546{ 547 dk4_er_t er; 548 struct addrinfo *ra; 549 struct addrinfo *la; 550 dk4_socket_t back = INVALID_SOCKET; 551 int mpf = 0; 552 $? "+ dk4socket_tcp_client_addresses_app %d %d", TR_IPTR(rast), TR_IPTR(last) 553 ra = rast; 554 while ((INVALID_SOCKET == back) && (NULL != ra)) { 555 if (NULL != last) { 556 la = last; 557 while ((INVALID_SOCKET == back) && (NULL != la)) { 558 if (ra->ai_family == la->ai_family) { 559 mpf = 1; 560 dk4error_init(&er); 561 back = dk4socket_tcp_client_for_addr( 562 ra->ai_family, 563 ra->ai_addr, ra->ai_addrlen, 564 la->ai_addr, la->ai_addrlen, 565 secs, usecs, &er 566 ); 567 if (INVALID_SOCKET != back) { 568 dk4socket_report_connection_established( 569 app, ra->ai_family, 570 ra->ai_addr, ra->ai_addrlen, 571 la->ai_addr, la->ai_addrlen 572 ); 573 ra = NULL; la = NULL; 574 } else { $? "! report failure" 575 /* ERROR: Failed */ 576 dk4socket_report_connection_error( 577 app, ra->ai_family, 578 ra->ai_addr, ra->ai_addrlen, 579 la->ai_addr, la->ai_addrlen, 580 &er 581 ); 582 } 583 } 584 if (NULL != la) { la = la->ai_next; } 585 } 586 } else { 587 mpf = 1; 588 dk4error_init(&er); 589 back = dk4socket_tcp_client_for_addr( 590 ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0, secs, usecs, &er 591 ); 592 if (INVALID_SOCKET != back) { 593 dk4socket_report_connection_established( 594 app, ra->ai_family, 595 ra->ai_addr, ra->ai_addrlen, 596 NULL, 0 597 ); 598 ra = NULL; 599 } else { $? "! report failure" 600 /* ERROR: Failed */ 601 dk4socket_report_connection_error( 602 app,ra->ai_family,ra->ai_addr,ra->ai_addrlen,NULL,0,&er 603 ); 604 } 605 } 606 if (NULL != ra) { ra = ra->ai_next; } 607 } 608 if (INVALID_SOCKET == back) { 609 if (0 == mpf) { 610 /* ERROR: No matching address pair found (27) */ 611 dk4socket_report_no_matching_addresses(hostname, app); 612 } 613 } 614 $? "- dk4socket_tcp_client_addresses_app %d", (int)back 615 return back; 616} 617 618#endif 619 620/* ----- +getaddrinfo ----- */ 621#else 622/* +++++ -getaddrinfo +++++ */ 623 624#if DK4_HAVE_STRUCT_SOCKADDR_IN6 625/** used to initialize IPv6 address for binding local ports. 626*/ 627static const IN6_ADDR dk4socket_any6 = IN6ADDR_ANY_INIT; 628#endif 629 630static 631void 632dk4socket_report_invalid_port_number(dk4_app_t *app, size_t i) 633{ 634 const dkChar * msgt[16]; 635 const dkChar * const *msga; 636 size_t szmsga; 637 size_t used = 0; 638 639 if (NULL != app) { 640 if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { 641 szmsga = dk4socket_log_num_texts(); 642 msga = dk4socket_log_texts(app); 643 msgt[used++] = msga[41]; 644 msgt[used++] = dk4socket_03_kwnl[0]; 645 msgt[used++] = msga[i]; 646 dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); 647 } 648 } 649} 650 651 652static 653void 654dk4socket_report_service_not_found(dk4_app_t *app, const dkChar *svcname) 655{ 656 const dkChar * msgt[16]; 657 const dkChar * const *msga; 658 size_t szmsga; 659 size_t used = 0; 660 661 if (NULL != app) { 662 if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { 663 szmsga = dk4socket_log_num_texts(); 664 msga = dk4socket_log_texts(app); 665 msgt[used++] = msga[23]; 666 msgt[used++] = svcname; 667 msgt[used++] = msga[24]; 668 dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); 669 } 670 } 671} 672 673 674 675#if DK4_CHAR_SIZE > 1 676 677static 678void 679dk4socket_report_service_not_ascii(dk4_app_t *app, const dkChar *svcname) 680{ 681 const dkChar * msgt[16]; 682 const dkChar * const *msga; 683 size_t szmsga; 684 size_t used = 0; 685 686 if (NULL != app) { 687 if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { 688 szmsga = dk4socket_log_num_texts(); 689 msga = dk4socket_log_texts(app); 690 msgt[used++] = msga[25]; 691 msgt[used++] = svcname; 692 msgt[used++] = msga[26]; 693 dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); 694 } 695 } 696} 697 698#endif 699 700 701 702static 703void 704dk4socket_report_illegal_address_part( 705 dk4_app_t *app, 706 const dkChar *hostname, 707 size_t i 708) 709{ 710 const dkChar * msgt[16]; 711 const dkChar * const *msga; 712 size_t szmsga; 713 size_t used = 0; 714 715 if (NULL != app) { 716 if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { 717 szmsga = dk4socket_log_num_texts(); 718 msga = dk4socket_log_texts(app); 719 msgt[used++] = msga[i]; 720 if (NULL != hostname) { 721 msgt[used++] = dk4socket_03_kwnl[0]; 722 msgt[used++] = msga[43]; 723 msgt[used++] = hostname; 724 } 725 dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); 726 } 727 } 728} 729 730 731 732static 733void 734dk4socket_report_host_name_problem( 735 dk4_app_t *app, 736 const dkChar *hostname, 737 size_t i1, 738 size_t i2 739) 740{ 741 const dkChar * msgt[16]; 742 const dkChar * const *msga; 743 size_t szmsga; 744 size_t used = 0; 745 746 if (NULL != app) { 747 if (0 != dk4app_log_do(app, DK4_LL_ERROR)) { 748 szmsga = dk4socket_log_num_texts(); 749 msga = dk4socket_log_texts(app); 750 if (NULL != hostname) { 751 msgt[used++] = msga[i1]; 752 msgt[used++] = hostname; 753 msgt[used++] = msga[i2]; 754 } 755 dk4app_log_msg(app, DK4_LL_ERROR, msgt, used); 756 } 757 } 758} 759 760/* ----- -getaddrinfo ----- */ 761#endif 762 763 764 765/* 766 Exported functions 767 ------------------ 768*/ 769 770#if DK4_CHAR_SIZE > 1 771#if DK4_ON_WINDOWS 772#if DK4_HAVE_GETADDRINFO 773/* +++++ wchar_t (Windows), +getaddrinfo +++++ */ 774 775 776 777dk4_socket_t 778dk4socket_tcp_client_for_host_num_service_app( 779 const dkChar *hostname, 780 const dkChar *svcname, 781 const dkChar *lsvcname, 782 long secs, 783 long usecs, 784 int nsrv, 785 dk4_app_t *app 786) 787{ 788 ADDRINFOW rhints; 789 ADDRINFOW lhints; 790 dk4_er_t er; 791 ADDRINFOW *rast = NULL; 792 ADDRINFOW *last = NULL; 793 dk4_socket_t back = INVALID_SOCKET; 794 int res; 795 $? "+ dk4socket_tcp_client_for_host_num_service_app (wchar_t +getaddrinfo)" 796#if DK4_USE_ASSERT 797 assert(NULL != hostname); 798 assert(NULL != svcname); 799#endif 800 if ((NULL != hostname) && (NULL != svcname)) { $? ". args ok" 801 DK4_MEMRES(&rhints, sizeof(rhints)); 802 rhints.ai_family = AF_UNSPEC; 803 rhints.ai_socktype = SOCK_STREAM; 804 if (0 != nsrv) { rhints.ai_flags = AI_NUMERICSERV; } 805 rhints.ai_protocol = 0; 806 dk4error_init(&er); 807 res = GetAddrInfoW(hostname, svcname, &rhints, &rast); 808 if ((0 == res) && (NULL != rast)) { $? ". getaddrinfo (remote)" 809 if (NULL != lsvcname) { $? ". local service name" 810 DK4_MEMRES(&lhints, sizeof(lhints)); 811 lhints.ai_family = AF_UNSPEC; 812 lhints.ai_socktype = SOCK_STREAM; 813 lhints.ai_flags = AI_PASSIVE; 814 if (0 != nsrv) { lhints.ai_flags |= AI_NUMERICSERV; } 815 lhints.ai_protocol = 0; 816 dk4error_init(&er); 817 res = GetAddrInfoW(NULL, lsvcname, &lhints, &last); 818 if ((0 == res) && (NULL != last)) { $? ". getaddrinfo local" 819 back = dk4socket_tcp_client_addresses_app( 820 hostname, rast, last, secs, usecs, app 821 ); 822 FreeAddrInfoW(last); 823 } else { $? "! getaddrinfo local" 824 /* ERROR: Failed to obtain local addresses to bind (18, 19) */ 825 dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res); 826 dk4socket_report_gai(NULL, lsvcname, res, 1, app, &er); 827 } 828 } else { $? ". no local service name" 829 back = dk4socket_tcp_client_addresses_app( 830 hostname, rast, NULL, secs, usecs, app 831 ); 832 } 833 FreeAddrInfoW(rast); 834 } else { $? "! getaddrinfo (remote)" 835 /* ERROR: Failed to obtain remote addresses (20, 21, 22) */ 836 dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res); 837 dk4socket_report_gai(hostname, svcname, res, 0, app, &er); 838 } 839 } else { $? "! args" 840 /* ERROR: Invalid arguments (bug) */ 841 dk4socket_report_invalid_arguments(app); 842 } 843 $? "- dk4socket_tcp_client_for_host_num_service_app (wchar_t) %d", (int)back 844 return back; 845} 846 847 848 849dk4_socket_t 850dk4socket_tcp_client_for_host_service_app( 851 const dkChar *hostname, 852 const dkChar *svcname, 853 const dkChar *lsvcname, 854 long secs, 855 long usecs, 856 dk4_app_t *app 857) 858{ 859 return ( 860 dk4socket_tcp_client_for_host_num_service_app( 861 hostname, svcname, lsvcname, secs, usecs, 0, app 862 ) 863 ); 864} 865 866 867 868dk4_socket_t 869dk4socket_tcp_client_for_host_port_app( 870 const dkChar *hostname, 871 unsigned short portno, 872 unsigned short lportno, 873 long secs, 874 long usecs, 875 dk4_app_t *app 876) 877{ 878 dkChar rpnb[16*sizeof(dk4_um_t)]; 879 dkChar lpnb[16*sizeof(dk4_um_t)]; 880 dk4_er_t er; 881 dk4_socket_t back = INVALID_SOCKET; 882 int res; 883 $? "+ dk4socket_tcp_client_for_host_port_app (wchar_t)" 884#if DK4_USE_ASSERT 885 assert(NULL != hostname); 886 assert(0 < portno); 887#endif 888 if ((NULL != hostname) && (0 < portno)) { $? ". args ok" 889 dk4error_init(&er); 890 res = dk4ma_write_decimal_unsigned( 891 rpnb, DK4_SIZEOF(rpnb,dkChar), (dk4_um_t)portno, 0, &er 892 ); 893 if (0 != res) { $? ". num to text" 894 if (0 < lportno) { $? ". local port" 895 dk4error_init(&er); 896 res = dk4ma_write_decimal_unsigned( 897 lpnb, DK4_SIZEOF(lpnb,dkChar), (dk4_um_t)lportno, 0, &er 898 ); 899 if (0 != res) { $? ". num to text" 900 back = dk4socket_tcp_client_for_host_num_service_app( 901 hostname, rpnb, lpnb, secs, usecs, 0, app 902 ); 903 } else { $? "! bug" 904 /* ERROR: Failed to convert local port number to text, bug */ 905 } 906 } else { $? ". no local port" 907 back = dk4socket_tcp_client_for_host_num_service_app( 908 hostname, rpnb, NULL, secs, usecs, 0, app 909 ); 910 } 911 } else { $? "! num to text" 912 /* ERROR: Failed to convert port number to text, bug */ 913 } 914 } else { $? "! args" 915 /* ERROR: Invalid arguments (bug) */ 916 dk4socket_report_invalid_arguments(app); 917 } 918 $? "- dk4socket_tcp_client_for_host_port_app (wchar_t) %d", (int)back 919 return back; 920} 921 922 923 924/* ----- wchar_t (Windows), +getaddrinfo ----- */ 925#else 926/* +++++ wchar_t (Windows), -getaddrinfo +++++ */ 927 928 929 930dk4_socket_t 931dk4socket_tcp_client_for_host_num_service_app( 932 const dkChar *hostname, 933 const dkChar *svcname, 934 const dkChar *lsvcname, 935 long secs, 936 long usecs, 937 int nsrv, 938 dk4_app_t *app 939) 940{ 941 char cppt[48]; 942 char cplp[48]; 943 dk4_er_t er; 944 struct servent *serv = NULL; 945 const dkChar *endptr = NULL; 946 dk4_socket_t back = INVALID_SOCKET; 947 int res = 0; 948 unsigned short rport = 0U; 949 unsigned short lport = 0U; 950 unsigned short iport = 0U; 951 $? "+ dk4socket_tcp_client_for_host_num_service_app (wchar_t)" 952#if DK4_USE_ASSERT 953 assert(NULL != hostname); 954 assert(NULL != svcname); 955#endif 956 if ((NULL != hostname) && (NULL != svcname)) { 957 dk4error_init(&er); 958 res = dk4ma_input_dk_dec_ushort(&rport, svcname, &endptr, 1, NULL); 959 if (0 == res) { 960 if (0 != dk4recode_wchar_t_to_char(cppt, sizeof(cppt), svcname, &er)) { 961 dk4socket_error_reset(); 962 serv = getservbyname(cppt, NULL); 963 if (NULL != serv) { 964 iport = serv->s_port; 965 dk4socket_swap_bytes_if_not_bigendian((void *)(&iport),sizeof(iport)); 966 rport = (unsigned short)iport; 967 } else { 968 dk4socket_error_report(&er, DK4_E_SOCKET_GETSERVBYNAME); 969 /* ERROR: Service not found (23, 24) */ 970 dk4socket_report_service_not_found(app, svcname); 971 } 972 } else { 973 /* ERROR: Failed to convert service name (25, 26) */ 974 dk4socket_report_service_not_ascii(app, svcname); 975 } 976 } 977 if (0 < rport) { 978 if (NULL != lsvcname) { 979 endptr = NULL; 980 dk4error_init(&er); 981 res = dk4ma_input_dk_dec_ushort(&lport, lsvcname, &endptr, 1, NULL); 982 if (0 == res) { 983 dk4error_init(&er); 984 if (0 != dk4recode_wchar_t_to_char(cplp,sizeof(cplp),lsvcname,&er)) { 985 dk4socket_error_reset(); 986 serv = getservbyname(cplp, NULL); 987 if (NULL != serv) { 988 iport = serv->s_port; 989 dk4socket_swap_bytes_if_not_bigendian( 990 (void *)(&iport), sizeof(iport) 991 ); 992 lport = (unsigned short)iport; 993 } else { 994 dk4socket_error_report(&er, DK4_E_SOCKET_GETSERVBYNAME); 995 /* Service not found (23, 24) */ 996 dk4socket_report_service_not_found(app, lsvcname); 997 } 998 } else { 999 /* ERROR: Text conversion failed (25, 26) */ 1000 dk4socket_report_service_not_ascii(app, lsvcname); 1001 } 1002 } 1003 if (0 < lport) { 1004 back = dk4socket_tcp_client_for_host_port_app( 1005 hostname, rport, lport, secs, usecs, app 1006 ); 1007 } else { 1008 /* ERROR: Illegal local port number (28) */ 1009 dk4socket_report_invalid_port_number(app, 28); 1010 } 1011 } else { 1012 back = dk4socket_tcp_client_for_host_port_app( 1013 hostname, rport, 0, secs, usecs, app 1014 ); 1015 } 1016 } else { 1017 /* ERROR: Illegal remote port number (29) */ 1018 dk4socket_report_invalid_port_number(app, 29); 1019 } 1020 } else { 1021 /* ERROR: Invalid arguments (bug) */ 1022 dk4socket_report_invalid_arguments(app); 1023 } 1024 $? "- dk4socket_tcp_client_for_host_num_service_app (wchar_t) %d", (int)back 1025 return back; 1026} 1027 1028 1029 1030dk4_socket_t 1031dk4socket_tcp_client_for_host_service_app( 1032 const dkChar *hostname, 1033 const dkChar *svcname, 1034 const dkChar *lsvcname, 1035 long secs, 1036 long usecs, 1037 dk4_app_t *app 1038) 1039{ 1040 return ( 1041 dk4socket_tcp_client_for_host_num_service_app( 1042 hostname, svcname, lsvcname, secs, usecs, 0, app 1043 ) 1044 ); 1045} 1046 1047 1048 1049dk4_socket_t 1050dk4socket_tcp_client_for_host_port_app( 1051 const dkChar *hostname, 1052 unsigned short portno, 1053 unsigned short lportno, 1054 long secs, 1055 long usecs, 1056 dk4_app_t *app 1057) 1058{ 1059 char hona[1040]; 1060#if DK4_HAVE_STRUCT_SOCKADDR_IN6 1061 struct sockaddr_in6 sr6; 1062 struct sockaddr_in6 sl6; 1063#endif 1064 struct sockaddr_in sr4; 1065 struct sockaddr_in sl4; 1066 dk4_er_t er; 1067 char **addrptr; 1068 struct hostent *hep; 1069 dk4_socket_t back = INVALID_SOCKET; 1070 1071 $? "+ dk4socket_tcp_client_for_host_port_app (wchar_t)" 1072#if DK4_USE_ASSERT 1073 assert(NULL != hostname); 1074 assert(0 < portno); 1075#endif 1076 if ((NULL != hostname) && (0 < portno)) { 1077 dk4error_init(&er); 1078 if (0 != dk4recode_wchar_t_to_char(hona, sizeof(hona), hostname, &er)) { 1079 dk4socket_error_reset(); 1080 hep = gethostbyname(hona); 1081 if (NULL != hep) { 1082 if (NULL != hep->h_addr_list) { 1083 switch (hep->h_addrtype) { 1084 case AF_INET : { 1085 if (4 == hep->h_length) { 1086 addrptr = hep->h_addr_list; 1087 while ((INVALID_SOCKET == back) && (NULL != *addrptr)) { 1088 DK4_MEMRES(&sr4, sizeof(sr4)); 1089 sr4.sin_family = AF_INET; 1090 sr4.sin_port = dk4socket_htons(portno); 1091 DK4_MEMCPY(&(sr4.sin_addr), *addrptr, sizeof(IN_ADDR)); 1092 dk4error_init(&er); 1093 if (0 != lportno) { 1094 DK4_MEMRES(&sl4, sizeof(sl4)); 1095 sl4.sin_family = AF_INET; 1096 sl4.sin_port = dk4socket_htons(lportno); 1097 sl4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY); 1098 back = dk4socket_tcp_client_for_addr( 1099 AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4), 1100 (struct sockaddr *)(&sl4), sizeof(sl4), secs, usecs, &er 1101 ); 1102 } else { 1103 back = dk4socket_tcp_client_for_addr( 1104 AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4), 1105 NULL, 0, secs, usecs, &er 1106 ); 1107 } 1108 if (INVALID_SOCKET == back) { $? "! report failure" 1109 /* ERROR: Failed */ 1110 dk4socket_report_connection_error( 1111 app, AF_INET, 1112 (struct sockaddr *)(&sr4), sizeof(sr4), 1113 ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL), 1114 ((0 < lportno) ? (sizeof(sl4)) : 0), 1115 &er 1116 ); 1117 } else { 1118 /* DEBUG: Connection established (30) */ 1119 dk4socket_report_connection_established( 1120 app, AF_INET, 1121 (struct sockaddr *)(&sr4), sizeof(sr4), 1122 ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL), 1123 ((0 < lportno) ? (sizeof(sl4)) : 0) 1124 ); 1125 } 1126 addrptr++; 1127 } 1128 } else { 1129 /* ERROR: Illegal address length, bug (31) */ 1130 dk4socket_report_illegal_address_part(app, hostname, 31); 1131 } 1132 } break; 1133#if DK4_HAVE_STRUCT_SOCKADDR_IN6 1134 case AF_INET6 : { 1135 if (16 == hep->h_length) { 1136 addrptr = hep->h_addr_list; 1137 while ((INVALID_SOCKET == back) && (NULL != *addrptr)) { 1138 DK4_MEMRES(&sr6, sizeof(sr6)); 1139 sr6.sin6_family = AF_INET6; 1140 sr6.sin6_port = dk4socket_htons(portno); 1141 DK4_MEMCPY(&(sr6.sin6_addr), *addrptr, sizeof(IN6_ADDR)); 1142 dk4error_init(&er); 1143 if (0 < lportno) { 1144 DK4_MEMRES(&sl6, sizeof(sl6)); 1145 sl6.sin6_family = AF_INET6; 1146 sl6.sin6_port = dk4socket_htons(lportno); 1147 DK4_MEMCPY(&(sl6.sin6_addr),&dk4socket_any6,sizeof(IN6_ADDR)); 1148 back = dk4socket_tcp_client_for_addr( 1149 AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6), 1150 (struct sockaddr *)(&sl6), sizeof(sl6), secs, usecs, &er 1151 ); 1152 } else { 1153 back = dk4socket_tcp_client_for_addr( 1154 AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6), 1155 NULL, 0, secs, usecs, &er 1156 ); 1157 } 1158 if (INVALID_SOCKET == back) { $? "! report failure" 1159 /* ERROR: Failed */ 1160 dk4socket_report_connection_error( 1161 app, AF_INET6, 1162 (struct sockaddr *)(&sr6), sizeof(sr6), 1163 ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL), 1164 ((0 < lportno) ? (sizeof(sl6)) : 0), 1165 &er 1166 ); 1167 } else { 1168 /* DEBUG: Connection established (30) */ 1169 dk4socket_report_connection_established( 1170 app, AF_INET6, 1171 (struct sockaddr *)(&sr6), sizeof(sr6), 1172 ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL), 1173 ((0 < lportno) ? (sizeof(sl6)) : 0) 1174 ); 1175 } 1176 addrptr++; 1177 } 1178 } else { 1179 /* ERROR: Illegal address length, bug (31) */ 1180 dk4socket_report_illegal_address_part(app, hostname, 31); 1181 } 1182 } break; 1183#endif 1184 default : { 1185 /* ERROR: Illegal address family (32) */ 1186 dk4socket_report_illegal_address_part(app, hostname, 32); 1187 } break; 1188 } 1189 } else { 1190 /* ERROR: Host not found (33, 34) */ 1191 dk4socket_report_host_name_problem(app, hostname, 33, 34); 1192 } 1193 } else { 1194 dk4socket_error_report(&er, DK4_E_SOCKET_GETHOSTBYNAME); 1195 /* ERROR: Host not found (33, 34) */ 1196 dk4socket_report_host_name_problem(app, hostname, 33, 34); 1197 } 1198 } else { 1199 /* ERROR: Failed to convert host name to ASCII (35, 36) */ 1200 dk4socket_report_host_name_problem(app, hostname, 35, 36); 1201 } 1202 } else { 1203 /* ERROR: Invalid arguments (bug) */ 1204 dk4socket_report_invalid_arguments(app); 1205 } 1206 $? "- dk4socket_tcp_client_for_host_port_app (wchar_t) %d", (int)back 1207 return back; 1208} 1209 1210 1211 1212/* ----- wchar_t (Windows), -getaddrinfo ----- */ 1213#endif 1214#else 1215#error No support for networking with wchar_t strings! 1216#endif 1217#else 1218#if DK4_HAVE_GETADDRINFO 1219/* +++++ char, +getaddrinfo +++++ */ 1220 1221dk4_socket_t 1222dk4socket_tcp_client_for_host_num_service_app( 1223 const dkChar *hostname, 1224 const dkChar *svcname, 1225 const dkChar *lsvcname, 1226 long secs, 1227 long usecs, 1228 int nsrv, 1229 dk4_app_t *app 1230) 1231{ 1232 struct addrinfo rhints; 1233 struct addrinfo lhints; 1234 dk4_er_t er; 1235 struct addrinfo *raddrst = NULL; 1236 struct addrinfo *laddrst = NULL; 1237 dk4_socket_t back = INVALID_SOCKET; 1238 int res; 1239 $? "+ dk4socket_tcp_client_for_host_num_service_app (char)" 1240#if DK4_USE_ASSERT 1241 assert(NULL != hostname); 1242 assert(NULL != svcname); 1243#endif 1244 $? ". svcname \"%!ds\"", TR_STR(svcname) 1245 $? ". lsvcname \"%!ds\"", TR_STR(lsvcname) 1246 if ((NULL != hostname) && (NULL != svcname)) { $? ". args ok" 1247 DK4_MEMRES(&rhints, sizeof(rhints)); 1248 rhints.ai_family = AF_UNSPEC; 1249 rhints.ai_socktype = SOCK_STREAM; 1250 if (0 != nsrv) { rhints.ai_flags = AI_NUMERICSERV; } 1251 rhints.ai_protocol = 0; 1252 dk4error_init(&er); 1253 res = getaddrinfo(hostname, svcname, &rhints, &raddrst); 1254 if ((0 == res) && (NULL != raddrst)) { $? ". remote addr ok" 1255 if (NULL != lsvcname) { $? ". need local addr" 1256 DK4_MEMRES(&lhints, sizeof(lhints)); 1257 lhints.ai_family = AF_UNSPEC; 1258 lhints.ai_socktype = SOCK_STREAM; 1259 lhints.ai_flags = AI_PASSIVE; 1260 if (0 != nsrv) { lhints.ai_flags |= AI_NUMERICSERV; } 1261 lhints.ai_protocol = 0; 1262 dk4error_init(&er); 1263 res = getaddrinfo(NULL, lsvcname, &lhints, &laddrst); 1264 if ((0 == res) && (NULL != laddrst)) { $? ". use local addr" 1265 back = dk4socket_tcp_client_addresses_app( 1266 hostname, raddrst, laddrst, secs, usecs, app 1267 ); 1268 freeaddrinfo(laddrst); 1269 } else { $? "! no local addr" 1270 /* ERROR: Failed to obtain local addresses (18, 19) */ 1271 dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res); 1272 dk4socket_report_gai(NULL, lsvcname, res, 1, app, &er); 1273 } 1274 } else { $? ". no local addr" 1275 back = dk4socket_tcp_client_addresses_app( 1276 hostname, raddrst, NULL, secs, usecs, app 1277 ); 1278 } 1279 freeaddrinfo(raddrst); 1280 } else { $? "! remote" 1281 /* ERROR: Failed to obtain remote addresses (20, 21, 22) */ 1282 dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res); 1283 dk4socket_report_gai(hostname, svcname, res, 0, app, &er); 1284 } 1285 } else { $? "! args" 1286 /* ERROR: Invalid arguments (bug) */ 1287 dk4socket_report_invalid_arguments(app); 1288 } 1289 $? "- dk4socket_tcp_client_for_host_num_service_app (char) %d", (int)back 1290 return back; 1291} 1292 1293 1294 1295dk4_socket_t 1296dk4socket_tcp_client_for_host_service_app( 1297 const dkChar *hostname, 1298 const dkChar *svcname, 1299 const dkChar *lsvcname, 1300 long secs, 1301 long usecs, 1302 dk4_app_t *app 1303) 1304{ 1305 return ( 1306 dk4socket_tcp_client_for_host_num_service_app( 1307 hostname, svcname, lsvcname, secs, usecs, 0, app 1308 ) 1309 ); 1310} 1311 1312 1313 1314dk4_socket_t 1315dk4socket_tcp_client_for_host_port_app( 1316 const dkChar *hostname, 1317 unsigned short portno, 1318 unsigned short lportno, 1319 long secs, 1320 long usecs, 1321 dk4_app_t *app 1322) 1323{ 1324 char rpn[16*sizeof(dk4_um_t)]; 1325 char lpn[16*sizeof(dk4_um_t)]; 1326 dk4_socket_t back = INVALID_SOCKET; 1327 int res; 1328 $? "+ dk4socket_tcp_client_for_host_port_app (char)" 1329#if DK4_USE_ASSERT 1330 assert(NULL != hostname); 1331 assert(0 < portno); 1332#endif 1333 if ((NULL != hostname) && (0 < portno)) { 1334 res = dk4ma_write_c8_decimal_unsigned( 1335 rpn, sizeof(rpn), (dk4_um_t)portno, 0, NULL 1336 ); 1337 if (0 != res) { 1338 if (0 < lportno) { 1339 res = dk4ma_write_c8_decimal_unsigned( 1340 lpn, sizeof(lpn), (dk4_um_t)lportno, 0, NULL 1341 ); 1342 if (0 != res) { 1343 back = dk4socket_tcp_client_for_host_num_service_app( 1344 hostname, rpn, lpn, secs, usecs, 1, app 1345 ); 1346 } else { 1347 /* ERROR: Failed to convert port number to text, bug */ 1348 } 1349 } else { 1350 back = dk4socket_tcp_client_for_host_num_service_app( 1351 hostname, rpn, NULL, secs, usecs, 1, app 1352 ); 1353 } 1354 } else { 1355 /* ERROR: Failed to convert port number to text, bug */ 1356 } 1357 } else { 1358 /* ERROR: Invalid arguments (bug) */ 1359 dk4socket_report_invalid_arguments(app); 1360 } 1361 $? "- dk4socket_tcp_client_for_host_port_app (char) %d", (int)back 1362 return back; 1363} 1364 1365 1366 1367/* ----- char, +getaddrinfo ----- */ 1368#else 1369/* +++++ char, -getaddrinfo ----- */ 1370 1371 1372 1373dk4_socket_t 1374dk4socket_tcp_client_for_host_num_service_app( 1375 const dkChar *hostname, 1376 const dkChar *svcname, 1377 const dkChar *lsvcname, 1378 long secs, 1379 long usecs, 1380 int nsrv, 1381 dk4_app_t *app 1382) 1383{ 1384 const char *endptr = NULL; 1385 struct servent *serv = NULL; 1386 dk4_socket_t back = INVALID_SOCKET; 1387 int res = 0; 1388 int iport = 0; 1389 unsigned short rport = 0; 1390 unsigned short lport = 0; 1391 $? "+ dk4socket_tcp_client_for_host_num_service_app (char)" 1392#if DK4_USE_ASSERT 1393 assert(NULL != hostname); 1394 assert(NULL != svcname); 1395#endif 1396 if ((NULL != hostname) && (NULL != svcname)) { 1397 res = dk4ma_input_c8_dec_ushort(&rport, svcname, &endptr, 1, NULL); 1398 if (0 == res) { 1399 dk4socket_error_reset(); 1400 serv = getservbyname(svcname, NULL); 1401 if (NULL != serv) { 1402 iport = serv->s_port; 1403 dk4socket_swap_bytes_if_not_bigendian((void *)(&iport), sizeof(iport)); 1404 rport = (unsigned short)iport; 1405 } else { 1406 /* ERROR: Service name for remote port not found (23, 24) */ 1407 dk4socket_report_service_not_found(app, svcname); 1408 } 1409 } 1410 if (0 != rport) { 1411 if (NULL != lsvcname) { 1412 endptr = NULL; 1413 res = dk4ma_input_c8_dec_ushort(&lport, lsvcname, &endptr, 1, NULL); 1414 if (0 == res) { 1415 dk4socket_error_reset(); 1416 serv = getservbyname(lsvcname, NULL); 1417 if (NULL != serv) { 1418 iport = serv->s_port; 1419 dk4socket_swap_bytes_if_not_bigendian( 1420 (void *)(&iport), sizeof(iport) 1421 ); 1422 lport = (unsigned short)iport; 1423 } else { 1424 /* ERROR: Service name for local port not found (23, 24) */ 1425 dk4socket_report_service_not_found(app, lsvcname); 1426 } 1427 } 1428 if (0 != lport) { 1429 back = dk4socket_tcp_client_for_host_port_app( 1430 hostname, rport, lport, secs, usecs, app 1431 ); 1432 } else { 1433 /* ERROR: Illegal local port number (28) */ 1434 dk4socket_report_invalid_port_number(app, 28); 1435 } 1436 } else { 1437 back = dk4socket_tcp_client_for_host_port_app( 1438 hostname, rport, 0, secs, usecs, app 1439 ); 1440 } 1441 } else { 1442 /* ERROR: Illegal remote port number (29) */ 1443 dk4socket_report_invalid_port_number(app, 29); 1444 } 1445 } else { 1446 /* ERROR: Invalid arguments (bug) */ 1447 dk4socket_report_invalid_arguments(app); 1448 } 1449 $? "- dk4socket_tcp_client_for_host_num_service_app (char) %d", (int)back 1450 return back; 1451} 1452 1453 1454 1455dk4_socket_t 1456dk4socket_tcp_client_for_host_service_app( 1457 const dkChar *hostname, 1458 const dkChar *svcname, 1459 const dkChar *lsvcname, 1460 long secs, 1461 long usecs, 1462 dk4_app_t *app 1463) 1464{ 1465 return ( 1466 dk4socket_tcp_client_for_host_num_service_app( 1467 hostname, svcname, lsvcname, secs, usecs, 0, app 1468 ) 1469 ); 1470} 1471 1472 1473 1474dk4_socket_t 1475dk4socket_tcp_client_for_host_port_app( 1476 const dkChar *hostname, 1477 unsigned short portno, 1478 unsigned short lportno, 1479 long secs, 1480 long usecs, 1481 dk4_app_t *app 1482) 1483{ 1484 dk4_er_t er; 1485#if DK4_HAVE_STRUCT_SOCKADDR_IN6 1486 struct sockaddr_in6 sr6; 1487 struct sockaddr_in6 sl6; 1488#endif 1489 struct sockaddr_in sr4; 1490 struct sockaddr_in sl4; 1491 char **addrptr; 1492 struct hostent *hep = NULL; 1493 dk4_socket_t back = INVALID_SOCKET; 1494 $? "+ dk4socket_tcp_client_for_host_port_app (char)" 1495#if DK4_USE_ASSERT 1496 assert(NULL != hostname); 1497 assert(0 < portno); 1498#endif 1499 if ((NULL != hostname) && (0 < portno)) { 1500 dk4error_init(&er); 1501 dk4socket_error_reset(); 1502 hep = gethostbyname(hostname); 1503 if (NULL != hep) { 1504 if (NULL != hep->h_addr_list) { 1505 switch (hep->h_addrtype) { 1506 case AF_INET : { 1507 if (4 == hep->h_length) { 1508 addrptr = hep->h_addr_list; 1509 while ((INVALID_SOCKET == back) && (NULL != *addrptr)) { 1510 DK4_MEMRES(&sr4, sizeof(sr4)); 1511 sr4.sin_family = AF_INET; 1512 sr4.sin_port = dk4socket_htons(portno); 1513 DK4_MEMCPY(&(sr4.sin_addr), *addrptr, sizeof(IN_ADDR)); 1514 dk4error_init(&er); 1515 if (0 != lportno) { 1516 DK4_MEMRES(&sl4, sizeof(sl4)); 1517 sl4.sin_family = AF_INET; 1518 sl4.sin_port = dk4socket_htons(lportno); 1519 sl4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY); 1520 back = dk4socket_tcp_client_for_addr( 1521 AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4), 1522 (struct sockaddr *)(&sl4), sizeof(sl4), secs, usecs, &er 1523 ); 1524 } else { 1525 back = dk4socket_tcp_client_for_addr( 1526 AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4), 1527 NULL, 0, secs, usecs, &er 1528 ); 1529 } 1530 if (INVALID_SOCKET == back) { $? "! report failure" 1531 /* ERROR: Failed */ 1532 dk4socket_report_connection_error( 1533 app, AF_INET, 1534 (struct sockaddr *)(&sr4), sizeof(sr4), 1535 ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL), 1536 ((0 < lportno) ? (sizeof(sl4)) : 0), 1537 &er 1538 ); 1539 } else { 1540 /* DEBUG: Connection established (30) */ 1541 dk4socket_report_connection_established( 1542 app, AF_INET, 1543 (struct sockaddr *)(&sr4), sizeof(sr4), 1544 ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL), 1545 ((0 < lportno) ? (sizeof(sl4)) : 0) 1546 ); 1547 } 1548 addrptr++; 1549 } 1550 } else { 1551 /* ERROR: Illegal address length (31) */ 1552 dk4socket_report_illegal_address_part(app, hostname, 31); 1553 } 1554 } break; 1555#if DK4_HAVE_STRUCT_SOCKADDR_IN6 1556 case AF_INET6 : { 1557 if (16 == hep->h_length) { 1558 addrptr = hep->h_addr_list; 1559 while ((INVALID_SOCKET == back) && (NULL != *addrptr)) { 1560 DK4_MEMRES(&sr6, sizeof(sr6)); 1561 sr6.sin6_family = AF_INET6; 1562 sr6.sin6_port = dk4socket_htons(portno); 1563 DK4_MEMCPY(&(sr6.sin6_addr), *addrptr, sizeof(IN6_ADDR)); 1564 dk4error_init(&er); 1565 if (0 != lportno) { 1566 DK4_MEMRES(&sl6, sizeof(sl6)); 1567 sl6.sin6_family = AF_INET6; 1568 sl6.sin6_port = dk4socket_htons(lportno); 1569 DK4_MEMCPY(&(sl6.sin6_addr),&dk4socket_any6,sizeof(IN6_ADDR)); 1570 back = dk4socket_tcp_client_for_addr( 1571 AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6), 1572 (struct sockaddr *)(&sl6), sizeof(sl6), 1573 secs, usecs, &er 1574 ); 1575 } else { 1576 back = dk4socket_tcp_client_for_addr( 1577 AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6), 1578 NULL, 0, secs, usecs, &er 1579 ); 1580 } 1581 if (INVALID_SOCKET == back) { $? "! report failure" 1582 /* ERROR: Failed */ 1583 dk4socket_report_connection_error( 1584 app, AF_INET6, 1585 (struct sockaddr *)(&sr6), sizeof(sr6), 1586 ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL), 1587 ((0 < lportno) ? (sizeof(sl6)) : 0), 1588 &er 1589 ); 1590 } else { 1591 /* DEBUG: Connection established (30) */ 1592 dk4socket_report_connection_established( 1593 app, AF_INET6, 1594 (struct sockaddr *)(&sr6), sizeof(sr6), 1595 ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL), 1596 ((0 < lportno) ? (sizeof(sl6)) : 0) 1597 ); 1598 } 1599 addrptr++; 1600 } 1601 } else { 1602 /* ERROR: Illegal address length (31) */ 1603 dk4socket_report_illegal_address_part(app, hostname, 31); 1604 } 1605 } break; 1606#endif 1607 default : { 1608 /* ERROR: Illegal address family (32) */ 1609 dk4socket_report_illegal_address_part(app, hostname, 32); 1610 } break; 1611 } 1612 } else { 1613 /* ERROR: Remote host address not found! (33, 34) */ 1614 dk4socket_report_host_name_problem(app, hostname, 33, 34); 1615 } 1616 } else { 1617 dk4socket_error_report(&er, DK4_E_SOCKET_GETHOSTBYNAME); 1618 /* ERROR: Remote host address not found! (33, 34) */ 1619 dk4socket_report_host_name_problem(app, hostname, 33, 34); 1620 } 1621 } else { 1622 /* ERROR: Invalid arguments (bug) */ 1623 dk4socket_report_invalid_arguments(app); 1624 } 1625 $? "- dk4socket_tcp_client_for_host_port_app (char) %d", (int)back 1626 return back; 1627} 1628 1629 1630 1631/* ----- char, -getaddrinfo ----- */ 1632#endif 1633#endif 1634 1635