This file is indexed.

/usr/include/ncbi/connect/ncbi_socket.h is in libncbi6-dev 6.1.20120620-8.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
#ifndef CONNECT___NCBI_SOCKET__H
#define CONNECT___NCBI_SOCKET__H

/* $Id: ncbi_socket.h,v 6.90 2012/06/07 00:54:33 kazimird Exp $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
 *               National Center for Biotechnology Information
 *
 *  This software/database is a "United States Government Work" under the
 *  terms of the United States Copyright Act.  It was written as part of
 *  the author's official duties as a United States Government employee and
 *  thus cannot be copyrighted.  This software/database is freely available
 *  to the public for use. The National Library of Medicine and the U.S.
 *  Government have not placed any restriction on its use or reproduction.
 *
 *  Although all reasonable efforts have been taken to ensure the accuracy
 *  and reliability of the software and data, the NLM and the U.S.
 *  Government do not and cannot warrant the performance or results that
 *  may be obtained by using this software or data. The NLM and the U.S.
 *  Government disclaim all warranties, express or implied, including
 *  warranties of performance, merchantability or fitness for any particular
 *  purpose.
 *
 *  Please cite the author in any work or product based on this material.
 *
 * ===========================================================================
 *
 * Authors:  Denis Vakatov, Anton Lavrentiev
 *
 * @file
 * File Description:
 *   Plain portable TCP/IP socket API for:  UNIX, MS-Win, MacOS
 *   Platform-specific library requirements:
 *     [UNIX ]   -DNCBI_OS_UNIX     -lresolv -lsocket -lnsl
 *     [MSWIN]   -DNCBI_OS_MSWIN    ws2_32.lib
 *
 *********************************
 * Generic:
 *
 *  SOCK_InitializeAPI
 *  SOCK_ShutdownAPI
 *  SOCK_AllowSigPipeAPI
 *  SOCK_OSHandleSize
 *
 * Event trigger (handle TRIGGER):
 *
 *  TRIGGER_Create
 *  TRIGGER_Close
 *  TRIGGER_Set
 *  TRIGGER_IsSet
 *  TRIGGER_Reset
 *
 * Listening socket (handle LSOCK):
 *
 *  LSOCK_Create[Ex]
 *  LSOCK_Accept[Ex]
 *  LSOCK_Close
 *  LSOCK_GetOSHandle[Ex]
 *  LSOCK_GetPort
 *
 * I/O Socket (handle SOCK):
 *
 *  SOCK_Create[Ex]      (see also LSOCK_Accept)
 *  SOCK_CreateOnTop[Ex]
 *  SOCK_Reconnect
 *  SOCK_Shutdown
 *  SOCK_Close[Ex]
 *  SOCK_Destroy
 *  SOCK_CloseOSHandle
 *  SOCK_Wait
 *  SOCK_Poll
 *  SOCK_SetTimeout
 *  SOCK_GetTimeout
 *  SOCK_Read (including "peek" and "persistent read")
 *  SOCK_ReadLine
 *  SOCK_PushBack
 *  SOCK_Status
 *  SOCK_Write
 *  SOCK_Abort
 *  SOCK_GetLocalPort[Ex]
 *  SOCK_GetRemotePort
 *  SOCK_GetPeerAddress
 *  SOCK_GetPeerAddressString[Ex]
 *  SOCK_GetOSHandle[Ex]
 *  SOCK_SetReadOnWriteAPI
 *  SOCK_SetReadOnWrite
 *  SOCK_SetCork
 *  SOCK_DisableOSSendDelay
 *
 * Datagram Socket:
 *
 *  DSOCK_Create[Ex]
 *  DSOCK_Bind
 *  DSOCK_Connect
 *  DSOCK_WaitMsg
 *  DSOCK_SendMsg
 *  DSOCK_RecvMsg
 *  DSOCK_WipeMsg
 *  DSOCK_SetBroadcast
 *  DSOCK_GetMessageCount
 *
 * Socket classification & statistics:
 *
 *  SOCK_IsDatagram
 *  SOCK_IsClientSide
 *  SOCK_IsServerSide
 *  SOCK_IsUNIX
 *  SOCK_IsSecure
 *  SOCK_GetPosition
 *  SOCK_GetCount
 *  SOCK_GetTotalCount
 *
 * Settings:
 *
 *  SOCK_SetInterruptOnSignalAPI
 *  SOCK_SetInterruptOnSignal
 *  SOCK_SetReuseAddressAPI
 *  SOCK_SetReuseAddress
 *
 * Data logging:
 *
 *  SOCK_SetDataLoggingAPI
 *  SOCK_SetDataLogging
 *
 * Auxiliary:
 *
 *  SOCK_ntoa
 *  SOCK_isip[Ex]
 *  SOCK_HostToNetShort
 *  SOCK_HostToNetLong
 *  SOCK_NetToHostShort
 *  SOCK_NetToHostLong
 *  SOCK_gethostname[Ex]
 *  SOCK_gethostbyname[Ex]
 *  SOCK_gethostbyaddr[Ex]
 *  SOCK_GetLoopbackAddress
 *  SOCK_GetLocalHostAddress
 *  SOCK_StringToHostPort
 *  SOCK_HostPortToString
 *
 * Utility:
 *
 *  SOCK_SetSelectInternalRestartTimeout
 *  SOCK_SetIOWaitSysAPI
 *
 * Secure Socket Layer:
 *
 *  SOCK_SetupSSL
 *
 */

#if defined(NCBISOCK__H)
#  error "<ncbisock.h> and <ncbi_socket.h> must never be #include'd together"
#endif

#include <connect/ncbi_core.h>


/** @addtogroup Sockets
 *
 * @{
 */


