1 #ifndef CONNECT___NCBI_SOCKETP__H 2 #define CONNECT___NCBI_SOCKETP__H 3 4 /* $Id: ncbi_socketp.h,v 1.31 2016/01/01 00:44:15 fukanchi Exp $ 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(ENFILE) 127 # define SOCK_ETOOMANY ENFILE 128 #elif defined(EMFILE) 129 # define SOCK_ETOOMANY EMFILE 130 #elif defined(WSAEMFILE) 131 # define SOCK_ETOOMANY WSAEMFILE 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 /* Event trigger 159 */ 160 typedef struct TRIGGER_tag { 161 TRIGGER_Handle fd; /* OS-specific trigger handle */ 162 unsigned int id; /* the internal ID (cf. "s_ID_Counter") */ 163 164 union { 165 volatile void* ptr; /* trigger state (UNIX only, otherwise MBZ) */ 166 int int_[2]; /* pointer storage area w/proper alignment */ 167 } isset; 168 169 /* type, status, EOF, log, read-on-write etc bit-field indicators */ 170 TBSOCK_Type type:2; /* eTrigger */ 171 EBSwitch log:2; /* how to log events */ 172 EBSwitch r_on_w:2; /* MBZ */ 173 EBSwitch i_on_sig:2; /* eDefault */ 174 175 EBIO_Status r_status:3; /* MBZ (NB: eIO_Success) */ 176 unsigned/*bool*/ eof:1; /* MBZ */ 177 EBIO_Status w_status:3; /* MBZ (NB: eIO_Success) */ 178 unsigned/*bool*/ pending:1; /* MBZ */ 179 180 unsigned reserved:16;/* MBZ */ 181 182 #ifdef NCBI_OS_UNIX 183 int out; /* write end of the pipe */ 184 #endif /*NCBI_OS_UNIX*/ 185 } TRIGGER_struct; 186 187 188 /* Sides of socket 189 */ 190 typedef enum { 191 eSOCK_Server = 0, 192 eSOCK_Client = 1 193 } ESOCK_Side; 194 195 typedef unsigned EBSOCK_Side; 196 197 198 /* Listening socket [must be in one-2-one binary correspondene with TRIGGER] 199 */ 200 typedef struct LSOCK_tag { 201 TSOCK_Handle sock; /* OS-specific socket handle */ 202 unsigned int id; /* the internal ID (see also "s_ID_Counter") */ 203 204 unsigned int n_accept; /* total number of accepted clients */ 205 unsigned short away; /* MSWIN: run-away connect warning counter */ 206 unsigned short port; /* port on which listening (host byte order) */ 207 208 /* type, status, EOF, log, read-on-write etc bit-field indicators */ 209 TBSOCK_Type type:2; /* eListening */ 210 EBSwitch log:2; /* how to log events and data for this socket*/ 211 EBSwitch r_on_w:2; /* MBZ */ 212 EBSwitch i_on_sig:2; /* eDefault */ 213 214 EBIO_Status r_status:3; /* MBZ (NB: eIO_Success) */ 215 unsigned/*bool*/ eof:1; /* MBZ */ 216 EBIO_Status w_status:3; /* MBZ (NB: eIO_Success) */ 217 unsigned/*bool*/ pending:1; /* MBZ */ 218 219 EBSOCK_Side side:1; /* MBZ (NB: eSOCK_Server) */ 220 unsigned/*bool*/ keep:1; /* whether to keep OS handle upon close */ 221 #ifndef NCBI_OS_MSWIN 222 unsigned reserved:14;/* MBZ */ 223 #else 224 unsigned reserved:11;/* MBZ */ 225 unsigned readable:1; /* =1 if known to have a pending accept */ 226 unsigned unused:2; /* MBZ */ 227 228 WSAEVENT event; /* event bound to I/O */ 229 #endif /*!NCBI_OS_MSWIN*/ 230 231 void* context; /* per-server session/credentials (not impl) */ 232 233 #ifdef NCBI_OS_UNIX 234 char path[1]; /* must go last */ 235 #endif /*NCBI_OS_UNIX*/ 236 } LSOCK_struct; 237 238 239 /* Socket [it must be in 1-2-1 binary correspondence with LSOCK above] 240 */ 241 typedef struct SOCK_tag { 242 TSOCK_Handle sock; /* OS-specific socket handle */ 243 unsigned int id; /* the internal ID (see also "s_ID_Counter") */ 244 245 /* connection point */ 246 unsigned int host; /* peer host (network byte order) */ 247 unsigned short port; /* peer port (host byte order) */ 248 unsigned short myport; /* this socket's port number, host byte order*/ 249 250 /* type, status, EOF, log, read-on-write etc bit-field indicators */ 251 TBSOCK_Type type:2; /* |= eSocket ({ eSocket | eDatagram }) */ 252 EBSwitch log:2; /* how to log events and data for this socket*/ 253 EBSwitch r_on_w:2; /* enable/disable automatic read-on-write */ 254 EBSwitch i_on_sig:2; /* enable/disable I/O restart on signals */ 255 256 EBIO_Status r_status:3; /* read status: eIO_Closed if was shut down*/ 257 unsigned/*bool*/ eof:1; /* Stream sockets: 'End of file' seen on read 258 Datagram socks: 'End of message' written */ 259 EBIO_Status w_status:3; /* write status: eIO_Closed if was shut down*/ 260 unsigned/*bool*/ pending:1; /* =1 if connection is still initing */ 261 262 EBSOCK_Side side:1; /* socket side: client- or server-side */ 263 unsigned/*bool*/ keep:1; /* whether to keep OS handle upon close */ 264 unsigned crossexec:1; /* =1 if close-on-exec must NOT be set */ 265 unsigned connected:1; /* =1 if remote end-point is fully connected */ 266 unsigned r_tv_set:1; /* =1 if read timeout is set (i.e. finite) */ 267 unsigned w_tv_set:1; /* =1 if write timeout is set (i.e. finite) */ 268 unsigned c_tv_set:1; /* =1 if close timeout is set (i.e. finite) */ 269 unsigned keepalive:1; /* =1 if needs to be kept alive (if OS supp.)*/ 270 #ifndef NCBI_OS_MSWIN 271 unsigned reserved:8; /* MBZ */ 272 #else 273 unsigned reserved:5; /* MBZ */ 274 unsigned readable:1; /* =1 if known to be readable */ 275 unsigned writable:1; /* =1 if known to be writeable */ 276 unsigned closing:1; /* =1 if FD_CLOSE posted */ 277 278 WSAEVENT event; /* event bound to I/O */ 279 #endif /*!NCBI_OS_MSWIN*/ 280 281 void* session; /* secure session handle if used, else 0 */ 282 NCBI_CRED cred; /* secure session credentials, 0 if none */ 283 284 /* timeouts */ 285 struct timeval r_tv; /* finite read timeout value */ 286 struct timeval w_tv; /* finite write timeout value */ 287 struct timeval c_tv; /* finite close timeout value */ 288 STimeout r_to; /* finite read timeout value (aux., temp.) */ 289 STimeout w_to; /* finite write timeout value (aux., temp.) */ 290 STimeout c_to; /* finite close timeout value (aux., temp.) */ 291 292 /* aux I/O data */ 293 BUF r_buf; /* read buffer */ 294 BUF w_buf; /* write buffer */ 295 size_t r_len; /* DSOCK: size of last message received */ 296 size_t w_len; /* SOCK: how much data is pending for output */ 297 298 /* statistics */ 299 TNCBI_BigCount n_read; /* DSOCK: total # of bytes read (in all msgs) 300 SOCK: # of bytes read since last connect 301 */ 302 TNCBI_BigCount n_written; /* DSOCK: total # of bytes written (all msgs) 303 SOCK: # of bytes written since last connect 304 */ 305 TNCBI_BigCount n_in; /* DSOCK: total # of messages received 306 SOCK: total # of bytes read in all 307 completed connections in this SOCK so far 308 */ 309 TNCBI_BigCount n_out; /* DSOCK: total # of messages sent 310 SOCK: total # of bytes written in all 311 completed connections in this SOCK so far 312 */ 313 #ifdef NCBI_OS_UNIX 314 /* pathname for UNIX socket */ 315 char path[1]; /* must go last */ 316 #endif /*NCBI_OS_UNIX*/ 317 } SOCK_struct; 318 319 320 /* 321 * The following implementation details are worth noting: 322 * 323 * 1. w_buf is used for stream sockets to keep initial data segment 324 * that has to be sent upon connection establishment. 325 * 326 * 2. eof is used differently for stream and datagram sockets: 327 * =1 for stream sockets means that last read has hit EOF; 328 * =1 for datagram sockets means that message in w_buf has been completed. 329 * 330 * 3. r_status keeps completion code of the last low-level read call; 331 * however, eIO_Closed is there when the socket is shut down for reading; 332 * see the table below for full details on stream sockets. 333 * 334 * 4. w_status keeps completion code of the last low-level write call; 335 * however, eIO_Closed is there when the socket is shut down for writing. 336 * 337 * 5. The following table depicts r_status and eof combinations and their 338 * meanings for stream sockets: 339 * -------------------------------+-------------------------------------------- 340 * Field | 341 * ---------------+---------------+ Meaning 342 * sock->r_status | sock->eof | (stream sockets only) 343 * ---------------+---------------+-------------------------------------------- 344 * eIO_Closed | 0 | Socket shut down for reading 345 * eIO_Closed | 1 | Read severely failed 346 * not eIO_Closed | 0 | Read completed with r_status error 347 * not eIO_Closed | 1 | Read hit EOF (and [maybe later] r_status) 348 * ---------------+---------------+-------------------------------------------- 349 */ 350 351 352 #if defined(NCBI_OS_MSWIN) && defined(_WIN64) 353 # pragma pack(pop) 354 #endif /*NCBI_OS_MSWIN && _WIN64*/ 355 356 357 /* Global data */ 358 extern const char g_kNcbiSockNameAbbr[]; 359 360 361 /* Initial socket data & respective private ctors */ 362 typedef struct { 363 const void* data; 364 size_t size; 365 NCBI_CRED cred; 366 } SSOCK_Init; 367 368 369 EIO_Status SOCK_CreateInternal(const char* host, 370 unsigned short port, 371 const STimeout* timeout, 372 SOCK* sock, 373 SSOCK_Init* init, 374 TSOCK_Flags flags); 375 376 377 EIO_Status SOCK_CreateOnTopInternal(const void* handle, 378 size_t handle_size, 379 SOCK* sock, 380 SSOCK_Init* init, 381 TSOCK_Flags flags); 382 383 384 /* Addtl socket API for internal use: if flag != 0 and host is nonexistent, 385 * return it as INADDR_NONE (-1) rather than an error. 386 */ 387 const char* SOCK_StringToHostPortEx(const char* str, 388 unsigned int* host, 389 unsigned short* port, 390 int/*bool*/ flag); 391 392 393 #ifdef __cplusplus 394 } /* extern "C" */ 395 #endif /*__cplusplus*/ 396 397 398 #endif /* CONNECT___NCBI_SOCKETP__H */ 399