1 #ifndef CONNECT___NCBI_SOCKETP__H 2 #define CONNECT___NCBI_SOCKETP__H 3 4 /* $Id: ncbi_socketp.h 606556 2020-04-23 14:39:23Z lavr $ 5 * =========================================================================== 6 * 7 * PUBLIC DOMAIN NOTICE 8 * National Center for Biotechnology Information 9 * 10 * This software/database is a "United States Government Work" under the 11 * terms of the United States Copyright Act. It was written as part of 12 * the author's official duties as a United States Government employee and 13 * thus cannot be copyrighted. This software/database is freely available 14 * to the public for use. The National Library of Medicine and the U.S. 15 * Government have not placed any restriction on its use or reproduction. 16 * 17 * Although all reasonable efforts have been taken to ensure the accuracy 18 * and reliability of the software and data, the NLM and the U.S. 19 * Government do not and cannot warrant the performance or results that 20 * may be obtained by using this software or data. The NLM and the U.S. 21 * Government disclaim all warranties, express or implied, including 22 * warranties of performance, merchantability or fitness for any particular 23 * purpose. 24 * 25 * Please cite the author in any work or product based on this material. 26 * 27 * =========================================================================== 28 * 29 * Author: Anton Lavrentiev 30 * 31 * File Description: 32 * Private API to define socket structure 33 * 34 */ 35 36 #include "ncbi_config.h" 37 /* OS must be specified in the command-line ("-D....") or in the conf. header 38 */ 39 #if !defined(NCBI_OS_UNIX) && !defined(NCBI_OS_MSWIN) 40 # error "Unknown OS, must be one of NCBI_OS_UNIX, NCBI_OS_MSWIN!" 41 #endif /*supported platforms*/ 42 43 #include <connect/ncbi_socket.h> 44 #include <connect/ncbi_buffer.h> 45 46 47 /* Pull in a minial set of platform-specific system headers here. 48 */ 49 50 #ifdef NCBI_OS_MSWIN 51 # define _WINSOCK_DEPRECATED_NO_WARNINGS 1 52 # include <winsock2.h> 53 #else /*NCBI_OS_UNIX*/ 54 # include <sys/socket.h> 55 # include <sys/time.h> 56 #endif /*NCBI_OS_MSWIN*/ 57 58 /* Portable error codes. 59 */ 60 #include <errno.h> 61 62 #ifdef __cplusplus 63 extern "C" { 64 #endif /*__cplusplus*/ 65 66 #ifdef NCBI_OS_MSWIN 67 68 typedef SOCKET TSOCK_Handle; /* NB: same as HANDLE */ 69 typedef HANDLE TRIGGER_Handle; /* NB: same as WSAEVENT */ 70 71 # ifdef _WIN64 72 # pragma pack(push, 4) 73 # endif /*_WIN64*/ 74 75 # define SOCK_EINTR WSAEINTR 76 # define SOCK_EWOULDBLOCK WSAEWOULDBLOCK/*EAGAIN*/ 77 # define SOCK_EADDRINUSE WSAEADDRINUSE 78 # define SOCK_ECONNRESET WSAECONNRESET 79 # define SOCK_EPIPE WSAESHUTDOWN 80 # define SOCK_EAGAIN WSAEINPROGRESS/*special-case missing in WSA*/ 81 # define SOCK_EINPROGRESS WSAEINPROGRESS 82 # define SOCK_EALREADY WSAEALREADY 83 # define SOCK_ENOTCONN WSAENOTCONN 84 # define SOCK_ECONNABORTED WSAECONNABORTED 85 # define SOCK_ECONNREFUSED WSAECONNREFUSED 86 # define SOCK_ENETRESET WSAENETRESET 87 # define SOCK_ETIMEDOUT WSAETIMEDOUT 88 # define SOCK_SHUTDOWN_RD SD_RECEIVE 89 # define SOCK_SHUTDOWN_WR SD_SEND 90 # define SOCK_SHUTDOWN_RDWR SD_BOTH 91 92 #else /*NCBI_OS_UNIX*/ 93 94 typedef int TSOCK_Handle; 95 typedef int TRIGGER_Handle; 96 97 # define SOCK_EINTR EINTR 98 # define SOCK_EWOULDBLOCK EWOULDBLOCK 99 # define SOCK_EADDRINUSE EADDRINUSE 100 # define SOCK_ECONNRESET ECONNRESET 101 # define SOCK_EPIPE EPIPE 102 # define SOCK_EAGAIN EAGAIN 103 # define SOCK_EINPROGRESS EINPROGRESS 104 # define SOCK_EALREADY EALREADY 105 # define SOCK_ENOTCONN ENOTCONN 106 # define SOCK_ECONNABORTED ECONNABORTED 107 # define SOCK_ECONNREFUSED ECONNREFUSED 108 # define SOCK_ENETRESET ENETRESET 109 # define SOCK_ETIMEDOUT ETIMEDOUT 110 111 # ifndef SHUT_RD 112 # define SHUT_RD 0 113 # endif /*SHUT_RD*/ 114 # define SOCK_SHUTDOWN_RD SHUT_RD 115 # ifndef SHUT_WR 116 # define SHUT_WR 1 117 # endif /*SHUT_WR*/ 118 # define SOCK_SHUTDOWN_WR SHUT_WR 119 # ifndef SHUT_RDWR 120 # define SHUT_RDWR 2 121 # endif /*SHUT_RDWR*/ 122 # define SOCK_SHUTDOWN_RDWR SHUT_RDWR 123 124 #endif /*NCBI_OS_MSWIN*/ 125 126 #if defined(WSAEMFILE) 127 # define SOCK_ETOOMANY WSAEMFILE 128 #elif defined(EMFILE) 129 # define SOCK_ETOOMANY EMFILE 130 #elif defined(ENFILE) 131 # define SOCK_ETOOMANY ENFILE 132 #elif defined(EINVAL) 133 # define SOCK_ETOOMANY EINVAL 134 #else 135 # define SOCK_ETOOMANY 0 136 #endif 137 138 139 #if 0/*defined(__GNUC__)*/ 140 typedef ESwitch EBSwitch; 141 typedef EIO_Status EBIO_Status; 142 #else 143 typedef unsigned EBSwitch; 144 typedef unsigned EBIO_Status; 145 #endif 146 147 148 typedef enum { 149 eListening = 0, 150 eTrigger = 1, 151 eSocket = 2, 152 eDatagram = 3/*2|1*/ 153 } ESOCK_Type; 154 155 typedef unsigned TBSOCK_Type; 156 157 158 typedef struct { 159 void* sess; /* secure session handle, 0 if none */ 160 NCBI_CRED cred; /* secure session credential(s), 0 if none */ 161 SOCK sock; /* sock that the above session handle using */ 162 const char* host; /* hostname for named SSL extension */ 163 } SNcbiSSLctx; 164 165 166 /* Event trigger 167 */ 168 typedef struct TRIGGER_tag { 169 TRIGGER_Handle fd; /* OS-specific trigger handle */ 170 unsigned int id; /* the internal ID (cf. "s_ID_Counter") */ 171 172 union { 173 volatile void* ptr; /* trigger state (UNIX only, otherwise MBZ) */ 174 int int_[2]; /* pointer storage area w/proper alignment */ 175 } isset; 176 177 int err; /* Last OS error */ 178 179 /* type, status, EOF, log, read-on-write etc bit-field indicators */ 180 TBSOCK_Type type:2; /* eTrigger */ 181 EBSwitch log:2; /* how to log events */ 182 EBSwitch r_on_w:2; /* MBZ */ 183 EBSwitch i_on_sig:2; /* eDefault */ 184 185 EBIO_Status r_status:3; /* MBZ (NB: eIO_Success) */ 186 unsigned/*bool*/ eof:1; /* MBZ */ 187 EBIO_Status w_status:3; /* MBZ (NB: eIO_Success) */ 188 unsigned/*bool*/ pending:1; /* MBZ */ 189 190 unsigned reserved:16;/* MBZ */ 191 192 #ifdef NCBI_OS_UNIX 193 int out; /* write end of the pipe */ 194 #endif /*NCBI_OS_UNIX*/ 195 } TRIGGER_struct; 196 197 198 /* Sides of socket 199 */ 200 typedef enum { 201 eSOCK_Server = 0, 202 eSOCK_Client = 1 203 } ESOCK_Side; 204 205 typedef unsigned EBSOCK_Side; 206 207 208 /* Listening socket [must be in one-2-one binary correspondene with TRIGGER] 209 */ 210 typedef struct LSOCK_tag { 211 TSOCK_Handle sock; /* OS-specific socket handle */ 212 unsigned int id; /* the internal ID (see also "s_ID_Counter") */ 213 214 unsigned int n_accept; /* total number of accepted clients */ 215 unsigned short away; /* MSWIN: run-away connect warning counter */ 216 unsigned short port; /* port on which listening (host byte order) */ 217 218 int err; /* Last OS error */ 219 220 /* type, status, EOF, log, read-on-write etc bit-field indicators */ 221 TBSOCK_Type type:2; /* eListening */ 222 EBSwitch log:2; /* how to log events and data for this socket*/ 223 EBSwitch r_on_w:2; /* MBZ */ 224 EBSwitch i_on_sig:2; /* eDefault */ 225 226 EBIO_Status r_status:3; /* MBZ (NB: eIO_Success) */ 227 unsigned/*bool*/ eof:1; /* MBZ */ 228 EBIO_Status w_status:3; /* MBZ (NB: eIO_Success) */ 229 unsigned/*bool*/ pending:1; /* MBZ */ 230 231 EBSOCK_Side side:1; /* MBZ (NB: eSOCK_Server) */ 232 unsigned/*bool*/ keep:1; /* whether to keep OS handle upon close */ 233 #ifndef NCBI_OS_MSWIN 234 unsigned reserved:14;/* MBZ */ 235 #else 236 unsigned reserved:11;/* MBZ */ 237 unsigned readable:1; /* =1 if known to have a pending accept */ 238 unsigned unused:2; /* MBZ */ 239 240 WSAEVENT event; /* event bound to I/O */ 241 #endif /*!NCBI_OS_MSWIN*/ 242 243 void* context; /* per-server session/credentials (not impl) */ 244 245 #ifdef NCBI_OS_UNIX 246 char path[1]; /* must go last */ 247 #endif /*NCBI_OS_UNIX*/ 248 } LSOCK_struct; 249 250 251 /* Socket [it must be in 1-2-1 binary correspondence with LSOCK above] 252 */ 253 typedef struct SOCK_tag { 254 TSOCK_Handle sock; /* OS-specific socket handle */ 255 unsigned int id; /* the internal ID (see also "s_ID_Counter") */ 256 257 /* connection point */ 258 unsigned int host; /* peer host (network byte order) */ 259 unsigned short port; /* peer port (host byte order) */ 260 unsigned short myport; /* this socket's port number, host byte order*/ 261 262 int err; /* Last OS error */ 263 264 /* type, status, EOF, log, read-on-write etc bit-field indicators */ 265 TBSOCK_Type type:2; /* |= eSocket ({ eSocket | eDatagram }) */ 266 EBSwitch log:2; /* how to log events and data for this socket*/ 267 EBSwitch r_on_w:2; /* enable/disable automatic read-on-write */ 268 EBSwitch i_on_sig:2; /* enable/disable I/O restart on signals */ 269 270 EBIO_Status r_status:3; /* read status: eIO_Closed if was shut down*/ 271 unsigned/*bool*/ eof:1; /* Stream sockets: 'End of file' seen on read 272 Datagram socks: 'End of message' written */ 273 EBIO_Status w_status:3; /* write status: eIO_Closed if was shut down*/ 274 unsigned/*bool*/ pending:1; /* =1 if connection is still initing */ 275 276 EBSOCK_Side side:1; /* socket side: client- or server-side */ 277 unsigned/*bool*/ keep:1; /* whether to keep OS handle upon close */ 278 unsigned crossexec:1; /* =1 if close-on-exec must NOT be set */ 279 unsigned connected:1; /* =1 if remote end-point is fully connected */ 280 unsigned r_tv_set:1; /* =1 if read timeout is set (i.e. finite) */ 281 unsigned w_tv_set:1; /* =1 if write timeout is set (i.e. finite) */ 282 unsigned c_tv_set:1; /* =1 if close timeout is set (i.e. finite) */ 283 unsigned keepalive:1; /* =1 if needs to be kept alive (if OS supp.)*/ 284 #ifndef NCBI_OS_MSWIN 285 unsigned reserved:8; /* MBZ */ 286 #else 287 unsigned reserved:5; /* MBZ */ 288 unsigned readable:1; /* =1 if known to be readable */ 289 unsigned writable:1; /* =1 if known to be writeable */ 290 unsigned closing:1; /* =1 if FD_CLOSE posted */ 291 292 WSAEVENT event; /* event bound to I/O */ 293 #endif /*!NCBI_OS_MSWIN*/ 294 295 SNcbiSSLctx* sslctx; /* secure session context if SSL's on, else 0*/ 296 297 /* timeouts */ 298 struct timeval r_tv; /* finite read timeout value */ 299 struct timeval w_tv; /* finite write timeout value */ 300 struct timeval c_tv; /* finite close timeout value */ 301 STimeout r_to; /* finite read timeout value (aux., temp.) */ 302 STimeout w_to; /* finite write timeout value (aux., temp.) */ 303 STimeout c_to; /* finite close timeout value (aux., temp.) */ 304 305 /* aux I/O data */ 306 BUF r_buf; /* read buffer */ 307 BUF w_buf; /* write buffer */ 308 size_t r_len; /* SOCK: unused; DSOCK: sz of last msg recv'd*/ 309 size_t w_len; /* SOCK: w_buf; DSOCK: sz of last msg sent */ 310 311 /* statistics */ 312 TNCBI_BigCount n_read; /* DSOCK: total # of bytes read (in all msgs) 313 SOCK: # of bytes read since last connect 314 */ 315 TNCBI_BigCount n_written; /* DSOCK: total # of bytes written (all msgs) 316 SOCK: # of bytes written since last connect 317 */ 318 TNCBI_BigCount n_in; /* DSOCK: total # of messages received 319 SOCK: total # of bytes read in all 320 completed connections in this SOCK so far 321 */ 322 TNCBI_BigCount n_out; /* DSOCK: total # of messages sent 323 SOCK: total # of bytes written in all 324 completed connections in this SOCK so far 325 */ 326 #ifdef NCBI_OS_UNIX 327 /* pathname for UNIX socket */ 328 char path[1]; /* must go last */ 329 #endif /*NCBI_OS_UNIX*/ 330 } SOCK_struct; 331 332 333 /* 334 * The following implementation details are worth noting: 335 * 336 * 1. w_buf is used for stream sockets to keep initial data segment 337 * that has to be sent upon connection establishment. 338 * 339 * 2. eof is used differently for stream and datagram sockets: 340 * =1 for stream sockets means that last read has hit EOF; 341 * =1 for datagram sockets means that message in w_buf has been completed. 342 * 343 * 3. r_status keeps completion code of the last low-level read call; 344 * however, eIO_Closed is there when the socket is shut down for reading; 345 * see the table below for full details on stream sockets. 346 * 347 * 4. w_status keeps completion code of the last low-level write call; 348 * however, eIO_Closed is there when the socket is shut down for writing. 349 * 350 * 5. The following table depicts r_status and eof combinations and their 351 * meanings for stream sockets: 352 * -------------------------------+-------------------------------------------- 353 * Field | 354 * ---------------+---------------+ Meaning 355 * sock->r_status | sock->eof | (stream sockets only) 356 * ---------------+---------------+-------------------------------------------- 357 * eIO_Closed | 0 | Socket shut down for reading 358 * eIO_Closed | 1 | Read severely failed 359 * not eIO_Closed | 0 | Read completed with r_status error 360 * not eIO_Closed | 1 | Read hit EOF (and [maybe later] r_status) 361 * ---------------+---------------+-------------------------------------------- 362 */ 363 364 365 #if defined(NCBI_OS_MSWIN) && defined(_WIN64) 366 # pragma pack(pop) 367 #endif /*NCBI_OS_MSWIN && _WIN64*/ 368 369 370 /* Global data */ 371 extern const char g_kNcbiSockNameAbbr[]; 372 373 374 /* Initial socket data & respective private ctors */ 375 typedef struct { 376 const void* data; 377 size_t size; 378 NCBI_CRED cred; 379 const char* host; 380 } SSOCK_Init; 381 382 383 EIO_Status SOCK_CreateInternal(const char* host, 384 unsigned short port, 385 const STimeout* timeout, 386 SOCK* sock, 387 const SSOCK_Init* init, 388 TSOCK_Flags flags); 389 390 391 EIO_Status SOCK_CreateOnTopInternal(const void* handle, 392 size_t handle_size, 393 SOCK* sock, 394 const SSOCK_Init* init, 395 TSOCK_Flags flags); 396 397 398 /* Addtl socket API for internal use: if flag != 0 and host is nonexistent, 399 * return it as INADDR_NONE (-1) rather than an error. 400 */ 401 const char* SOCK_StringToHostPortEx(const char* str, 402 unsigned int* host, 403 unsigned short* port, 404 int/*bool*/ flag); 405 406 407 void SOCK_SetupSSLInternal(FSSLSetup setup, int/*bool*/ init); 408 409 410 #ifdef __cplusplus 411 } /* extern "C" */ 412 #endif /*__cplusplus*/ 413 414 415 #endif /* CONNECT___NCBI_SOCKETP__H */ 416