#ifdef __cplusplus
extern "C" {
#endif


/******************************************************************************
 *  TYPEDEFS & MACROS
 */


/** Network and host byte order enumeration type
 */
typedef enum {
    eNH_HostByteOrder,
    eNH_NetworkByteOrder
} ENH_ByteOrder;


/** Forward declarations of the hidden socket internal structures, and
 *  their upper-level handles to use by the SOCK API.
 */
struct LSOCK_tag;                     /* listening socket:  internal storage */
typedef struct LSOCK_tag*   LSOCK;    /* listening socket:  handle, opaque   */

struct SOCK_tag;                      /* socket:  internal storage           */
typedef struct SOCK_tag*    SOCK;     /* socket:  handle, opaque             */

struct TRIGGER_tag;                   /* trigger: internal storage           */
typedef struct TRIGGER_tag* TRIGGER;  /* trigger: handle, opaque             */



/******************************************************************************
 *                       Multi-Thread safety NOTICE
 *
 * If you are using this API in a multi-threaded application, and there is
 * more than one thread using this API, it is safe to call SOCK_InitializeAPI()
 * explicitly at the beginning of your main thread, before you run any other
 * threads, and to call SOCK_ShutdownAPI() after all threads have exited.
 *
 * As soon as the API is initialized it becomes relatively MT-safe, however
 * you still must not operate on same LSOCK or SOCK objects from different
 * threads simultaneously.  Any entry point of this API will attempt to
 * initialize the API implicitly if that has not yet been previously done.
 * However, the implicit initialization gets disabled by SOCK_ShutdownAPI()
 * (explicit re-init with SOCK_InitializeAPI() is always allowed).
 *
 * A MUCH BETTER WAY of dealing with this issue is to provide your own MT
 * locking callback (see CORE_SetLOCK() in "ncbi_core.h").  This will also
 * ensure proper MT protection should some SOCK functions start accessing
 * any intrinsic static data (such as in case of SSL).
 *
 * The MT lock as well as other library-wide settings are also provided
 * (in most cases automatically) by CONNECT_Init() API:  for C Toolkit it gets
 * always called before [Nlm_]Main();  in C++ Toolkit it gets called by
 * most of C++ classes' ctors, except for sockets;  so if your application
 * does not use any C++ classes besides sockets, it has to set CORE_LOCK
 * explicitly, as described above.
 *
 * @sa
 *  CORE_SetLOCK, CONNECT_Init
 */



/******************************************************************************
 *  API Initialization, Shutdown/Cleanup, and Utility
 */

/** Initialize all internal/system data & resources to be used by the SOCK API.
 * @note
 *  You can safely call it more than once; just, all calls after the first
 *  one will have no result.
 * @note
 *  Usually, SOCK API does not require an explicit initialization -- as it is
 *  guaranteed to initialize itself automagically, in one of API functions,
 *  when necessary.  Yet, see the "Multi Thread safety" remark above.
 * @note
 *  This call, when used for the very first time in the application, enqueues
 *  SOCK_ShutdownAPI() to be called upon application exit on plaftorms that
 *  provide this functionality. In any case, the application can opt for
 *  explicit SOCK_ShutdownAPI() call when it is done with all sockets.
 * @sa
 *  SOCK_ShutdownAPI
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_InitializeAPI(void);


/** Cleanup; destroy all internal/system data & resources used by the SOCK API.
 * @attention  No function from the SOCK API should be called after this call!
 * @note
 *  You can safely call it more than once;  just, all calls after the first
 *  one will have no result.
 * @sa
 *  SOCK_InitializeAPI
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_ShutdownAPI(void);


/** By default (on UNIX platforms) the SOCK API functions automagically call
 * "signal(SIGPIPE, SIG_IGN)" on initialization.  To prohibit this feature,
 * you must call SOCK_AllowSigPipeAPI() before you call any other.
 * function from the SOCK API.
 */
extern NCBI_XCONNECT_EXPORT void SOCK_AllowSigPipeAPI(void);


/** Get size of OS-dependent native socket handle.
 * @return
 *  OS-dependent handle size or 0 in case of an error
 * @sa
 *  SOCK_GetOSHandle
 */
extern NCBI_XCONNECT_EXPORT size_t SOCK_OSHandleSize(void);


/** This is a helper call that can improve I/O behavior.
 * @param timeslice
 *  [in]  Break down long waits on I/O into smaller intervals of at most
 *  "timeslice" duration each.  This can help recover "hanging" sockets from
 *  indefinite wait and allow them to report an exceptional I/O condition.
 * @return
 *  Previous value of the timeslice
 * @sa
 *  SOCK_Wait, SOCK_Poll
 */
extern NCBI_XCONNECT_EXPORT const STimeout*SOCK_SetSelectInternalRestartTimeout
(const STimeout* timeslice
 );


/** Selector of I/O wait system API:  auto, poll(), or select().
 * @sa
 *  SOCK_SetIOWaitSysAPI
 */
typedef enum {
    eSOCK_IOWaitSysAPIAuto,   /** default; use some euristics to choose API */
    eSOCK_IOWaitSysAPIPoll,   /** always use poll()                         */
    eSOCK_IOWaitSysAPISelect  /** always use select()                       */
} ESOCK_IOWaitSysAPI;

/** This is a helper call that can improve I/O behavior (ignored for Windows).
 * @param api
 *  [in]  Default behavior is to wait on I/O such a way that accomodates the
 *  requested sockets accordingly.  There is a known limitation of select()
 *  API that requires all sockets to have low-level IO descriptors less than
 *  1024, but works faster than poll() API that does not have limits on the
 *  numeric values of the descriptors.  Either API can be enforced here.
 * @return
 *  Previous value of the API selector
 * @sa
 *  SOCK_Wait, SOCK_Poll
 */
extern NCBI_XCONNECT_EXPORT ESOCK_IOWaitSysAPI SOCK_SetIOWaitSysAPI
(ESOCK_IOWaitSysAPI api
 );



/******************************************************************************
 *  EVENT TRIGGER
 */

/** Create an event trigger.
 * @param trigger
 *  [in|out]  a pointer to a location where to store handle of the new trigger
 * @return
 *  eIO_Success on success; other status on error
 * @sa
 *  TRIGGER_Close, TRIGGER_Set
 */
extern NCBI_XCONNECT_EXPORT EIO_Status TRIGGER_Create
(TRIGGER* trigger,
 ESwitch  log
 );


/** Close an event trigger.
 * @param trigger
 *  [in]  a handle returned by TRIGGER_Create()
 * @return
 *   eIO_Success on success; other status on error
 * @sa
 *  TRIGGER_Create
 */
extern NCBI_XCONNECT_EXPORT EIO_Status TRIGGER_Close
(TRIGGER trigger
 );


/** Set an event trigger.  Can be used from many threads concurrently.
 * @param trigger
 *  [in]  a handle returned by TRIGGER_Create()
 * @return
 *   eIO_Success on success; other status on error
 * @sa
 *  TRIGGER_Create, TRIGGER_IsSet
 */
extern NCBI_XCONNECT_EXPORT EIO_Status TRIGGER_Set
(TRIGGER trigger
 );


/** Check whether the trigger has been set.  Should not be used from
 * multiple threads concurrently at a time.
 * @param trigger
 *  [in]  a handle returned by TRIGGER_Create()
 * @return
 *  eIO_Success if the trigger has been set;
 *  eIO_Closed  if the trigger has not yet been set;
 *  other status on error
 * @sa
 *  TRIGGER_Create, TRIGGER_Set, TRIGGER_Reset
 */
extern NCBI_XCONNECT_EXPORT EIO_Status TRIGGER_IsSet
(TRIGGER trigger
 );


/** Reset trigger.  Should not be used from multiple threads concurently.
 * @param trigger
 *  [in]  a handle returned by TRIGGER_Create()
 * @return
 *  eIO_Success if the trigger has been set; other status on error
 * @sa
 *  TRIGGER_Create, TRIGGER_Set
 */
extern NCBI_XCONNECT_EXPORT EIO_Status TRIGGER_Reset
(TRIGGER trigger
 );



/******************************************************************************
 *  SOCKET FLAGS
 */

typedef enum {
    fSOCK_LogOff       = eOff, /**< NB: logging is inherited in accepted SOCK*/
    fSOCK_LogOn        = eOn,
    fSOCK_LogDefault   = eDefault,
    fSOCK_KeepAlive    = 8,    /**< keep socket alive (if supported by OS)   */
    fSOCK_BindAny      = 0,    /**< bind to 0.0.0.0 (i.e. any), default      */
    fSOCK_BindLocal    = 0x10, /**< bind to 127.0.0.1 only                   */
    fSOCK_KeepOnExec   = 0x20, /**< can be applied to all sockets            */
    fSOCK_CloseOnExec  = 0,    /**< can be applied to all sockets, default   */
    fSOCK_Secure       = 0x40, /**< subsumes CloseOnExec regardless of Keep  */
    fSOCK_KeepOnClose  = 0x80, /**< retain OS handle in SOCK_Close[Ex]()     */
    fSOCK_CloseOnClose = 0,    /**< close  OS handle in SOCK_Close[Ex]()     */
    fSOCK_ReadOnWrite       = 0x100,
    fSOCK_InterruptOnSignal = 0x200
} ESOCK_Flags;
typedef unsigned int TSOCK_Flags;  /**< bitwise "OR" of ESOCK_Flags */


/******************************************************************************
 *  LISTENING SOCKET [SERVER-side]
 */

/** [SERVER-side]  Create and initialize the server-side(listening) socket
 * (socket() + bind() + listen())
 * @param port
 *  [in]  the port to listen at (0 to select first available)
 * @param backlog
 *  [in]  maximal # of pending connections
 *  @note  On some systems, "backlog" may be silently limited down to 128
           (or even 5), or completely ignored whatsoever.
 * @param lsock
 *  [out] handle of the created listening socket
 * @param flags
 *  [in]  special modifiers
 * @sa
 *  LSOCK_Create, LSOCK_Close, LSOCK_GetPort
 */
extern NCBI_XCONNECT_EXPORT EIO_Status LSOCK_CreateEx
(unsigned short port,
 unsigned short backlog,
 LSOCK*         lsock,
 TSOCK_Flags    flags
 );


/** [SERVER-side]  Create and initialize the server-side(listening) socket
 * Same as LSOCK_CreateEx() called with the last argument provided as
 * fSOCK_LogDefault.
 * @param port
 *  [in]  the port to listen at
 * @param backlog
 *  [in]  maximal # of pending connections
 *  @note  On some systems, "backlog" can be silently limited down to 128
 *         (or even 5), or completely ignored whatsoever.
 * @param lsock
 *  [out] handle of the created listening socket
 * @sa
 *  LSOCK_CreateEx, LSOCK_Close
 */
extern NCBI_XCONNECT_EXPORT EIO_Status LSOCK_Create
(unsigned short port,
 unsigned short backlog,
 LSOCK*         lsock
 );


/** [SERVER-side]  Accept connection from a client.
 * @param lsock
 *  [in]  handle of a listening socket
 * @param timeout
 *  [in]  timeout (infinite if NULL)
 * @param sock
 *  [out] handle of the accepted socket
 * @param flags
 *  [in]  properties for the accepted socket to have
 * @note
 *  The provided "timeout" is for this Accept() only.  To set I/O timeout on
 *  the resulted socket use SOCK_SetTimeout();
 *  all I/O timeouts are infinite by default.
 * @sa
 *  SOCK_Create, SOCK_Close, TSOCK_Flags
 */
extern NCBI_XCONNECT_EXPORT EIO_Status LSOCK_AcceptEx
(LSOCK           lsock,
 const STimeout* timeout,
 SOCK*           sock,
 TSOCK_Flags     flags
 );


/** [SERVER-side]  Accept connection from a client.
 * Same as LSOCK_AcceptEx(.,.,.,fSOCK_LogDefault)
 * @sa
 *  LSOCK_AcceptEx
 */
extern NCBI_XCONNECT_EXPORT EIO_Status LSOCK_Accept
(LSOCK           lsock,
 const STimeout* timeout,
 SOCK*           sock
 );


/** [SERVER-side]  Close the listening socket, destroy relevant internal data.
 * @param lsock
 *  [in]  listening socket handle to close
 * The call invalidates the handle, so its further is not allowed.
 * @sa
 *  LSOCK_Create
 */
extern NCBI_XCONNECT_EXPORT EIO_Status LSOCK_Close(LSOCK lsock);


/** Get an OS-dependent native socket handle to use by platform-specific API.
 * FYI: on MS-Windows it will be "SOCKET", on other platforms -- "int".
 * @param lsock
 *  [in]  socket handle
 * @param handle_buf
 *  [in]  pointer to a memory location to store the OS-dependent handle at
 * @param handle_size
 *  The exact(!) size of the expected OS handle
 * @param ownership
 *  eTakeOwnership removes the handle from LSOCK;  eNoOwnership retains it
 * @note
 *  If handle ownership is taken, all operations with this LSOCK (except for
 *  LSOCK_Close()) will fail.
 * @sa
 *  SOCK_OSHandleSize, SOCK_GetOSHandle, SOCK_CloseOSHandle, LSOCK_GetOSHandle,
 *  LSOCK_Close
 */
extern NCBI_XCONNECT_EXPORT EIO_Status LSOCK_GetOSHandleEx
(LSOCK      lsock,
 void*      handle_buf,
 size_t     handle_size,
 EOwnership owndership
 );

/** Same as LSOCK_GetOSHandleEx(lsock, handle_buf, handle_size, eNoOwnership).
 * @sa
 *  LSOCK_GetOSHandleEx
 */
extern NCBI_XCONNECT_EXPORT EIO_Status LSOCK_GetOSHandle
(LSOCK  lsock,
 void*  handle_buf,
 size_t handle_size
 );


/** Get socket port number, which it listens on.
 * The returned port is either one specified when the socket was created, or
 * an automatically assigned number if LSOCK_Create() provided the port as 0.
 * @param lsock
 *  [in]  socket handle
 * @param byte_order
 *  [in]  byte order for port on return
 * @return
 *  Listening port number in requested byte order, or 0 in case of an error.
 * @sa
 *  LSOCK_Create
 */
extern NCBI_XCONNECT_EXPORT unsigned short LSOCK_GetPort
(LSOCK         lsock,
 ENH_ByteOrder byte_order
 );



/******************************************************************************
 *  SOCKET (connection-oriented)
 */

/** [CLIENT-side]  Connect client to another(server-side, listening) socket
 * (socket() + connect() [+ select()])
 * @note
 *  SOCK_Close[Ex]() will not close the underlying OS handle if
 *  fSOCK_KeepOnClose is set in "flags".
 * @param host
 *  [in]  host to connect to
 * @param port
 *  [in]  port to connect to
 * @param timeout
 *  [in]  the connect timeout (infinite if NULL)
 * @param sock
 *  [out] handle of the created socket
 * @param init_data
 *  [in]  initial output data segment (may be NULL)
 * @param init_size
 *  [in]  size of initial data segment (may be 0)
 * @param flags
 *  [in]  additional socket requirements
 * @sa
 *  SOCK_Create, SOCK_Reconnect, SOCK_Close
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_CreateEx
(const char*     host,
 unsigned short  port,
 const STimeout* timeout,
 SOCK*           sock,
 const void*     init_data,
 size_t          init_size,
 TSOCK_Flags     flags
 );


/** [CLIENT-side]  Connect client to another(server-side, listening) socket
 * (socket() + connect() [+ select()])
 * Equivalent to
 * SOCK_CreateEx(host, port, timeout, sock, 0, 0, fSOCK_LogDefault).
 *
 * @param host
 *  [in]  host to connect to
 * @param port
 *  [in]  port to connect to
 * @param timeout
 *  [in]  the connect timeout (infinite if NULL)
 * @param sock
 *  [out] handle of the created socket
 * @sa
 *  SOCK_CreateEx, SOCK_Reconnect, SOCK_Close
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_Create
(const char*     host,
 unsigned short  port,
 const STimeout* timeout,
 SOCK*           sock
 );


/** [SERVER-side]  Create a socket on top of either an OS-dependent "handle"
 * (file descriptor on Unix, SOCKET on MS-Windows) or an existing SOCK object.
 * Returned socket is not reopenable to its default peer (SOCK_Reconnect() may
 * not specify zeros for the connection point).
 * All timeouts are set to default [infinite] values.
 * The call does *not* destroy either OS handle or SOCK passed in the
 * arguments, regardless of the return status code.
 * When a socket gets created on top of a "SOCK" handle, the original SOCK gets
 * always emptied (the underlying OS handle removed from it) upon the call
 * returns:  either the handle gets migrated to the new socket just created,
 * or it gets closed unconditionally of the fSOCK_KeepOnClose flag in the
 * original socket.  In either case, the original SOCK will still need
 * SOCK_Close() in the caller's code to free up the memory it occupies.
 * Any secure session that may have existed in the original SOCK will have
 * been terminated (and new session may have been initiated in the new SOCK --
 * at this time the old session is not allowed to "migrate").
 * @note
 *  SOCK_Close[Ex]() on the resultant socket will not close the OS handle
 *  if fSOCK_KeepOnClose is set in "flags".
 * @param handle
 *  [in]  OS-dependent "handle" or SOCK to be converted
 * @param handle_size
 *  [in]  "handle" size (0 if a SOCK passed in "handle")
 * @param sock
 *  [out] SOCK built on top of the "handle"
 * @param init_data
 *  [in]  initial output data segment (may be NULL)
 * @param init_size
 *  [in]  size of the initial data segment (may be 0)
 * @param flags
 *  [in]  additional socket requirements
 * @return
 *  Return eIO_Success on success;  otherwise: eIO_Closed if the "handle"
 *  does not refer to an open socket [but e.g. to a normal file or a pipe];
 *  other error codes in case of other errors.
 * @sa
 *  SOCK_GetOSHandleEx, SOCK_CreateOnTop, SOCK_Reconnect, SOCK_Close
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_CreateOnTopEx
(const void* handle,
 size_t      handle_size,
 SOCK*       sock,
 const void* init_data,
 size_t      init_size,
 TSOCK_Flags flags
 );


/** [SERVER-side]  Create a socket on top of a "handle".
 * Equivalent to SOCK_CreateOnTopEx(handle, handle_size, sock,
 *                                  0, 0, fSOCK_LogDefault|fSOCK_CloseOnClose).
 * @param handle
 *  [in]  OS-dependent "handle" or "SOCK" to be converted
 * @param handle_size
 *  [in]  "handle" size (0 if a "SOCK" passed in "handle")
 * @param sock
 *  [out] SOCK built on top of the OS "handle"
 * @sa
 *  SOCK_GetOSHandleEx, SOCK_CreateOnTopEx, SOCK_Close
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_CreateOnTop
(const void* handle,
 size_t      handle_size,
 SOCK*       sock
 );


/** [CLIENT-side]  Close the socket referred to by "sock" and then connect
 * it to another "host:port";  fail if it takes more than "timeout"
 * (close() + connect() [+ select()])
 *
 * HINT:  if "host" is NULL then connect to the same host address as before;
 *        if "port" is zero then connect to the same port # as before.
 *
 * @note  The "new" socket inherits old I/O timeouts;
 * @note  The call is only applicable to stream [not datagram] sockets.
 * @note  "timeout"==NULL is infinite (also as kInfiniteTimeout);
 *        "timeout"=={0,0} causes no wait for connection to be established,
 *        and to return immediately.
 * @note  UNIX sockets can only be reconnected to the same file,
 *        thus both host and port have to be passed as 0s.
 * @param sock
 *  [in]  handle of the socket to reconnect
 * @param host
 *  [in]  host to connect to  (can be NULL)
 * @param port
 *  [in]  port to connect to  (can be 0)
 * @param timeout
 *  [in]  the connect timeout (infinite if NULL)
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_Reconnect
(SOCK            sock,
 const char*     host,
 unsigned short  port,
 const STimeout* timeout
 );


/** Shutdown the connection in only one direction (specified by "direction").
 * Later attempts to I/O (or to wait) in the shutdown direction will
 * do nothing, and immediately return with "eIO_Closed" status.
 * Pending data output can cause data transfer to the remote end (subject
 * for eIO_Close timeout as previously set by SOCK_SetTimeout()).
 * Cannot be applied to datagram sockets (eIO_InvalidArg results).
 * @param sock
 *  [in]  handle of the socket to shutdown
 * @param how
 *  [in]  one of:  eIO_Read, eIO_Write, eIO_ReadWrite
 * @sa
 *  SOCK_SetTimeout
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_Shutdown
(SOCK      sock,
 EIO_Event how
 );


/** Close the SOCK handle, destroy relevant internal data.
 * The "sock" handle goes invalid after this function call, regardless of
 * whether the call was successful or not.  If eIO_Close timeout was specified
 * (or NULL) then it blocks until either all unsent data are sent, an error
 * flagged, or the timeout expires;  if there is any output pending, that
 * output will be flushed.
 * Connection may remain in the system if the socket was created with the
 * fSOCK_KeepOnClose flag set;  otherwise, it gets closed.
 * @note
 *  On MS-Win closing a socket whose OS handle has been used elsewhere (e.g.
 *  in SOCK_CreateOnTop()) may render the OS handle unresponsive, so always
 *  make sure to close the current socket first (assuming fSOCK_KeepOnClose),
 *  and only then use the extracted handle to build another socket.
 * @param sock
 *  [in]  socket handle to close(if not yet closed) and destroy(always)
 * @sa
 *  SOCK_Create, SOCK_CreateOnTop, DSOCK_Create, SOCK_SetTimeout, SOCK_CloseEx
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_Close(SOCK sock);
#define SOCK_Destroy(s)  SOCK_Close(s)


/** Close the SOCK handle, and conditionally destroy relevant internal data.
 * If eIO_Close timeout was specified (or NULL) then it blocks until either all
 * unsent data are sent, an error flagged, or the timeout expires;  if there is
 * any output pending, that output will be flushed.
 * Connection may remain in the system if the socket was created with the
 * fSOCK_KeepOnClose flag set;  otherwise, it gets closed.
 * @note
 *  On MS-Win closing a socket whose OS handle has been used elsewhere (e.g.
 *  in SOCK_CreateOnTop()) may render the OS handle unresponsive, so always
 *  make sure to close the current socket first (assuming fSOCK_KeepOnClose),
 *  and only then use the extracted handle to build another socket.
 * @param sock
 *  [in]  handle of the socket to close
 * @param destroy
 *  [in]  =1 to destroy the SOCK handle; =0 to keep the handle
 * @note
 *  A kept SOCK handle can be freed/destroyed by the SOCK_Close() call.
 * @note
 *  SOCK_CloseEx(sock, 1) is equivalent to SOCK_Close(sock).
 * @sa
 *  SOCK_Close, SOCK_Create, SOCK_CreateOnTop, DSOCK_Create, SOCK_SetTimeout
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_CloseEx
(SOCK         sock,
 int/**bool*/ destroy
 );


