1 2 #ifndef __LIBGSOCKET_H__ 3 #define __LIBGSOCKET_H__ 1 4 5 6 #if 0 7 #if defined __has_include 8 # if __has_include (<openssl/srp.h>) 9 # define HAS_OPENSSL_SRP 1 10 # endif 11 # if __has_include ("gsocket-ssl.h") 12 # define HAS_GSOCKET_SSL 1 13 # endif 14 # if __has_include (<gsocket/gsocket-ssl.h>) 15 # define HAS_GSOCKET_SSL 1 16 # endif 17 #endif 18 19 /* The user can delete gsocket-ssl.h to build his project without OpenSSL */ 20 #ifdef HAS_OPENSSL_SRP 21 # ifdef HAS_GSOCKET_SSL 22 # define WITH_GSOCKET_SSL 1 23 # endif 24 #endif 25 #endif 26 27 #define WITH_GSOCKET_SSL 1 28 29 #ifndef GS_MAX 30 # define GS_MAX(X, Y) (((X) < (Y)) ? (Y) : (X)) 31 #endif 32 33 #ifndef GS_MIN 34 # define GS_MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) 35 #endif 36 37 #define GS_ADDR_SIZE (16) /* 128 bit */ 38 #define GS_ADDR_B58_LEN (GS_ADDR_SIZE) * 138 / 100 + 1 39 #define GS_ADDR_PROTO_SIZE (32) /* 256 bit */ 40 #define GS_MAX_SOX_BACKLOG (5) /* Relevant for GS_listen() only */ 41 #define GS_TOKEN_SIZE (16) /* 128 bit */ 42 43 #define GS_TV_TO_USEC(tv) ((uint64_t)(tv)->tv_sec * 1000000 + (tv)->tv_usec) 44 #define GS_TV_TO_MSEC(tv) ((uint64_t)(tv)->tv_sec * 1000 + (tv)->tv_usec/1000) 45 #define GS_TV_DIFF(tv_a, tv_b) (GS_TV_TO_USEC(tv_b) - GS_TV_TO_USEC(tv_a)) 46 #define GS_SEC_TO_USEC(sec) ((uint64_t)(sec) * 1000000) 47 #define GS_MSEC_TO_USEC(ms) ((uint64_t)(ms) * 1000) 48 #define GS_USEC_TO_SEC(usec) ((usec) / 1000000) 49 #define GS_USEC_TO_MSEC(usec) ((usec) / 1000) 50 #define GS_USEC_TO_TV(tv, usec) do { (tv)->tv_sec = (usec) / 1000000; (tv)->tv_usec = (usec) % 1000000; } while(0) 51 52 #define GS_SECRET_MAX_LEN (256 / 8) /* max length in bytes */ 53 #define GS_DFL_CIPHER "SRP-AES-256-CBC-SHA" 54 #define GS_DFL_CIPHER_STRENGTH "4096" 55 56 #include <gsocket/list.h> 57 #include <gsocket/event.h> 58 #include <gsocket/gs-select.h> 59 #include <gsocket/packet.h> 60 #include <gsocket/gs-readline.h> 61 #include <gsocket/buf.h> 62 63 /* ########################### 64 * ### PROTOCOL DEFINITION ### 65 * ########################### 66 */ 67 /* First message from Listening Client (LC) to GS-Network (GN) [server] 68 * LC2GN: Register a GS-Address for listening. 69 */ 70 struct _gs_listen /* 128 bytes */ 71 { 72 uint8_t type; 73 uint8_t version_major; 74 uint8_t version_minor; 75 uint8_t flags; 76 uint8_t reserved1[4]; 77 78 uint8_t reserved2[8]; 79 80 uint8_t token[GS_TOKEN_SIZE]; 81 uint8_t addr[GS_ADDR_PROTO_SIZE]; /* 32 bytes */ 82 uint8_t reserved3[64]; 83 }; 84 85 /* 86 * First message from Connecting Client (CC) to GS-Network (GN) [server] 87 * CC2GN: Connect a listening GS-Address. 88 * CC awaiting _gs_start from GN. 89 */ 90 struct _gs_connect 91 { 92 uint8_t type; 93 uint8_t version_major; 94 uint8_t version_minor; 95 uint8_t flags; 96 97 uint8_t reserved2[28]; 98 99 uint8_t addr[GS_ADDR_PROTO_SIZE]; /* 32 bytes */ 100 uint8_t reserved3[64]; 101 }; 102 #define GS_PKT_PROTO_VERSION_MAJOR (0x01) 103 #define GS_PKT_PROTO_VERSION_MINOR (0x02) 104 105 #define GS_FL_PROTO_WAIT (0x01) /* Wait for LC to connect */ 106 107 /* Client allowed to become a Server if Server does not exist. 108 * Or Server allowed to become a Client if Server already exists. 109 */ 110 #define GS_FL_PROTO_CLIENT_OR_SERVER (0x02) 111 112 /* 113 * all2GN 114 */ 115 struct _gs_ping 116 { 117 uint8_t type; 118 uint8_t reserved[3]; 119 120 uint8_t payload[28]; 121 }; 122 123 /* 124 * GN2all 125 */ 126 struct _gs_pong 127 { 128 uint8_t type; 129 uint8_t reserved[3]; 130 131 uint8_t payload[28]; 132 }; 133 134 /* GN2all: New incoming connection. 135 * GN must not send any further GS messages. 136 */ 137 struct _gs_start 138 { 139 uint8_t type; 140 uint8_t flags; 141 uint8_t reserved[2]; 142 143 uint8_t reserved2[28]; 144 }; 145 #define GS_FL_PROTO_START_SERVER (0x01) /* Act as a Server [ssl] */ 146 #define GS_FL_PROTO_START_CLIENT (0x02) /* Act as a Client [ssl] */ 147 148 /* GN2all: Status (error) 149 */ 150 struct _gs_status 151 { 152 uint8_t type; 153 uint8_t err_type; 154 uint8_t code; 155 uint8_t reserved[1]; 156 157 uint8_t msg[28]; 158 }; 159 160 /* err_type */ 161 #define GS_STATUS_TYPE_WARN (0x01) 162 #define GS_STATUS_TYPE_FATAL (0x02) // Must exit. 163 164 #define GS_STATUS_CODE_BAD_AUTH (0x01) // Auth Token mismatch 165 #define GS_STATUS_CODE_CONNREFUSED (0x02) // No server listening 166 #define GS_STATUS_CODE_IDLE_TIMEOUT (0x03) // Timeout 167 168 /* 169 * all2GN: Accepting incoming connection. 170 * LC/CC must not send any further GS messages. 171 */ 172 struct _gs_accept 173 { 174 uint8_t type; 175 uint8_t reserved[3]; 176 177 uint8_t reserved2[28]; 178 }; 179 180 #define GS_PKT_TYPE_LISTEN (0x01) // LC2GN 181 #define GS_PKT_TYPE_CONNECT (0x02) // CC2GN 182 #define GS_PKT_TYPE_PING (0x03) // all2GN 183 #define GS_PKT_TYPE_PONG (0x04) // GN2all 184 #define GS_PKT_TYPE_START (0x05) // GN2all 185 #define GS_PKT_TYPE_ACCEPT (0x06) // all2GN 186 #define GS_PKT_TYPE_STATUS (0x07) // GN2all 187 188 189 #define GS_MAX_MSG_LEN GS_MAX(sizeof (struct _gs_listen), GS_MAX(sizeof (struct _gs_ping), GS_MAX(sizeof (struct _gs_pong), sizeof (struct _gs_start)))) 190 191 enum gs_ctx_flags_t {GS_CTX_FL_RFD_INTERNAL}; 192 enum gs_flags_t { 193 GS_FL_TCP_CONNECTED = 0x01, // App TCP sockets are connected 194 GSC_FL_NONBLOCKING = 0x02, // Do not Block on socket IO 195 GS_FL_CALLED_NET_CONNECT = 0x04, // GS_connect() already called GS_FL_CALLED_NET_CONNECT 196 GS_FL_IS_CLIENT = 0x08, 197 GS_FL_CALLED_NET_NEW_SOCKET = 0x10, 198 GSC_FL_USE_SRP = 0x20, 199 GSC_FL_CLIENT_OR_SERVER = 0x40, 200 GS_FL_IS_SERVER = 0x80, // A GS-CLient (the first connected) is an SRP-Server 201 GS_FL_AUTO_RECONNECT = 0x100, // GS_accept() to reconnect on GS-NET errors 202 GS_FL_SINGLE_SHOT = 0x200 // single GS_listen(). (for stdin/stdout) 203 }; 204 205 /* 206 * - GS-Network host/port 207 * - Handle TCP sockets (non-blocking) 208 */ 209 typedef struct 210 { 211 int max_sox; 212 fd_set *rfd; 213 fd_set *wfd; 214 fd_set *r; 215 fd_set *w; 216 int gsocket_success_count; /* Successfull connection counter */ 217 GS_SELECT_CTX *gselect_ctx; 218 /* Listening CB and values */ 219 gselect_cb_t func_listen; 220 int cb_val_listen; 221 222 struct timeval *tv_now; 223 char err_buf[1024]; 224 char err_buf2[1024]; 225 226 enum gs_ctx_flags_t flags; // CTX specific flags 227 228 enum gs_flags_t gs_flags; // GS specific flags. Copied to GS on creation. 229 uint32_t flags_proto; 230 231 uint32_t socks_ip; // NBO. Use Socks5 232 uint16_t socks_port; // Socks5 233 uint16_t gs_port; // 7350 or GSOCKET_PORT 234 } GS_CTX; 235 236 237 enum sox_state_t { 238 GS_STATE_SYS_NONE, // We are idle... 239 GS_STATE_SYS_CONNECT, // need call to 'connect()' _again_. 240 GS_STATE_SYS_RECONNECT, // Re-connecting to GS-NET 241 GS_STATE_PKT_LISTEN, // listen_write() did not complete 242 GS_STATE_PKT_PING, // ping_write() did not complete 243 GS_STATE_APP_CONNECTED, // Application is connected. Passingthrough of data (no pkt any longer) 244 GS_STATE_PKT_CONNECT, 245 GS_STATE_PKT_ACCEPT, 246 GS_STATE_SOCKS // TOR 247 }; 248 249 enum sox_flags_t { 250 GS_SOX_FL_AWAITING_PONG, // Waiting for PONG 251 GS_SOX_FL_AWAITING_SOCKS // Waiting for Socks5 (TOR) reply 252 }; 253 254 /* TCP network address may depend on GS_ADDR (load balancing) */ 255 struct gs_sox 256 { 257 int fd; 258 enum sox_state_t state; 259 enum sox_flags_t flags; 260 uint8_t rbuf[GS_MAX_MSG_LEN]; 261 size_t rlen; 262 uint8_t wbuf[GS_MAX_MSG_LEN]; 263 size_t wlen; 264 struct timeval tv_last_data; /* For KeepAlive */ 265 }; 266 267 struct gs_net 268 { 269 uint16_t port; /* NBO */ 270 uint32_t addr; /* IPv4, NBO */ 271 int conn_count; 272 struct gs_sox sox[GS_MAX_SOX_BACKLOG]; 273 int n_sox; /* Number of sox[n] entries */ 274 int fd_accepted; 275 char *hostname; /* xxx.gs.thc.org */ 276 uint64_t tv_connect; // Time connect() was called 277 uint64_t tv_gs_hton; // Time hostname was resolved last. 278 int is_connect_error_warned; // 'Re-connecting...' warning issued 279 }; 280 281 282 typedef struct 283 { 284 uint8_t addr[GS_ADDR_SIZE]; 285 char b58str[GS_ADDR_B58_LEN + 1]; /* Base58 string representation of gs-address + \0-terminated. */ 286 size_t b58sz; /* Base58 size */ 287 } GS_ADDR; 288 289 #ifdef WITH_GSOCKET_SSL 290 enum ssl_state_t { 291 GS_SSL_STATE_ACCEPT, /* Call SSL_accpet() again */ 292 GS_SSL_STATE_CONNECT, /* Call SSL_connect() again */ 293 GS_SSL_STATE_RW, /* Call SSL_read/SSL_write again */ 294 GS_SSL_STATE_SHUTDOWN /* Call SSL_shutdown() again */ 295 }; 296 #endif 297 298 enum gs_rw_state_t { 299 GS_CAN_READ = 0x01, 300 GS_CAN_WRITE = 0x02, 301 GS_CAN_RW = 0x03 302 }; 303 304 /* 305 * A specific GS connection with a single GSOCKET-ID. 306 * There can be multiple connection per GSOCKET-ID (eventually). 307 */ 308 typedef struct 309 { 310 GS_CTX *ctx; 311 GS_ADDR gs_addr; 312 enum gs_flags_t flags; 313 int id; /* ID of this gsocket. Set AFTER conn success */ 314 struct gs_net net; /* fd's for listening tcp_fd */ 315 int fd; /* Only set if this is a 'connected' tcp_fd (not listening socket) */ 316 int64_t bytes_read; 317 int64_t bytes_written; 318 uint64_t ts_net_io; // TimeStamp network I/O 319 struct timeval tv_connected; /* TV when GS entered CONNECTED state */ 320 int read_pending; 321 int write_pending; 322 int is_sent_shutdown; 323 int is_want_shutdown; /* Call GS_shutdown() after SRP completion */ 324 uint8_t token[GS_TOKEN_SIZE]; 325 int eof_count; /* How many EOF received (needed for ssl compat) */ 326 #ifdef WITH_GSOCKET_SSL 327 SSL_CTX *ssl_ctx; 328 SRP_VBASE *srpData; /* Verifier is identical 4 all conns on same GS */ 329 SSL *ssl; 330 enum ssl_state_t ssl_state; 331 char srp_sec[128]; /* SRP Secret */ 332 int ssl_shutdown_count; // Calls to gs_ssl_close 333 #endif 334 } GS; 335 336 337 /* ##################################### 338 * ### GSOCKET FUNCTION DECLARATIONS ### 339 * ##################################### 340 */ 341 342 void GS_library_init(FILE *err_fp, FILE *dout_fp); 343 int GS_CTX_init(GS_CTX *, fd_set *rfd, fd_set *wfd, fd_set *r, fd_set *w, struct timeval *tv_now); 344 void GS_CTX_use_gselect(GS_CTX *ctx, GS_SELECT_CTX *gselect_ctx); 345 int GS_CTX_free(GS_CTX *); 346 GS *GS_new(GS_CTX *ctx, GS_ADDR *addr); /* Connect to GS-Network */ 347 const char *GS_CTX_strerror(GS_CTX *gs_ctx); 348 const char *GS_strerror(GS *gsocket); 349 350 int GS_connect(GS *gsocket); /* Fail if no such GS-ID is listening */ 351 int GS_get_fd(GS *gsocket); 352 int GS_listen(GS *gsocket, int backlog); /* Listen for an incoming GS connection */ 353 void GS_listen_add_gs_select(GS *gs, GS_SELECT_CTX *ctx, gselect_cb_t func, void *arg, int val); 354 GS *GS_accept(GS *gsocket, int *error); /* Wait until client connects by GS-ID and return Unix fileno */ 355 int GS_close(GS *gsocket); /* close() and free() a connected GS */ 356 int GS_shutdown(GS *gsocket); 357 void GS_heartbeat(GS *gsocket); 358 void GS_set_token(GS *gsocket, const void *buf, size_t num); 359 /* Logging */ 360 char *GS_usecstr(char *dst, size_t len, uint64_t usec); 361 char *GS_bytesstr(char *dst, size_t len, int64_t bytes); 362 char *GS_bytesstr_long(char *dst, size_t len, int64_t bytes); 363 const char *GS_logtime(void); 364 365 int GS_CTX_setsockopt(GS_CTX *ctx, int level, const void *opt_value, size_t opt_len); 366 367 #define GS_OPT_SOCKWAIT (0x02) 368 #define GS_OPT_BLOCK (0x04) /* Blocking TCP */ 369 #define GS_OPT_NO_ENCRYPTION (0x08) 370 #define GS_OPT_CLIENT_OR_SERVER (0x10) /* Whoever connects first acts as a Server */ 371 #define GS_OPT_USE_SOCKS (0x20) // Use TOR (Socks5) 372 #define GS_OPT_SINGLESHOT (0x40) 373 374 ssize_t GS_write(GS *gsocket, const void *buf, size_t num); 375 ssize_t GS_read(GS *gsocket, void *buf, size_t num); 376 GS_ADDR *GS_ADDR_bin2addr(GS_ADDR *addr, const void *data, size_t len); 377 GS_ADDR *GS_ADDR_str2addr(GS_ADDR *addr, const char *str); 378 GS_ADDR *GS_ADDR_ipport2addr(GS_ADDR *addr, uint32_t ip, uint16_t port); 379 uint32_t GS_hton(const char *hostname); 380 void GS_SELECT_FD_SET_W(GS *gs); 381 382 void GS_daemonize(FILE *logfp); 383 uint64_t GS_usec(void); 384 void GS_format_bps(char *dst, size_t size, int64_t bytes, const char *suffix); 385 char *GS_getpidwd(pid_t pid); 386 387 const char *GS_gen_secret(void); 388 const char *GS_user_secret(GS_CTX *ctx, const char *file, const char *sec_str); 389 390 #ifdef WITH_GSOCKET_SSL 391 const char *GS_SSL_strerror(int err); 392 void GS_srp_setpassword(GS *gsocket, const char *pwd); 393 const char *GS_get_cipher(GS *gs); 394 int GS_get_cipher_strength(GS *gs); 395 int GS_is_server(GS *gs); 396 #endif /* !WITH_GSOCKET_SSL */ 397 398 #endif /* !__LIBGSOCKET_H__ */ 399