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