/** Close socket OS handle (ungracefully aborting the connection if necessary).
 * The call retries repeatedly if interrupted by a singal (so no eIO_Interrupt
 * should be expected).  Return eIO_Success when the handle has been closed
 * successfully, eIO_Closed if the handle has been passed already closed,
 * eIO_InvalidArg if passed arguments are not valid, eIO_Unknow if the
 * handle cannot be closed (per an error returned by the system).
 * @note  Using this call on a handle that belongs to an active [LD]SOCK object
 *        is undefined.
 * @sa
 *  SOCK_GetOSHandleEx
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_CloseOSHandle
(const void* handle,
 size_t      handle_size
);


/** Block on the socket until either the specified "event" is available or
 * "timeout" expires (if "timeout" is NULL then assume it infinite).
 * eIO_Open (as "event") can be used to check whether the socket has been
 * connected.  When eIO_Read is requested as an "event" for a datagram socket,
 * then eIO_Closed results if the internally latched message has been entirely
 * read out.  Either of eIO_Open, eIO_Write and eIO_ReadWrite always succeed
 * immediately for the datagram socket.
 * @param sock
 *  [in]  socket handle
 * @param event
 *  [in]  one of:  eIO_Open, eIO_Read, eIO_Write, eIO_ReadWrite
 * @param timeout
 *  [in]  maximal time to wait for the event to occur
 * @return
 *  eIO_Closed     -- if the socket has been closed (in the specified
 *                    direction when a read/write "event" requested);
 *  eIO_Success    -- if the socket is ready;
 *  eIO_Unknown    -- if partially closed with eIO_Open requested,
 *                    or an I/O error occurred;
 *  eIO_Timeout    -- if socket is not ready for the "event" and the allotted
 *                    timeout has expired (for eIO_Open means the socket is
 *                    still connecting);
 *  eIO_Interrupt  -- if the call had been interrupted by a signal before
 *                    any other verifiable status was available;
 *  eIO_InvalidArg -- if the "event" is not one of those mentioned above.
 * @note  It is allowed to use a non-NULL zeroed STimeout to poll
 *        on the socket for the immediately available event and
 *        return it (or eIO_Timeout, otherwise) without blocking.
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_Wait
(SOCK            sock,
 EIO_Event       event,
 const STimeout* timeout
 );


/** I/O polling structure.
 * @sa SOCK_Poll()
 */
typedef struct {
    SOCK      sock;   /** [in]          SOCK to poll (NULL if not to poll)  */
    EIO_Event event;  /** [in]  one of: eIO_Open/Read/Write/ReadWrite       */
    EIO_Event revent; /** [out] one of: eIO_Open/Read/Write/ReadWrite/Close */
} SSOCK_Poll;


/** Block until at least one of the sockets enlisted in "polls" array
 * (of size "n") becomes available for requested operation (SSOCK_Poll::event),
 * or until timeout expires (wait indefinitely if timeout is passed as NULL).
 *
 * @note To lower overhead, use SOCK_Wait() to wait for I/O on a single socket.
 *
 * Return eIO_Success if at least one socket was found ready;  eIO_Timeout
 * if timeout expired;  eIO_Unknown if underlying system call(s) failed.
 *
 * @note  NULL sockets (without any verification for the contents of
 *        the "event" field) as well as non-NULL sockets with eIO_Open
 *        requested in their "event" do not get polled (yet the corresponding
 *        "revent" gets updated to indicate eIO_Open, for no I/O event ready);
 * @note  For a socket found not ready for an operation, eIO_Open gets returned
 *        in its "revent";  for a failing / closed socket -- eIO_Close;
 * @note  This call may return eIO_InvalidArg if:
 *        - parameters to the call are incomplete / inconsistent;
 *        - a non-NULL socket polled with a bad "event" (e.g. eIO_Close).
 *        With this return code, the caller cannot rely on "revent" fields in
 *        the "polls" array as they might not have been updated properly.
 * @note  If either both "n" and "polls" are NULL, or all sockets in the
 *        "polls" array are either NULL or without any events requested
 *        (eIO_Open), then the returned status is either:
 *        - eIO_Timeout (after the specified amount of time was spent idle), or
 *        - eIO_Interrupt (if a signal came while the waiting was in progress).
 * @note  For datagram sockets, the readiness for reading is determined by the
 *        message data latched since the last message receive call,
 *        DSOCK_RecvMsg().
 * @note  This call allows the intermixture of stream, datagram, and listening
 *        sockets (cast to SOCK), as well as triggers (also cast to SOCK), but
 *        for the sake of readability, it is recommended to use POLLABLE_Poll()
 *        in such circumstances.
 * @note  This call may cause some socket I/O in those sockets marked for
 *        read-on-write and those with pending connection or output data.
 * @param n
 *  [in]  # of SSOCK_Poll elems in "polls"
 * @param polls[]
 *  [in|out] array of query/result structures
 * @param timeout
 *  [in]  max time to wait (infinite if NULL)
 * @param n_ready
 *  [out] # of ready sockets  (may be NULL)
 * @sa
 *  POLLABLE_Poll
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_Poll
(size_t          n,
 SSOCK_Poll      polls[],
 const STimeout* timeout,
 size_t*         n_ready
 );


/** Specify timeout for the connection I/O (see SOCK_[Read|Write|Close]()).
 * If "timeout" is NULL then set the timeout to be infinite;
 * @note  The default timeout is infinite (to wait indefinitely).
 * @param sock
 *  [in]  socket handle
 * @param event
 *  [in]  one of:  eIO_[Read/Write/ReadWrite/Close]
 * @param timeout
 *  [in]  new timeout value to set
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_SetTimeout
(SOCK            sock,
 EIO_Event       event,
 const STimeout* timeout
 );


/** Get the connection's i/o timeout (or NULL, if the timeout is infinite).
 * @note  The returned timeout is guaranteed to be pointing to
 *        a valid structure in memory at least until the SOCK is closed
 *        or SOCK_SetTimeout() is called for this "sock".
 * @note  eIO_ReadWrite timeout is the least of eIO_Read and eIO_Write ones.
 * @param sock
 *  [in]  socket handle
 * @param event
 *  [in]  one of:  eIO_[Read/Write/Close]
 */
extern NCBI_XCONNECT_EXPORT const STimeout* SOCK_GetTimeout
(SOCK      sock,
 EIO_Event event
 );


/** Read/peek up to "size" bytes from "sock" to a buffer pointed to by "buf".
 * In "*n_read", return the number of successfully read bytes.
 * Read method "how" can be either of the following:
 * eIO_ReadPlain   -- read as many as "size" bytes and return (eIO_Success);
 *                    if no data are readily available then wait at most
 *                    read timeout and return (eIO_Timeout) if no data still
 *                    could be got; eIO_Success if some data were obtained.
 * eIO_ReadPeek    -- same as "eIO_ReadPlain" but do not extract the data from
 *                    the socket (so that the next read operation will see the
 *                    data again), with one important exception noted below.
 * eIO_ReadPersist -- read exactly "size" bytes and return eIO_Success; if less
 *                    data received then return an error condition (including
 *                    eIO_Timeout).
 *
 * If there is no data available to read (also, if eIO_ReadPersist and cannot
 * read exactly "size" bytes) and the timeout(see SOCK_SetTimeout()) is expired
 * then return eIO_Timeout.
 *
 * Both eIO_ReadPlain and eIO_ReadPeek return eIO_Success iff some data have
 * been read (perhaps within the time allowance specified by eIO_Read timeout).
 * Both mothods return any other code when no data at all were available.
 * eIO_ReadPersist differs from the other two methods as it can return an
 * error condition even if some data were actually obtained from the socket.
 * Hence, as the *rule of thumb*, an application should always check the number
 * of read bytes BEFORE checking the return status, which merely advises
 * whether it is okay to read again.
 *
 * As a special case, "buf" may passed as NULL:
 *   eIO_ReadPeek      -- read up to "size" bytes and store them
 *                        in internal buffer;
 *   eIO_Read[Persist] -- discard up to "size" bytes from internal buffer
 *                        and socket (check "*n_read" to know how many).
 *
 * @note  "Read" and "peek" methods differ:  if "read" is
 *        performed and not enough but only some data available immediately
 *        from the internal buffer, then the call still completes with
 *        eIO_Success status.  For "peek", if not all requested data were
 *        available, the real I/O occurs to pick up additional data (if any)
 *        from the system.  Keep this difference in mind when programming
 *        loops that heavily use "peek"s without "read"s.
 * @note  If on input "size" == 0, then "*n_read" is set to 0,
 *        and the return value can be either of eIO_Success, eIO_Closed or
 *        eIO_Unknown depending on connection status of the socket.
 * @param sock
 *  [in]  socket handle
 * @param buf
 *  [out] data buffer to read to
 * @param size
 *  [in]  max # of bytes to read to "buf"
 * @param n_read
 *  [out] # of bytes read  (can be NULL)
 * @param how
 *  [in]  how to read the data
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_Read
(SOCK           sock,
 void*          buf,
 size_t         size,
 size_t*        n_read,
 EIO_ReadMethod how
 );


/**
 * Read a line from SOCK.  A line is terminated by either '\n' (with
 * optional preceding '\r') or '\0'.  Returned result is always '\0'-
 * terminated and having '\r'(if any)'\n' stripped. *n_read (if 'n_read'
 * passed non-NULL) contains the numbed of characters written into
 * 'buf' (not counting the terminating '\0').  If 'buf', whose size is
 * specified via 'size' parameter, is not big enough to contain the
 * line, all 'size' bytes will be filled, with *n_read == size upon
 * return.  Note that there will be no terminating '\0' in this
 * (and the only) case, which the caller can easily distinguish.
 * @param sock
 *  [in]  socket handle
 * @param buf
 *  [out] data buffer to read to
 * @param size
 *  [in]  max # of bytes to read to "buf"
 * @param n_read
 *  [out] # of bytes read  (can be NULL)
 * @return
 *  Return code eIO_Success upon successful completion, other - upon
 *  an error.  Note that *n_read must be analyzed prior to return code,
 *  because the buffer could have received some contents before
 *  the indicated error occurred (especially when connection closed).
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_ReadLine
(SOCK    sock,
 char*   buf,
 size_t  size,
 size_t* n_read
 );


/** Push the specified data back to the socket input queue (in the socket's
 * internal read buffer). These can be any data, not necessarily the data
 * previously read from the socket.
 * @param sock
 *  [in]  socket handle
 * @param buf
 *  [in]  data to push back to the socket's local buffer
 * @param size
 *  [in]  # of bytes (starting at "buf") to push back
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_PushBack
(SOCK        sock,
 const void* buf,
 size_t      size
 );


/** Return low-level socket I/O status of *last* socket operation.
 * This call does not perform any I/O or socket-related system calls.
 * @param sock
 *  [in]  socket handle
 * @param direction
 *  [in]  one of:  eIO_Open, eIO_Read, eIO_Write
 * @return
 *   - eIO_Closed     - if either the connection has been closed / shut down
 *                      (in corresponding direction for eIO_Read or eIO_Write),
 *                      or the socket does not exist (for eIO_Open);
 *   - eIO_Timeout    - if connection request has been submitted but not
 *                      completed (i.e. it was still pending during last I/O);
 *   - eIO_Interrupt  - if last data I/O was interrupted by a signal
 *                      (applicable only to eIO_Read or eIO_Write);
 *   - eIO_Unknown    - if an error has been detected during last data I/O
 *                      (applicable only to eIO_Read or eIO_Write);
 *   - eIO_InvalidArg - if "direction" is not one of the allowed above;
 *   - eIO_Success    - otherwise (also covers eIO_Timeout in last data I/O).
 *
 * @note  eIO_Open merely checks whether the socket still exists (i.e. open as
 *        a system object), and that SOCK_CloseEx() has not been called on it.
 *
 * @note  SOCK_Read(eIO_ReadPeek) and SOCK_Wait(eIO_Read) will not
 *        return any error as long as there is unread buffered
 *        data left.  Thus, when you are "peeking" data (instead of
 *        reading it out), then the only "non-destructive" way to
 *        check whether an EOF or an error has actually occurred,
 *        it is to use this call.
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_Status
(SOCK      sock,
 EIO_Event direction
 );


/** Write "size" bytes from buffer "buf" to "sock".
 * @param sock
 *  [in]  socket handle
 * @param buf
 *  [in]  data to write to the socket
 * @param size
 *  [in]  # of bytes (starting at "buf") to write
 * @param n_written
 *  [out] # of written bytes (can be NULL)
 * @param how
 *  [in]  eIO_WritePlain | eIO_WritePersist
 * @return
 *  In "*n_written", return the number of bytes actually written.
 *  eIO_WritePlain   --  write as many bytes as possible at once and return
 *                      immediately; if no bytes can be written then wait
 *                      at most WRITE timeout, try again and return.
 *  eIO_WritePersist --  write all data (doing an internal retry loop
 *                      if necessary); if any single write attempt times out
 *                      or fails then stop writing and return (error code).
 *  Return status: eIO_Success -- some bytes were written successfully  [Plain]
 *                            -- all bytes were written successfully [Persist]
 *                other code denotes an error, but some bytes might have
 *                been sent nevertheless (always check *n_written to know).
 *
 * @note  With eIO_WritePlain the call returns eIO_Success if and only if
 *        some data were actually written to the socket.  If no data could
 *        be written (and perhaps timeout expired) this call always returns
 *        an error.
 * @note  eIO_WritePlain and eIO_WritePersist differ that
 *        the latter can flag an error condition even if some data were
 *        actually written
 *        (see "the rule of thumb" in the comments for SOCK_Read() above).
 * @note  If "size"==0, return value can be eIO_Success if no
 *        pending data left in the socket, or eIO_Timeout if there are still
 *        data pending.  In either case, "*n_written" is set to 0 on return.
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_Write
(SOCK            sock,
 const void*     buf,
 size_t          size,
 size_t*         n_written,
 EIO_WriteMethod how
 );


/** If there is outstanding connection or output data pending, cancel it.
 * Mark the socket as if it has been shut down for both reading and writing.
 * Break actual connection if any was established.
 * Do not attempt to send anything upon SOCK_Close().
 * This call is available for stream sockets only.
 * @note  Even though the underlying OS socket handle may have been marked for
 *        preservation via fSOCK_KeepOnClose, this call always and
 *        unconditially closes and destroys the actual OS handle.
 * @param sock
 *  [in] socket handle
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_Abort
(SOCK sock
 );


/** Get local port of the socket (true or cached / stored).
 * For most users, a simpler SOCK_GetLocalPort() call is going to be the
 * most suitable.  This call allows to inquire the network level about
 * a temporary port number assigned when a socket was created as a result
 * of accepting the connection (otherwise, the listening socket port number
 * gets returned as the local port).  For connecting sockets, both "trueport"
 * and no "trueport" results are identical (with the exception that "trueport"
 * causes an additional system call, and the result is not stored).
 * @param sock
 *  [in]  socket handle
 * @param trueport
 *  [in]  non-zero causes to refetch / no-cache port from the network layer
 * @param byte_order
 *  [in]  byte order for port on return
 * @return
 *  The port number in requested byte order, or 0 in case of an error.
 * @sa
 *  SOCK_GetLocalPort
 */
extern NCBI_XCONNECT_EXPORT unsigned short SOCK_GetLocalPortEx
(SOCK          sock,
 int/*bool*/   trueport,
 ENH_ByteOrder byte_order
 );


/** Get local port of the socket.
 * The returned port number is also cached within "sock" so any further
 * inquires for the local port do not cause any system calls to occur.
 * The call is exactly equavalent to SOCK_GetLocalPortEx(sock, 0, byte_order).
 * @param sock
 *  [in]  socket handle
 * @param byte_order
 *  [in]  byte order for port on return
 * @return
 *  Local port number in requested byte order, or 0 in case of an error.
 * @sa
 *  SOCK_GetLocalPortEx
 */
extern NCBI_XCONNECT_EXPORT unsigned short SOCK_GetLocalPort
(SOCK          sock,
 ENH_ByteOrder byte_order
 );


/** Get host and port of the socket's peer (remote end).
 * @param sock
 *  [in]  socket handle
 * @param host
 *  [out] the peer's host (can be NULL, then not filled in)
 * @param port
 *  [out] the peer's port (can be NULL, then not filled in)
 * @param byte_order
 *  [in]  byte order for either host or port, or both, on return
 * @return
 *  Host/port addresses in requested byte order, or 0 in case of an error.
 * @sa
 *  SOCK_GetLocalPort
 */
extern NCBI_XCONNECT_EXPORT void SOCK_GetPeerAddress
(SOCK            sock,
 unsigned int*   host,
 unsigned short* port,
 ENH_ByteOrder   byte_order
 );


/** Get remote port of the socket (the port it is connected to).
 * The call is provided as a counterpart for SOCK_GetLocalPort(), and is
 * equivalent to calling SOCK_GetPeerAddress(sock, 0, &port, byte_order).
 * @param sock
 *  [in]  socket handle
 * @param byte_order
 *  [in]  byte order for port on return
 * @return
 *  Remote port number in requested byte order, or 0 in case of an error.
 * @sa
 *  SOCK_GetPeerAddress, SOCK_GetLocalPort
 */
extern NCBI_XCONNECT_EXPORT unsigned short SOCK_GetRemotePort
(SOCK          sock,
 ENH_ByteOrder byte_order
 );


/** Get textual representation of the socket's peer.
 * For INET domain sockets, the result is of the form "aaa.bbb.ccc.ddd:ppppp";
 * for UNIX domain socket, the result is the name of the socket's file.
 * @param sock
 *  [in]  socket handle
 * @param buf
 *  [out] pointer to provided buffer to store the text to
 * @param bufsize
 *  [in]  usable size of the buffer above
 * @param format
 *  [in]  what parts of address to include
 * @return
 *  On success, return its "buf" argument; return 0 on error.
 */
typedef enum {
    eSAF_Full = 0,  /** address in full, native form                      */
    eSAF_Port,      /** only numeric port if INET socket, empty otherwise */
    eSAF_IP         /** only numeric IP if INET socket,   empty otherwise */
} ESOCK_AddressFormat;

extern NCBI_XCONNECT_EXPORT char* SOCK_GetPeerAddressStringEx
(SOCK                sock,
 char*               buf,
 size_t              bufsize,
 ESOCK_AddressFormat format
 );


/** Equivalent to SOCK_GetPeerAddressStringEx(.,.,.,eSAF_Full) */
extern NCBI_XCONNECT_EXPORT char* SOCK_GetPeerAddressString
(SOCK   sock,
 char*  buf,
 size_t bufsize
 );


/** Get an OS-dependent native socket handle to use by platform-specific API.
 * FYI:  on MS-Windows it will be "SOCKET", on other platforms -- "int".
 * @param sock
 *  [in]  socket handle
 * @param handle_buf
 *  [out] pointer to a memory area to put the OS handle at
 * @param handle_size
 *  [in]  the exact(!) size of the expected OS handle
 * @param ownership
 *  eTakeOwnership removes the handle from SOCK;  eNoOwnership retains it
 * @note
 *  If handle ownership is taken, all operations with this SOCK (except for
 *  SOCK_Close[Ex]()) will fail.
 * @sa
 *  SOCK_OSHandleSize, SOCK_GetOSHandle, SOCK_CloseOSHandle, SOCK_CloseEx
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_GetOSHandleEx
(SOCK       sock,
 void*      handle_buf,
 size_t     handle_size,
 EOwnership ownership
 );


/** Same as SOCK_GetOSHandleEx(sock, handle_buf, handle_size, eNoOwnership).
 * @sa
 *  SOCK_GetOSHandleEx
 */
extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_GetOSHandle
(SOCK   sock,
 void*  handle_buf,
 size_t handle_size
 );


/** By default, sockets will not try to read data from inside SOCK_Write().
 * If you want to automagically upread the data (and cache it in the internal
 * socket buffer) when the write operation is not immediately available,
 * call this func with "on_off" == eOn.
 * Pass "on_off" as eDefault to get current setting.
 * @param on_off
 *
 * @return
 *  Prior setting
 */
extern NCBI_XCONNECT_EXPORT ESwitch SOCK_SetReadOnWriteAPI
(ESwitch on_off
 );


/** Control the reading-while-writing feature for socket "sock" individually.
 * To reset to the global default behavior (as set by
 * SOCK_SetReadOnWriteAPI()), call this function with "on_off" == eDefault.
 * @param sock
 *  [in]  socket handle
 * @param on_off
 *
 * @return
 *  Prior setting
 */
extern NCBI_XCONNECT_EXPORT ESwitch SOCK_SetReadOnWrite
(SOCK    sock,
 ESwitch on_off
 );


/** Control OS-defined send strategy by disabling/enabling TCP
 * layer to send incomplete network frames (packets).
 * With the "cork" set on, data gets always buffered until a complete
 * hardware packet is full (or connection is about to close), and only
 * then is sent out to the medium.
 * @note The setting cancels any effects of SOCK_DisableOSSendDelay().
 * @param sock
 *  [in]  socket handle [stream socket only]
 * @param on_off
 *  [in]  1 to set the cork; 0 to remove the cork
 * @sa
 *  SOCK_DisableOSSendDelay
 */
extern NCBI_XCONNECT_EXPORT void SOCK_SetCork
(SOCK         sock,
 int/**bool*/ on_off
 );


/** Control OS-defined send strategy by disabling/enabling TCP
 * Nagle algorithm that packs multiple requests into a single
 * packet and thus transferring data in fewer transactions,
 * miminizing the network traffic and bursting the throughput.
 * Some applications, however, may find it useful to disable this
 * default behavior for the sake of their performance increase
 * (like in case of short transactions otherwise held by the system
 * to be possibly coalesced into larger chunks).
 * @note The setting cancels any effects of SOCK_SetCork().
 * @param sock
 *  [in]  socket handle [stream socket only]
 * @param on_off
 *  [in]  1 to disable the send delay; 0 to enable the send delay
 * @sa
 *  SOCK_SetCork
 */
extern NCBI_XCONNECT_EXPORT void SOCK_DisableOSSendDelay
(SOCK         sock,
 int/**bool*/ on_off
 );



/******************************************************************************
 *  DATAGRAM SOCKETS (connectionless)
 *
 *  How the datagram exchange API works:
 *
 *  Datagram socket is created with special DSOCK_Create[Ex]() calls but the
 *  resulting object is a SOCK handle.  That is, almost all SOCK routines
 *  may be applied to the handle.  There are few exceptions, though.
 *  In datagram sockets I/O differs from how it is done in stream sockets:
 *
 *  SOCK_Write() writes data into an internal message buffer, appending new
 *  data as they come with each SOCK_Write().  When the message is complete,
 *  SOCK_SendMsg() should be called (optionally with additional last,
 *  or the only [if no SOCK_Write() preceded the call] message fragment)
 *  to actually send the message down the wire.  If successful, SOCK_SendMsg()
 *  cleans the internal buffer, and the process may repeat.  If unsuccessful,
 *  SOCK_SendMsg() can be repeated with restiction that no additional data are
 *  provided in the call.  This way, the entire message will be attempted to
 *  be sent again.  On the other hand, if after any SOCK_SendMsg() new data
 *  are added [regardless of whether previous data were successfully sent
 *  or not], all previously written [and kept in the internal send buffer]
 *  data get dropped and replaced with the new data.
 *
 *  DSOCK_WaitMsg() can be used to learn whether there is a new message
 *  available for read by DSOCK_RecvMsg() immediately.
 *
 *  SOCK_RecvMsg() receives the message into an internal receive buffer,
 *  and optionally can return the initial datagram fragment via provided
 *  buffer [this initial fragment is then stripped from what remains unread
 *  in the internal buffer].  Optimized version can supply a maximal message
 *  size (if known in advance), or 0 to get a message of any allowed size.
 *  The actual size of the received message can be obtained via a
 *  pointer-type argument 'msgsize'.  The message kept in the internal buffer
 *  can be read out in several SOCK_Read() calls, last returning eIO_Closed,
 *  when all data have been taken out.  SOCK_Wait() returns eIO_Success while
 *  there are data in the internal message buffer that SOCK_Read() can read.
 *
 *  SOCK_WipeMsg() can be used to clear the internal message buffers in
 *  either eIO_Read or eIO_Write directions, meaning receive and send
 *  buffers correspondingly.
 */


/**
 * @param sock
 *  [out] socket created
 * @param flags
 *  [in]  additional socket properties
 */
extern NCBI_XCONNECT_EXPORT EIO_Status DSOCK_CreateEx
(SOCK*       sock,
 TSOCK_Flags flags
 );


/** Same as DSOCK_CreateEx(, fSOCK_LogDefault)
 * @param sock
 *  [out] socket created
 */
extern NCBI_XCONNECT_EXPORT EIO_Status DSOCK_Create
(SOCK* sock
 );


/** Assosiate a datagram socket with a local port.
 * All other attempts to use the same port will result in eIO_Closed (for "port
 * busy") unless SOCK_SetReuseAddress() is called, which then allows multiple
 * sockets to bind to the same port, and receive messages, in undefined order,
 * arriving at that port.
 * Passing 0 will ask the OS to automatically select an unused port, which then
 * can be obtained via SOCK_GetLocalPort().
 * @param sock
 *  [in]  SOCK from DSOCK_Create[Ex]()
 * @param port
 *  [in]  port to bind to (0 to auto-select)
 * @sa
 *  SOCK_SetReuseAddress, SOCK_GetLocalPort
 */
extern NCBI_XCONNECT_EXPORT EIO_Status DSOCK_Bind
(SOCK           sock,
 unsigned short port
 );


/** Associate a datagram socket with a destination address.
 * @param sock
 *  [in]  SOCK from DSOCK_Create[Ex]()
 * @param host
 *  [in]  peer host
 * @param port
 *  [in]  peer port
 */
extern NCBI_XCONNECT_EXPORT EIO_Status DSOCK_Connect
(SOCK           sock,
 const char*    host,
 unsigned short port
 );


/** Wait for a datagram on a datagram socket.
 * @param sock
 *  [in]  SOCK from DSOCK_Create[Ex]()
 * @param timeout
 *  [in]  time to wait for message
 */
extern NCBI_XCONNECT_EXPORT EIO_Status DSOCK_WaitMsg
(SOCK            sock,
 const STimeout* timeout
 );


/** Send a datagram to a datagram socket.
 * @param sock
 *  [in]  SOCK from DSOCK_Create[Ex]()
 * @param host
 *  [in]  hostname or dotted IP
 * @param port
 *  [in]  port number, host byte order
 * @param data
 *  [in]  additional data to send
 * @param datalen
 *  [in]  size of additional data (bytes)
 */
extern NCBI_XCONNECT_EXPORT EIO_Status DSOCK_SendMsg
(SOCK           sock,
 const char*    host,
 unsigned short port,
 const void*    data,
 size_t         datalen
 );


/** Receive a datagram from a datagram socket.
 * @param sock
 *  [in]  SOCK from DSOCK_Create[Ex]()
 * @param buf
 *  [in]  buf to store msg at, may be NULL
 * @param bufsize
 *  [in]  buf length provided
 * @param maxmsglen
 *  [in]  maximal expected message len
 * @param msglen
 *  [out] actual msg size, may be NULL
 * @param sender_addr
 *  [out] net byte order, may be NULL
 * @param sender_port
 *  [out] host byte order, may be NULL
 */
extern NCBI_XCONNECT_EXPORT EIO_Status DSOCK_RecvMsg
(SOCK            sock,
 void*           buf,
 size_t          bufsize,
 size_t          maxmsglen,
 size_t*         msglen,
 unsigned int*   sender_addr,
 unsigned short* sender_port
);


/** Clear message froma datagram socket
 * @param sock
 *  [in]  SOCK from DSOCK_Create[Ex]()
 * @param direction
 *  [in]  either of eIO_Read (incoming), eIO_Write (outgoing)
 */
extern NCBI_XCONNECT_EXPORT EIO_Status DSOCK_WipeMsg
(SOCK      sock,
 EIO_Event direction
 );


/** Set a datagram socket for broadcast.
 * @param sock
 *  [in]  SOCK from DSOCK_Create[Ex]()
 * @param broadcast
 *  [in]  set(1)/unset(0) broadcast capability
 */
extern NCBI_XCONNECT_EXPORT EIO_Status DSOCK_SetBroadcast
(SOCK         sock,
 int/**bool*/ broadcast
 );


/** Get message count.
 * @param sock
 *  [in]  socket handle (datagram socket only)
 * @param direction
 *  [in]  either eIO_Read (in) or eIO_Write (out)
 * @return
 *  Total number of messages sent or received through this datagram socket.
 */
extern NCBI_XCONNECT_EXPORT TNCBI_BigCount DSOCK_GetMessageCount
(SOCK      sock,
 EIO_Event direction
 );



/******************************************************************************
 *  Type & statistics information for SOCK sockets
 */


/** Check whether a socket is a datagram one.
 * @param sock
 *  [in]  socket handle
 * @return
 *  Non-zero value if socket "sock" was created by DSOCK_Create[Ex]().
 *  Return zero otherwise.
 */
extern NCBI_XCONNECT_EXPORT int/**bool*/ SOCK_IsDatagram(SOCK sock);


/** Check whether a socket is client-side.
 * @param sock
 *  [in]  socket handle
 * @return
 *  Non-zero value if socket "sock" was created by SOCK_Create[Ex]().
 *  Return zero otherwise.
 */
extern NCBI_XCONNECT_EXPORT int/**bool*/ SOCK_IsClientSide(SOCK sock);


/** Check whether a socket is server-side.
 * @param sock
 *  [in]  socket handle
 * @return
 *  Non-zero value if socket "sock" was created by LSOCK_Accept().
 *  Return zero otherwise.
 */
extern NCBI_XCONNECT_EXPORT int/**bool*/ SOCK_IsServerSide(SOCK sock);


/** Check whether a socket is UNIX type.
 * @param sock
 *  [in]  socket handle
 * @return
 *  Non-zero value if socket "sock" is a UNIX family named socket
 *  Return zero otherwise.
 */
extern NCBI_XCONNECT_EXPORT int/**bool*/ SOCK_IsUNIX(SOCK sock);


/** Check whether a socket is using SSL (Secure Socket Layer).
 * @param sock
 *  [in]  socket handle
 * @return
 *  Non-zero value if socket "sock" is using Secure Socket Layer (SSL).
 *  Return zero otherwise.
 */
extern NCBI_XCONNECT_EXPORT int/**bool*/ SOCK_IsSecure(SOCK sock);


/** Get current read or write position within a socket.
 * @param sock
 *  [in]  socket handle
 * @param direction
 *  [in]  either eIO_Read or eIO_Write
 * @return
 *  Current read or write logical position, which takes any pending
 *  (i.e. unread or unwritten) data into account.
 */
extern NCBI_XCONNECT_EXPORT TNCBI_BigCount SOCK_GetPosition
(SOCK      sock,
 EIO_Event direction
 );


/** Get counts of read or written bytes.
 * @param sock
 *  [in]  socket handle
 * @param direction
 *  [in]  either eIO_Read or eIO_Write
 * @return
 *  Count of bytes actually read or written through this socket in the current
 *  session. For datagram sockets the count applies for the last message only;
 *  for stream sockets it counts only since last accept or connect event.
 */
extern NCBI_XCONNECT_EXPORT TNCBI_BigCount SOCK_GetCount
(SOCK      sock,
 EIO_Event direction
 );


/** Get the total volume of data transferred by a socket.
 * @param sock
 *  [in]  socket handle
 * @param direction
 *  [in]  either eIO_Read or eIO_Write
 * @return
 *  Total number of bytes transferred through the socket in its lifetime.
 */
extern NCBI_XCONNECT_EXPORT TNCBI_BigCount SOCK_GetTotalCount
(SOCK      sock,
 EIO_Event direction
 );


/******************************************************************************
 *   I/O restart on signals
 */

/** Control restartability of I/O interrupted by signals.
 * By default I/O is restartable if interrupted.
 * Pass "on_off" as eDefault to get the current setting.
 * @param on_off
 *  [in]  eOn to cancel I/O on signals;  eOff to restart
 * @return
 *  Prior setting
 * @sa
 *  SOCK_SetInterruptOnSignal
 */
extern NCBI_XCONNECT_EXPORT ESwitch SOCK_SetInterruptOnSignalAPI
(ESwitch on_off
 );


/** Control restartability of I/O interrupted by signals on a per-socket basis.
 * eDefault causes the use of global API flag.
 * @param sock
 *  [in]  socket handle
 * @param on_off
 *  [in]  per-socket I/O restart behavior on signals
 * @return
 *  Prior setting
 * @sa
 *  SOCK_SetInterruptOnSignalAPI, SOCK_Create, DSOCK_Create
 */
extern NCBI_XCONNECT_EXPORT ESwitch SOCK_SetInterruptOnSignal
(SOCK    sock,
 ESwitch on_off
 );


/******************************************************************************
 *   Address reuse: EXPERIMENTAL and may be removed in the upcoming releases!
 */

/** Control address reuse for socket addresses taken by the API.
 * By default address is not marked for reuse in either SOCK or DSOCK,
 * but is always reused for LSOCK (upon socket closure).
 * Pass "on_off" as eDefault to get the current setting.
 * @param on_off
 *  [in]  whether to turn on (eOn), turn off (eOff) or get current (eDefault)
 * @return
 *  Prior setting
 * @sa
 *  SOCK_SetReuseAddress
 */
extern NCBI_XCONNECT_EXPORT ESwitch SOCK_SetReuseAddressAPI
(ESwitch on_off
 );


/** Control reuse of socket addresses on per-socket basis
 * Note: only a boolean parameter value is can be used here.
 * @param sock
 *  [in]  socket handle
 * @param on_off
 *  [in]  whether to reuse the address (true, non-zero) or not (false, zero)
 * @sa
 *  SOCK_SetReuseAddressAPI, SOCK_Create, DSOCK_Create
 */
extern NCBI_XCONNECT_EXPORT void SOCK_SetReuseAddress
(SOCK         sock,
 int/**bool*/ on_off
 );


/******************************************************************************
 *  Error & Data Logging
 *
 * @note  Use CORE_SetLOG() from "ncbi_core.h" to set log handler.
 *
 * @sa
 *  CORE_SetLOG
 */

/** By default data are not logged.
 * @param log
 *  To start logging the data, call this func with "log" == eOn.
 *  To stop  logging the data, call this func with "log" == eOff.
 *  To get current log switch, call this func with "log" == eDefault.
 * @return
 *  Prior setting
 * @sa
 *  SOCK_SetDataLogging
 */
extern NCBI_XCONNECT_EXPORT ESwitch SOCK_SetDataLoggingAPI
(ESwitch log
 );


/** Control the data logging for socket "sock" individually.
 * @param sock
 *  [in]  socket handle
 * @param log
 *  [in]  requested data logging
 *  To reset to the global default behavior (as set by SOCK_SetDataLoggingAPI),
 *  call this function with "log" == eDefault.
 * @return
 *  Prior setting
 * @sa
 *  SOCK_SetDataLoggingAPI, SOCK_Create, DSOCK_Create
 */
extern NCBI_XCONNECT_EXPORT ESwitch SOCK_SetDataLogging
(SOCK    sock,
 ESwitch log
 );



/******************************************************************************
 * GENERIC POLLABLE INTERFACE, please see SOCK_Poll() above for explanations
 */


/*fwdecl; opaque*/
struct SPOLLABLE_tag;
typedef struct SPOLLABLE_tag* POLLABLE;

typedef struct {
    POLLABLE  poll;
    EIO_Event event;
    EIO_Event revent;
} SPOLLABLE_Poll;

/**
 * @param n
 *
 * @param polls[]
 *
 * @param timeout
 *
 * @param n_ready
 *
 */
extern NCBI_XCONNECT_EXPORT EIO_Status POLLABLE_Poll
(size_t          n,
 SPOLLABLE_Poll  polls[],
 const STimeout* timeout,
 size_t*         n_ready
 );


/**
 * @return
 *  Return 0 if conversion cannot be made; otherwise the converted handle
 */
extern NCBI_XCONNECT_EXPORT POLLABLE POLLABLE_FromSOCK   (SOCK);
extern NCBI_XCONNECT_EXPORT POLLABLE POLLABLE_FromLSOCK  (LSOCK);
extern NCBI_XCONNECT_EXPORT POLLABLE POLLABLE_FromTRIGGER(TRIGGER);
extern NCBI_XCONNECT_EXPORT SOCK     POLLABLE_ToSOCK   (POLLABLE);
extern NCBI_XCONNECT_EXPORT LSOCK    POLLABLE_ToLSOCK  (POLLABLE);
extern NCBI_XCONNECT_EXPORT TRIGGER  POLLABLE_ToTRIGGER(POLLABLE);



/******************************************************************************
 *  AUXILIARY network-specific functions (added for the portability reasons)
 */


/**
 * @param addr
 *  [in]  must be in the network byte-order
 * @param buf
 *  [out] to be filled by smth. like "123.45.67.89\0"
 * @param bufsize
 *  [in]  max # of bytes to put to "buf"
 * @return
 *  Zero on success, non-zero on error.  Vaguely related to BSD's
 *  inet_ntoa(). On error "buf" returned emptied (buf[0] == '\0').
 */
extern NCBI_XCONNECT_EXPORT int SOCK_ntoa
(unsigned int addr,
 char*        buf,
 size_t       bufsize
 );


/**
 * @param host
 *  [in]  '\0'-terminated string to check against being a plain IP address
 * @param fullquad
 *  [in]  non-zero to only accept "host" if it is a full-quad IP notation
 * @return
 *  Non-zero (true) if given string is an IP address, zero (false) otherwise.
 */
extern NCBI_XCONNECT_EXPORT int/*bool*/ SOCK_isipEx
(const char* host,
 int/*bool*/ fullquad
 );


/** Equivalent of SOCK_isip(host, 0)
 * @param host
 *  [in]  '\0'-terminated string to check against being a plain IP address
 * @return
 *  Non-zero (true) if given string is an IP address, zero (false) otherwise.
 */
extern NCBI_XCONNECT_EXPORT int/*bool*/ SOCK_isip
(const char* host
 );


/** See man for the BSDisms, htonl() and htons().
 * @param value
 *
 */
extern NCBI_XCONNECT_EXPORT unsigned int SOCK_HostToNetLong
(unsigned int value
 );

#define SOCK_NetToHostLong SOCK_HostToNetLong

/**
 * @param value
 *
 */
extern NCBI_XCONNECT_EXPORT unsigned short SOCK_HostToNetShort
(unsigned short value
 );

#define SOCK_NetToHostShort SOCK_HostToNetShort


/* Deprecated:  Use SOCK_{Host|Net}To{Net|Host}{Long|Short}() instead */
#ifndef NCBI_DEPRECATED
#  define NCBI_SOCK_DEPRECATED
#else
#  define NCBI_SOCK_DEPRECATED NCBI_DEPRECATED
#endif
extern NCBI_XCONNECT_EXPORT NCBI_SOCK_DEPRECATED
unsigned int   SOCK_htonl(unsigned int);
#define        SOCK_ntohl SOCK_htonl
extern NCBI_XCONNECT_EXPORT NCBI_SOCK_DEPRECATED
unsigned short SOCK_htons(unsigned short);
#define        SOCK_ntohs SOCK_htons


/**
 * @param name
 *  [out] (guaranteed to be '\0'-terminated)
 * @param namelen
 *  [in]   max # of bytes allowed to put to "name"
 * @param log
 *  [in]   whether to log failures
 * @return
 *  Zero on success, non-zero on error.  See BSD gethostname().
 *  On error "name" returned emptied (name[0] == '\0').
 * @sa
 *  SOCK_gethostname
 */
extern NCBI_XCONNECT_EXPORT int SOCK_gethostnameEx
(char*   name,
 size_t  namelen,
 ESwitch log
 );


/** Same as SOCK_gethostnameEx(,,eOff)
 * @sa
 *  SOCK_gethostnameEx
 */
extern NCBI_XCONNECT_EXPORT int SOCK_gethostname
(char*  name,
 size_t namelen
 );


/**
 * @param hostname
 *  [in]  specified host, or the current host if hostname is 0
 * @param log
 *  [in]  whether to log failures
 * @return
 *  INET host address (in network byte order) of the specified host
 *  (or local host, if hostname is passed as NULL), which can be either
 *  domain name or an IP address in the dotted notation
 *  (e.g. "123.45.67.89\0").  Return 0 on error.
 *  @note  "0.0.0.0" and "255.255.255.255" are both considered invalid.
 * @sa
 *  SOCK_gethostbyname, SOCK_gethostname
 */
extern NCBI_XCONNECT_EXPORT unsigned int SOCK_gethostbynameEx
(const char* hostname,
 ESwitch     log
 );


/** Same as SOCK_gethostbynameEx(,eOff)
 * @sa
 *  SOCK_gethostbynameEx
 */
extern NCBI_XCONNECT_EXPORT unsigned int SOCK_gethostbyname
(const char* hostname
 );


/** Take INET host address (in network byte order) and fill out the
 * the provided buffer with the name, which the address corresponds to
 * (in case of multiple names the primary name is used).
 * @param addr
 *  [in]  host address in network byte order
 * @param name
 *  [out] buffer to put the name to
 * @param namelen
 *  [in]  size (bytes) of the buffer above
 * @param log
 *  [in]  whether to log failures
 * @return
 *  Value 0
 *  means error, while success is denoted by the 'name' argument returned.
 *  Note that on error the name returned emptied (name[0] == '\0').
 * @sa
 *  SOCK_gethostbyaddr
 */
extern NCBI_XCONNECT_EXPORT char* SOCK_gethostbyaddrEx
(unsigned int addr,
 char*        name,
 size_t       namelen,
 ESwitch      log
 );


/** Same as SOCK_gethostbyaddrEx(,,eOff)
 * @sa
 *  SOCK_gethostbyaddrEx
 */
extern NCBI_XCONNECT_EXPORT char* SOCK_gethostbyaddr
(unsigned int addr,
 char*        name,
 size_t       namelen
 );


/**
 * @return
 *  Loopback address (in network byte order).
 */
extern NCBI_XCONNECT_EXPORT unsigned int SOCK_GetLoopbackAddress(void);


/** Get (and cache for faster follow-up retrievals) the address of local host
 * @param reget
 *  eOn      to forcibly recache and return the address;
 *  eDefault to recache only if unknown, return the cached value;
 *  eOff     not to recache even if unknown, return whatever is available.
 * @return
 *  Local address (in network byte order).
 */
extern NCBI_XCONNECT_EXPORT unsigned int SOCK_GetLocalHostAddress
(ESwitch reget
 );


/** Read (skipping leading blanks) "[host][:port]" from a string stopping
 * at EOL or a blank character.
 * @param str
 *  must not be NULL
 * @param host
 *  may be NULL for no assignment
 * @param port
 *  may be NULL for no assignment
 * @return
 *  On success, return the advanced pointer past the host/port read.
 *  If no host/port detected, return 'str'.  On format error, return 0.
 *  If host and/or port fragments are missing, then the corresponding 'host'/
 *  'port' parameters get a value of 0.
 * @note  'host' gets returned in network byte order, unlike 'port', which
 *        always comes out in host (native) byte order.
 */
extern NCBI_XCONNECT_EXPORT const char* SOCK_StringToHostPort
(const char*     str,
 unsigned int*   host,
 unsigned short* port
 );


/** Print host:port into provided buffer string, not to exceed 'bufsize' bytes
 * (including the teminating '\0' character).
 * Suppress printing host if parameter 'host' is zero.
 * @param host
 *  in network byte order
 * @param port
 *  in host byte order
 * @param buf
 *  must not be NULL
 * @param bufsize
 *  must be large enough
 * @return
 *  Number of bytes printed, or 0 on error (e.g. buffer too short).
 */
extern NCBI_XCONNECT_EXPORT size_t SOCK_HostPortToString
(unsigned int   host,
 unsigned short port,
 char*          buf,
 size_t         bufsize
 );


/******************************************************************************
 *  Secure Socket Layer support
 */

/*fwdecl*/
struct SOCKSSL_struct;
typedef const struct SOCKSSL_struct* SOCKSSL;


typedef SOCKSSL (*FSSLSetup)(void);

extern NCBI_XCONNECT_EXPORT void SOCK_SetupSSL(FSSLSetup setup);


#ifdef __cplusplus
} /* extern "C" */
#endif


/* @} */

#endif /* CONNECT___NCBI_SOCKET__H */