1 /* ncdc - NCurses Direct Connect client
2
3 Copyright (c) 2011-2019 Yoran Heling
4
5 Permission is hereby granted, free of charge, to any person obtaining
6 a copy of this software and associated documentation files (the
7 "Software"), to deal in the Software without restriction, including
8 without limitation the rights to use, copy, modify, merge, publish,
9 distribute, sublicense, and/or sell copies of the Software, and to
10 permit persons to whom the Software is furnished to do so, subject to
11 the following conditions:
12
13 The above copyright notice and this permission notice shall be included
14 in all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24 */
25
26
27 #include "ncdc.h"
28 #include "net.h"
29
30
31 // global network stats
32 ratecalc_t net_in, net_out;
33
34 #define NET_RECV_SIZE ( 8*1024)
35 #define NET_MAX_RBUF (1024*1024)
36 #define NET_TRANS_BUF ( 32*1024)
37
38
39 #if INTERFACE
40
41 // actions that can fail
42 #define NETERR_CONN 0
43 #define NETERR_RECV 1
44 #define NETERR_SEND 2
45 #define NETERR_TIMEOUT 3
46
47 typedef struct net_t net_t;
48
49 // ALPN protocols
50 #define ALPN_DEFAULT 0 // default, no ALPN
51 #define ALPN_NMDC 1
52 #define ALPN_ADC 2
53
54 #endif
55
56
57 // Network states
58 #define NETST_IDL 0 // idle, disconnected
59 #define NETST_DNS 1 // resolving DNS
60 #define NETST_CON 2 // connecting
61 #define NETST_ASY 3 // connected, handling async messages
62 #define NETST_SYN 4 // connected, handling a synchronous send/receive
63 #define NETST_DIS 5 // disconnecting (cleanly)
64
65 typedef struct dnscon_t dnscon_t;
66 typedef struct synfer_t synfer_t;
67
68 struct net_t {
69 int state;
70
71 ratecalc_t rate_in;
72 ratecalc_t rate_out;
73
74 dnscon_t *dnscon; // state DNS,CON. Setting ->net to NULL 'cancels' DNS resolving.
75 int sock; // state CON,ASY,SYN,DIS
76 int socksrc; // state CON,ASY,DIS. Glib event source on 'sock'.
77 char addr[56]; // state ASY,SYN,DIS, ip:port
78 char laddr[40]; // state ASY,SYN,DIS, ip only
79
80 gnutls_session_t tls; // state ASY,SYN,DIS (only if tls is enabled)
81 void (*cb_handshake)(net_t *, const char *, int); // state ASY, called after complete handshake.
82 void (*cb_shutdown)(net_t *); // state DIS, called after complete disconnect.
83
84 gboolean v6 : 4; // state ASY,SYN, whether we're on IPv6
85 gboolean tls_handshake : 4; // state ASY, whether we're handshaking.
86 gboolean shutdown_closed : 4; // state DIS, whether shutdown() has been called on the socket.
87 gboolean writing : 4; // state ASY. Whether 'socksrc' is write poll event.
88 gboolean wantwrite : 4; // state ASY. Whether we want a write on sock.
89
90 GString *tlsrbuf; // state ASY. Temporary buffer for data read before switching to TLS. (To be fed to GnuTLS)
91 GString *rbuf; // state ASY. Read buffer.
92 GString *wbuf; // state ASY. Write buffer.
93
94 // Called when an error has occured. Second argument is NETERR_*, third a
95 // string representing the error.
96 void (*cb_err)(net_t *, int, const char *);
97
98 // Read buffer handling. Callback will be called only once. (State ASY)
99 void (*rd_cb)(net_t *, char *, int len);
100 gboolean rd_msg : 1; // TRUE: message, rd_dat=EOM; FALSE=bytes, rd_dat=count
101 gboolean rd_consume : 1;
102 int rd_dat;
103
104 // Synchronous file transfers (SYN state) When set in the ASY state, it means
105 // that buffers should be flushed before switching to the SYN state.
106 synfer_t *syn;
107
108 // some pointer for use by the user
109 void *handle;
110 // reference counter
111 int ref;
112
113 // Timeout handling
114 int timeout_src;
115 time_t timeout_last;
116 const char *timeout_msg;
117 };
118
119
120
121
122
net_sock_bind(int af,int sock,char * laddr)123 static int net_sock_bind(int af, int sock, char *laddr) {
124 if(!laddr)
125 return 0;
126
127 if(af == AF_INET) {
128 struct in_addr a = var_parse_ip4(laddr);
129 return bind(sock, ip4_sockaddr(a, 0), sizeof(struct sockaddr_in));
130 }
131 if(af == AF_INET6) {
132 struct in6_addr a = var_parse_ip6(laddr);
133 return bind(sock, ip6_sockaddr(a, 0), sizeof(struct sockaddr_in6));
134 }
135 g_return_val_if_reached(0);
136 }
137
138
139 // Low-level recv/send wrappers
140
tls_pull(gnutls_transport_ptr_t dat,void * buf,size_t len)141 static ssize_t tls_pull(gnutls_transport_ptr_t dat, void *buf, size_t len) {
142 net_t *n = dat;
143
144 // Special buffer to allow passing read data back to the GnuTLS stream.
145 if(n->tlsrbuf) {
146 memcpy(buf, n->tlsrbuf->str, MIN(len, n->tlsrbuf->len));
147 if(len >= n->tlsrbuf->len) {
148 g_string_free(n->tlsrbuf, TRUE);
149 n->tlsrbuf = NULL;
150 } else
151 g_string_erase(n->tlsrbuf, 0, len);
152 return len;
153 }
154
155 // Otherwise, get the data directly from the network.
156 int r = recv(n->sock, buf, len, 0);
157 if(r < 0)
158 gnutls_transport_set_errno(n->tls, errno == EWOULDBLOCK ? EAGAIN : errno);
159 else {
160 ratecalc_add(&net_in, r);
161 ratecalc_add(&n->rate_in, r);
162 }
163 return r;
164 }
165
166 // Behaves similarly to a normal recv(), but writes a readable error message to
167 // *err. If the error is temporary (e.g. EAGAIN), returns -1 but with *err=NULL.
168 // Does not return 0, disconnect is considered a fatal error.
low_recv(net_t * n,char * buf,int len,const char ** err)169 static int low_recv(net_t *n, char *buf, int len, const char **err) {
170 int r = n->tls
171 ? gnutls_record_recv(n->tls, buf, len)
172 : recv(n->sock, buf, len, 0);
173
174 if(r < 0 && (n->tls ? !gnutls_error_is_fatal(r) : errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)) {
175 *err = NULL;
176 return -1;
177 }
178
179 if(n->state != NETST_DIS)
180 time(&n->timeout_last);
181 if(r <= 0) {
182 *err = !r || !n->tls ? g_strerror(!r ? ECONNRESET : errno) : gnutls_strerror(r);
183 return -1;
184 }
185
186 if(!n->tls) {
187 ratecalc_add(&net_in, r);
188 ratecalc_add(&n->rate_in, r);
189 }
190 return r;
191 }
192
193
tls_push(gnutls_transport_ptr_t dat,const void * buf,size_t len)194 static ssize_t tls_push(gnutls_transport_ptr_t dat, const void *buf, size_t len) {
195 net_t *n = dat;
196 int r = send(n->sock, buf, len, 0);
197 if(r < 0)
198 gnutls_transport_set_errno(n->tls, errno == EWOULDBLOCK ? EAGAIN : errno);
199 else {
200 ratecalc_add(&net_out, r);
201 ratecalc_add(&n->rate_out, r);
202 }
203 return r;
204 }
205
206
207 // Same as low_recv(), but for send().
low_send(net_t * n,const char * buf,int len,const char ** err)208 static int low_send(net_t *n, const char *buf, int len, const char **err) {
209 int r = n->tls
210 ? gnutls_record_send(n->tls, buf, len)
211 : send(n->sock, buf, len, 0);
212
213 // Note: r == 0 is seen as a temporary error
214 if(!r || (r < 0 && (n->tls ? !gnutls_error_is_fatal(r) : errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN))) {
215 *err = NULL;
216 return -1;
217 }
218
219 if(n->state != NETST_DIS)
220 time(&n->timeout_last);
221 if(r < 0) {
222 *err = n->tls ? gnutls_strerror(r) : g_strerror(errno);
223 return -1;
224 }
225
226 if(!n->tls) {
227 ratecalc_add(&net_out, r);
228 ratecalc_add(&n->rate_out, r);
229 }
230 return r;
231 }
232
233
234
235
236
237
238 // Synchronous file transfers
239
240 static void asy_setuppoll(net_t *n);
241
242 struct synfer_t {
243 GStaticMutex lock; // protects n->left, any data used within the low_* functions and, in the case of a disconnect, net->sock and net->tls.
244 net_t *net;
245 guint64 left; // The transfer thread itself does not need the lock to read this value, only to write. (It is the only writer)
246 int fd; // for uploads
247 int cancel; // set to 1 to cancel transfer
248 int can[2]; // close() this pipe (can[1]) to cancel the transfer
249 gboolean upl : 1; // whether this is an upload or download
250 gboolean flush : 1; // for uploads
251 char *err;
252 void *ctx; // for downloads
253 void (*cb_downdone)(net_t *, void *);
254 gboolean (*cb_downdata)(void *, const char *, int);
255 void (*cb_upldone)(net_t *);
256 };
257
258 static GThreadPool *syn_pool = NULL;
259
260
syn_new(net_t * n,gboolean upl,guint64 len)261 static void syn_new(net_t *n, gboolean upl, guint64 len) {
262 n->syn = g_slice_new0(synfer_t);
263 n->syn->left = len;
264 n->syn->net = n;
265 n->syn->upl = upl;
266
267 g_static_mutex_init(&n->syn->lock);
268 if(pipe(n->syn->can) < 0) {
269 g_critical("pipe() failed: %s", g_strerror(errno));
270 g_return_if_reached();
271 }
272 net_ref(n);
273 }
274
275
syn_free(synfer_t * s)276 static void syn_free(synfer_t *s) {
277 net_unref(s->net);
278 close(s->can[0]);
279 if(s->fd)
280 close(s->fd);
281 if(s->cb_downdone)
282 s->cb_downdone(NULL, s->ctx);
283 g_free(s->err);
284 g_slice_free(synfer_t, s);
285 }
286
287
syn_cancel(net_t * n)288 static void syn_cancel(net_t *n) {
289 n->syn->cancel = 1;
290 close(n->syn->can[1]);
291 n->syn = NULL;
292 }
293
294
295 // Called as an idle function from syn_thread
syn_done(gpointer dat)296 static gboolean syn_done(gpointer dat) {
297 synfer_t *s = dat;
298 net_t *n = s->net;
299
300 // Cancelled
301 if(s->cancel) {
302 syn_free(s);
303 return FALSE;
304 }
305
306 // Error
307 if(s->err) {
308 g_debug("%s: Syn: %s", net_remoteaddr(n), s->err);
309 syn_cancel(n);
310 n->cb_err(n, s->upl ? NETERR_SEND : NETERR_RECV, s->err);
311 syn_free(s);
312 return FALSE;
313 }
314
315 syn_cancel(n);
316 n->state = NETST_ASY;
317 n->wantwrite = FALSE;
318 asy_setuppoll(n);
319 if(s->cb_upldone)
320 s->cb_upldone(n);
321 if(s->cb_downdone) {
322 s->cb_downdone(n, s->ctx);
323 s->cb_downdone = NULL;
324 }
325 syn_free(s);
326 return FALSE;
327 }
328
329
330 // Does two things: Waits some time to ensure that we are allowed to burst with
331 // the rate limiting thing, and then waits for the socket to become
332 // readable/writable. Returns the number of bytes that may be read/written on
333 // success, 0 if the operation has been cancelled.
syn_wait(synfer_t * s,int sock,gboolean write)334 static int syn_wait(synfer_t *s, int sock, gboolean write) {
335 // Lock to get the socket fd
336 g_static_mutex_lock(&s->lock);
337 GPollFD fds[2] = {};
338 fds[0].fd = s->can[0];
339 fds[0].events = G_IO_IN;
340 fds[1].fd = sock;
341 fds[1].events = write ? G_IO_OUT : G_IO_IN;
342 g_static_mutex_unlock(&s->lock);
343
344 // Poll for burst
345 int b = 0;
346 int r = 0;
347 while(r <= 0 && (b = ratecalc_burst(write ? &s->net->rate_out : &s->net->rate_in)) <= 0) {
348 // Wake up 4 times per second. If the resource is CPU or HDD I/O
349 // constrained, then this means that at most 1/4th of the possible usage
350 // time is "thrown away". I don't expect this to be much of an issue,
351 // however.
352 r = g_poll(fds, 1, 250); // only poll for the cancel fd here.
353 g_return_val_if_fail(r >= 0 || errno == EINTR, 0);
354 }
355 if(r)
356 return 0;
357
358 // Now poll for read/writability of the socket.
359 do
360 r = g_poll(fds, 2, -1);
361 while(r < 0 && errno == EINTR);
362
363 if(fds[0].revents)
364 return 0;
365 return b;
366 }
367
368
369 #ifdef HAVE_SENDFILE
370
syn_upload_sendfile(synfer_t * s,int sock,fadv_t * adv)371 static void syn_upload_sendfile(synfer_t *s, int sock, fadv_t *adv) {
372 off_t off = lseek(s->fd, 0, SEEK_CUR);
373 if(off == (off_t)-1) {
374 s->err = g_strdup(g_strerror(errno));
375 return;
376 }
377
378 while(s->left > 0 && !s->err && !s->cancel) {
379 off_t oldoff = off;
380 int b = syn_wait(s, sock, TRUE);
381 if(b <= 0)
382 return;
383
384 // No need for a lock here, we're not using the TLS session and socket fd's
385 // are thread-safe. To some extent at least.
386 #ifdef HAVE_LINUX_SENDFILE
387 // XXX: On 32bit Linux with musl, sendfile() may fail with EOVERFLOW when
388 // an offset argument is given and is larger than UINT32_MAX, so we're
389 // passing NULL instead to use the fd's internal file offset.
390 ssize_t r = sendfile(sock, s->fd, NULL, MIN(b, s->left));
391 #elif HAVE_BSD_SENDFILE
392 off_t len = 0;
393 gint64 r = sendfile(s->fd, sock, off, (size_t)MIN(b, s->left), NULL, &len, 0);
394 // a partial write results in an EAGAIN error on BSD, even though this isn't
395 // really an error condition at all.
396 if(r != -1 || (r == -1 && errno == EAGAIN))
397 r = len;
398 #endif
399
400 if(r >= 0) {
401 if(s->flush)
402 fadv_purge(adv, r);
403 off = oldoff + r;
404 // This bypasses the low_send() function, so manually add it to the
405 // ratecalc thing and update timeout_last.
406 ratecalc_add(&net_out, r);
407 ratecalc_add(&s->net->rate_out, r);
408 g_static_mutex_lock(&s->lock);
409 time(&s->net->timeout_last);
410 s->left -= r;
411 g_static_mutex_unlock(&s->lock);
412 continue;
413 } else if(errno == EAGAIN || errno == EINTR) {
414 continue;
415 } else if(errno == ENOTSUP || errno == ENOSYS || errno == EINVAL || errno == EOVERFLOW) {
416 // Don't set s->err here, let the fallback handle the rest
417 g_message("sendfile() failed with `%s', using fallback.", g_strerror(errno));
418 // The fallback code continues from the fd position, so make sure to
419 // update it in case (FreeBSD's) sendfile() didn't do so.
420 if(lseek(s->fd, off, SEEK_SET) == (off_t)-1) {
421 g_message("Can't switch to fallback, seek failed: %d (%s)", errno, g_strerror(errno));
422 s->err = g_strdup(g_strerror(errno));
423 }
424 return;
425 } else {
426 if(errno != EPIPE && errno != ECONNRESET)
427 g_message("sendfile() returned an unknown error: %d (%s)", errno, g_strerror(errno));
428 s->err = g_strdup(g_strerror(errno));
429 return;
430 }
431 }
432 }
433
434 #endif
435
436
syn_upload_buf(synfer_t * s,int sock,fadv_t * adv)437 static void syn_upload_buf(synfer_t *s, int sock, fadv_t *adv) {
438 char *buf = g_malloc(NET_TRANS_BUF);
439
440 while(s->left > 0 && !s->err && !s->cancel) {
441 int rd = read(s->fd, buf, MIN(NET_TRANS_BUF, s->left));
442 if(rd <= 0) {
443 s->err = g_strdup(g_strerror(errno));
444 goto done;
445 }
446 if(s->flush)
447 fadv_purge(adv, rd);
448
449 char *p = buf;
450 while(rd > 0) {
451 int b = syn_wait(s, sock, TRUE);
452 if(b <= 0)
453 goto done;
454
455 g_static_mutex_lock(&s->lock);
456 const char *err = NULL;
457 int wr = s->cancel || !s->net->sock ? 0 : low_send(s->net, p, MIN(rd, b), &err);
458 // successful write
459 if(wr > 0) {
460 p += wr;
461 s->left -= wr;
462 rd -= wr;
463 }
464 g_static_mutex_unlock(&s->lock);
465
466 if(!wr) // cancelled
467 goto done;
468 if(wr < 0 && !err) // would block
469 continue;
470 if(wr < 0) { // actual error
471 s->err = g_strdup(err);
472 goto done;
473 }
474 }
475 }
476
477 done:
478 g_free(buf);
479 }
480
481
syn_download(synfer_t * s,int sock)482 static void syn_download(synfer_t *s, int sock) {
483 char *buf = g_malloc(NET_TRANS_BUF);
484
485 while(s->left > 0 && !s->err && !s->cancel) {
486 int b = syn_wait(s, sock, FALSE);
487 if(b <= 0)
488 break;
489
490 g_static_mutex_lock(&s->lock);
491 const char *err = NULL;
492 int r = s->cancel || !s->net->sock ? 0 : low_recv(s->net, buf, MIN(NET_TRANS_BUF, s->left), &err);
493 if(r > 0)
494 s->left -= r;
495 g_static_mutex_unlock(&s->lock);
496
497 if(!r)
498 break;
499 if(r < 0 && !err)
500 continue;
501 if(r < 0) {
502 s->err = g_strdup(err);
503 break;
504 }
505
506 if(!s->cb_downdata(s->ctx, buf, r)) {
507 s->err = g_strdup("Operation cancelled");
508 break;
509 }
510 }
511
512 g_free(buf);
513 }
514
515
syn_thread(gpointer dat,gpointer udat)516 static void syn_thread(gpointer dat, gpointer udat) {
517 synfer_t *s = dat;
518
519 // Make a copy of sock to make sure it doesn't disappear on us.
520 // (Still need to obtain the lock to make use of it).
521 g_static_mutex_lock(&s->lock);
522 int sock = s->net->sock;
523 gboolean tls = !!s->net->tls;
524 g_static_mutex_unlock(&s->lock);
525
526 if(sock && !s->cancel && s->upl) {
527 fadv_t adv;
528 if(s->flush)
529 fadv_init(&adv, s->fd, lseek(s->fd, 0, SEEK_CUR), VAR_FFC_UPLOAD);
530
531 #ifdef HAVE_SENDFILE
532 if(!tls && var_get_bool(0, VAR_sendfile))
533 syn_upload_sendfile(s, sock, &adv);
534 #endif
535 if(s->left > 0 && !s->err && !s->cancel)
536 syn_upload_buf(s, sock, &adv);
537
538 if(s->flush)
539 fadv_close(&adv);
540 }
541
542 if(sock && !s->cancel && !s->upl)
543 syn_download(s, sock);
544
545 g_idle_add(syn_done, s);
546 }
547
548
syn_start(net_t * n)549 static void syn_start(net_t *n) {
550 n->state = NETST_SYN;
551 // We're coming from the ASY state, so make sure to clean this up.
552 if(n->socksrc) {
553 g_source_remove(n->socksrc);
554 n->socksrc = 0;
555 }
556 g_thread_pool_push(syn_pool, n->syn, NULL);
557 }
558
559
net_left(net_t * n)560 guint64 net_left(net_t *n) {
561 if(!n->syn)
562 return 0;
563 g_static_mutex_lock(&n->syn->lock);
564 guint64 r = n->syn->left;
565 g_static_mutex_unlock(&n->syn->lock);
566 return r;
567 }
568
569
570
571
572
573
574
575 // Asynchronous TLS handshaking & message handling & disconnecting
576
577 static gboolean handle_timer(gpointer dat);
578
579 // Checks rbuf against any queued read events and handles those. (Can be called
580 // as a glib idle function)
asy_handlerbuf(gpointer dat)581 static gboolean asy_handlerbuf(gpointer dat) {
582 net_t *n = dat;
583 // The callbacks itself may in turn call other net_* functions, and thus
584 // immediately queue another read action. Hence the while loop. Note that no
585 // net_* function that remains in the ASY state is allowed to modify rbuf,
586 // otherwise we need to make a copy of rbuf before passing it to the
587 // callback.
588 net_ref(n);
589 while(n->state == NETST_ASY && n->rbuf->len && n->rd_cb && !n->syn) {
590 gboolean msg = n->rd_msg;
591 gboolean consume = n->rd_consume;
592 int dat = n->rd_dat;
593 void(*cb)(net_t *, char *, int) = n->rd_cb;
594
595 char *end = msg
596 ? memchr(n->rbuf->str, dat, n->rbuf->len)
597 : n->rbuf->len >= dat ? n->rbuf->str + dat : NULL;
598 if(!end)
599 break;
600 n->rd_cb = NULL;
601 if(msg) {
602 *end = 0;
603 if(consume)
604 g_debug("%s< %s%c", net_remoteaddr(n), n->rbuf->str, dat != '\n' ? dat : ' ');
605 }
606 cb(n, n->rbuf->str, end - n->rbuf->str);
607 if(n->state == NETST_ASY || n->state == NETST_SYN || n->state == NETST_DIS) {
608 if(consume)
609 g_string_erase(n->rbuf, 0, end - n->rbuf->str + (msg ? 1 : 0));
610 else if(msg)
611 *end = dat;
612 }
613 }
614
615 // Handle recvfile
616 if(n->syn && n->state == NETST_ASY && !n->syn->upl) {
617 synfer_t *s = n->syn;
618 if(n->rbuf->len) {
619 int w = MIN(n->rbuf->len, s->left);
620 s->left -= w;
621 s->cb_downdata(s->ctx, n->rbuf->str, w);
622 g_string_erase(n->rbuf, 0, w);
623 }
624 if(s->left)
625 syn_start(n);
626 else {
627 s->cb_downdone(n, s->ctx);
628 s->cb_downdone = NULL;
629 syn_cancel(n);
630 syn_free(s);
631 }
632 }
633
634 net_unref(n);
635 return FALSE;
636 }
637
638
639 // Tries a read. Returns FALSE if there was an error other than "please try
640 // again later".
asy_read(net_t * n)641 static gboolean asy_read(net_t *n) {
642 // Make sure we have enough buffer space
643 if(n->rbuf->allocated_len < NET_MAX_RBUF && n->rbuf->allocated_len - n->rbuf->len < NET_RECV_SIZE) {
644 gsize oldlen = n->rbuf->len;
645 g_string_set_size(n->rbuf, MIN(NET_MAX_RBUF, n->rbuf->len+NET_RECV_SIZE));
646 n->rbuf->len = oldlen;
647 }
648 int len = n->rbuf->allocated_len - n->rbuf->len - 1;
649 if(len <= 10) { // Some arbitrary low number.
650 g_debug("%s: Read buffer full", net_remoteaddr(n));
651 n->cb_err(n, NETERR_RECV, "Read buffer full");
652 return FALSE;
653 }
654
655 const char *err = NULL;
656 int r = low_recv(n, n->rbuf->str + n->rbuf->len, len, &err);
657 if(r < 0 && !err)
658 return TRUE;
659
660 // Handle error and disconnect
661 if(r < 0) {
662 g_debug("%s: %s", net_remoteaddr(n), err);
663 n->cb_err(n, NETERR_RECV, err);
664 return FALSE;
665 }
666
667 // Otherwise, update buffer info
668 g_return_val_if_fail(n->rbuf->len + r < n->rbuf->allocated_len, FALSE);
669 n->rbuf->len += r;
670 n->rbuf->str[n->rbuf->len] = 0;
671 net_ref(n);
672 asy_handlerbuf(n);
673 gboolean ret = n->state == NETST_ASY;
674 net_unref(n);
675 return ret;
676 }
677
678
dis_shutdown(net_t * n)679 static gboolean dis_shutdown(net_t *n) {
680 // Shutdown TLS
681 if(n->tls) {
682 int r = gnutls_bye(n->tls, GNUTLS_SHUT_RDWR);
683 if(r == 0) {
684 gnutls_deinit(n->tls);
685 n->tls = NULL;
686 } else if(r < 0 && !gnutls_error_is_fatal(r)) {
687 if(gnutls_record_get_direction(n->tls))
688 n->wantwrite = TRUE;
689 return TRUE;
690 } else {
691 char *e = g_strdup_printf("Shutdown error: %s", gnutls_strerror(r));
692 g_debug("%s: %s", net_remoteaddr(n), e);
693 n->cb_err(n, NETERR_RECV, e);
694 g_free(e);
695 return FALSE;
696 }
697 }
698
699 // Shutdown socket
700 if(!n->tls && !n->shutdown_closed) {
701 shutdown(n->sock, SHUT_WR);
702 n->shutdown_closed = TRUE;
703 }
704
705 // Wait for ACK (discard anything we read)
706 if(!n->tls) {
707 char buf[10];
708 int r = recv(n->sock, buf, sizeof(buf), 0);
709 if(r < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
710 return TRUE;
711 if(r < 0) {
712 g_debug("%s: %s", net_remoteaddr(n), g_strerror(errno));
713 n->cb_err(n, NETERR_RECV, g_strerror(errno));
714 return FALSE;
715 }
716 if(r == 0) {
717 if(n->cb_shutdown)
718 n->cb_shutdown(n);
719 net_disconnect(n); // still do a force disconnect to clean up stuff and go to IDLE state
720 }
721 }
722 return FALSE;
723 }
724
725
asy_write(net_t * n)726 static gboolean asy_write(net_t *n) {
727 if(!n->wbuf->len)
728 return TRUE;
729
730 const char *err = NULL;
731 int r = low_send(n, n->wbuf->str, n->wbuf->len, &err);
732 if(r < 0 && !err) {
733 n->wantwrite = TRUE;
734 return TRUE;
735 }
736
737 // Handle error
738 if(r < 0) {
739 char *e = g_strdup_printf("Write error: %s", err);
740 g_debug("%s: %s", net_remoteaddr(n), e);
741 n->cb_err(n, NETERR_SEND, e);
742 g_free(e);
743 return FALSE;
744 }
745
746 g_string_erase(n->wbuf, 0, r);
747
748 if(!n->wbuf->len) {
749 if(n->syn && n->syn->upl) {
750 syn_start(n);
751 return FALSE;
752 }
753 if(n->state == NETST_DIS)
754 return dis_shutdown(n);
755 }
756
757 n->wantwrite = !!n->wbuf->len;
758 return TRUE;
759 }
760
asy_handshake(net_t * n)761 static gboolean asy_handshake(net_t *n) {
762 if(!n->tls_handshake)
763 return TRUE;
764
765 int r = gnutls_handshake(n->tls);
766
767 if(!r) { // Successful handshake
768 unsigned int len;
769 char kpr[32] = {};
770 char kpf[53] = {};
771 const gnutls_datum_t *certs = gnutls_certificate_get_peers(n->tls, &len);
772 if(certs && len >= 1) {
773 certificate_sha256(*certs, kpr);
774 base32_encode_dat(kpr, kpf, 32);
775 }
776 g_debug("%s: TLS Handshake successful, KP=SHA256/%s", net_remoteaddr(n), kpf);
777 n->tls_handshake = FALSE;
778 gboolean ret = TRUE;
779
780 int alpn_selected = ALPN_DEFAULT;
781
782 #if GNUTLS_VERSION_NUMBER >= 0x030200
783 gnutls_datum_t neg;
784 if(gnutls_alpn_get_selected_protocol(n->tls, &neg) == GNUTLS_E_SUCCESS) {
785 g_debug("%s: ALPN negotiated: %.*s", net_remoteaddr(n), (int)neg.size, neg.data);
786 if (neg.size == 3 && !memcmp(neg.data, "adc", neg.size)) {
787 alpn_selected = ALPN_ADC;
788 } else if (neg.size == 4 && !memcmp(neg.data, "nmdc", neg.size)) {
789 alpn_selected = ALPN_NMDC;
790 }
791 }
792 #endif
793
794 if(n->cb_handshake) {
795 net_ref(n);
796 n->cb_handshake(n, *kpf ? kpr : NULL, alpn_selected);
797 n->cb_handshake = NULL;
798 ret = n->state == NETST_ASY;
799 net_unref(n);
800 }
801 if(ret && n->syn) {
802 syn_start(n);
803 return FALSE;
804 }
805 return ret;
806
807 } else if(gnutls_error_is_fatal(r)) { // Error
808 char *e = g_strdup_printf("TLS error: %s", gnutls_strerror(r));
809 g_debug("%s: %s", net_remoteaddr(n), e);
810 n->cb_err(n, NETERR_RECV, e);
811 g_free(e);
812 return FALSE;
813 }
814
815 if(gnutls_record_get_direction(n->tls))
816 n->wantwrite = TRUE;
817
818 return TRUE;
819 }
820
821
asy_pollresult(gpointer dat)822 static gboolean asy_pollresult(gpointer dat) {
823 net_t *n = dat;
824 n->socksrc = 0;
825 n->wantwrite = FALSE;
826
827 // Shutdown
828 if(n->state == NETST_DIS) {
829 if(dis_shutdown(n))
830 asy_setuppoll(n);
831 return FALSE;
832 }
833
834 // Handshake
835 if(n->tls_handshake && !asy_handshake(n))
836 return FALSE;
837
838 // Fill rbuf
839 if(!n->tls_handshake && !asy_read(n))
840 return FALSE;
841
842 // Flush wbuf
843 if(!n->tls_handshake && !asy_write(n))
844 return FALSE;
845
846 asy_setuppoll(n);
847 return FALSE;
848 }
849
850
asy_setuppoll(net_t * n)851 static void asy_setuppoll(net_t *n) {
852 // If we already have the right poll source active, ignore this.
853 if(n->socksrc && (!n->wantwrite || n->writing))
854 return;
855
856 if(n->socksrc)
857 g_source_remove(n->socksrc);
858
859 n->writing = n->wantwrite;
860 GSource *src = fdsrc_new(n->sock, G_IO_IN | (n->writing ? G_IO_OUT : 0));
861 g_source_set_callback(src, asy_pollresult, n, NULL);
862 n->socksrc = g_source_attach(src, NULL);
863 g_source_unref(src);
864 }
865
866
asy_setupread(net_t * n,gboolean msg,gboolean consume,int dat,void (* cb)(net_t *,char *,int))867 static void asy_setupread(net_t *n, gboolean msg, gboolean consume, int dat, void(*cb)(net_t *, char *, int)) {
868 g_return_if_fail(n->state == NETST_ASY);
869 n->rd_msg = msg;
870 n->rd_consume = consume;
871 n->rd_dat = dat;
872 n->rd_cb = cb;
873 g_idle_add(asy_handlerbuf, n);
874 }
875
876
877 // Will run the specified callback once a full message has been received. A
878 // "message" meaning any bytes before reading the EOM character. The EOM
879 // character is not passed to the callback.
880 // Only a single net_(read|peek) may be active at a single time.
net_readmsg(net_t * n,unsigned char eom,void (* cb)(net_t *,char *,int))881 void net_readmsg(net_t *n, unsigned char eom, void(*cb)(net_t *, char *, int)) {
882 asy_setupread(n, TRUE, TRUE, eom, cb);
883 }
884
885
net_readbytes(net_t * n,int bytes,void (* cb)(net_t *,char *,int))886 void net_readbytes(net_t *n, int bytes, void(*cb)(net_t *, char *, int)) {
887 asy_setupread(n, FALSE, TRUE, bytes, cb);
888 }
889
890
891 // Will run the specified callback once at least the specified number of bytes
892 // are in the buffer. The data will remain in the buffer after the callback has
893 // run.
net_peekbytes(net_t * n,int bytes,void (* cb)(net_t *,char *,int))894 void net_peekbytes(net_t *n, int bytes, void(*cb)(net_t *, char *, int)) {
895 asy_setupread(n, FALSE, FALSE, bytes, cb);
896 }
897
898
899 // Similar to net_readbytes(), but will call the data() callback for every read
900 // from the network, this callback may be run from another thread. When done,
901 // the done() callback will be run in the main thread.
net_recvfile(net_t * n,guint64 len,gboolean (* data)(void *,const char *,int),void (* done)(net_t *,void *),void * ctx)902 void net_recvfile(net_t *n, guint64 len, gboolean(*data)(void *, const char *, int), void(*done)(net_t *, void *), void *ctx) {
903 g_return_if_fail(n->state == NETST_ASY);
904 syn_new(n, FALSE, len);
905 n->syn->cb_downdata = data;
906 n->syn->cb_downdone = done;
907 n->syn->ctx = ctx;
908 n->rd_cb = NULL;
909 g_idle_add(asy_handlerbuf, n);
910 }
911
912
913 #define flush if(n->tls_handshake || asy_write(n)) asy_setuppoll(n)
914
915 // This is often used to write a raw byte strings, so is not logged for debugging.
net_write(net_t * n,const char * buf,int len)916 void net_write(net_t *n, const char *buf, int len) {
917 if(n->state != NETST_ASY || n->syn)
918 g_warning("%s: Write in incorrect state.", net_remoteaddr(n));
919 else {
920 g_string_append_len(n->wbuf, buf, len);
921 flush;
922 }
923 }
924
925
926 // Logs the write for debugging. Does not log a trailing newline if there is one.
asy_debugwrite(net_t * n,int oldlen)927 static void asy_debugwrite(net_t *n, int oldlen) {
928 if(n->wbuf->len && n->wbuf->len > oldlen) {
929 int len = n->wbuf->len-oldlen;
930 if(n->wbuf->str[n->wbuf->len-1] == '\n')
931 len--;
932 g_debug("%s> %.*s", net_remoteaddr(n), len, n->wbuf->str+oldlen);
933 }
934 }
935
936
net_writestr(net_t * n,const char * msg)937 void net_writestr(net_t *n, const char *msg) {
938 if(n->state != NETST_ASY || n->syn)
939 g_warning("%s: Writestr in incorrect state: %s", net_remoteaddr(n), msg);
940 else {
941 int old = n->wbuf->len;
942 g_string_append(n->wbuf, msg);
943 asy_debugwrite(n, old);
944 flush;
945 }
946 }
947
948
net_writef(net_t * n,const char * fmt,...)949 void net_writef(net_t *n, const char *fmt, ...) {
950 if(n->state != NETST_ASY || n->syn)
951 g_warning("%s: Writef in incorrect state: %s", net_remoteaddr(n), fmt);
952 else {
953 int old = n->wbuf->len;
954 va_list va;
955 va_start(va, fmt);
956 g_string_append_vprintf(n->wbuf, fmt, va);
957 va_end(va);
958 asy_debugwrite(n, old);
959 flush;
960 }
961 }
962
963 #undef flush
964
965
966 // Switches to the SYN state when the write buffer has been flushed. fd will be
967 // close()'d when done. cb() will be called in the main thread.
net_sendfile(net_t * n,int fd,guint64 len,gboolean flush,void (* cb)(net_t *))968 void net_sendfile(net_t *n, int fd, guint64 len, gboolean flush, void (*cb)(net_t *)) {
969 g_return_if_fail(n->state == NETST_ASY && !n->syn);
970 syn_new(n, TRUE, len);
971 n->syn->flush = flush;
972 n->syn->cb_upldone = cb;
973 n->syn->fd = fd;
974 if(!n->wbuf->len)
975 syn_start(n);
976 }
977
978
979 // Clean and orderly shutdown. Callback is called when done (unless there was
980 // some error). Only supported in the ASY state.
net_shutdown(net_t * n,void (* cb)(net_t *))981 void net_shutdown(net_t *n, void(*cb)(net_t *)) {
982 g_return_if_fail(n->state == NETST_ASY);
983 g_debug("%s: Shutting down", net_remoteaddr(n));
984 n->state = NETST_DIS;
985 n->cb_shutdown = cb;
986 time(&n->timeout_last);
987 if(!n->wbuf->len)
988 dis_shutdown(n);
989 }
990
991 #if GNUTLS_VERSION_NUMBER >= 0x030200
992 static const gnutls_datum_t alpn_protos[2] = {
993 { (unsigned char *)"adc", 3 },
994 { (unsigned char *)"nmdc", 4 }
995 };
996 #endif
997
998 // Enables TLS-mode and initates the handshake. May not be called when there's
999 // something in the write buffer. If the read buffer is not empty, its contents
1000 // are assumed to be valid TLS packets and will be forwarded to gnutls.
1001 // The callback function, if set, will be called when the handshake has
1002 // completed. If a certificate of the peer has been received, its keyprint will
1003 // be sent as first argument. NULL otherwise.
1004 // Once TLS is enabled, it's not possible to switch back to a raw connection
1005 // again.
net_settls(net_t * n,gboolean serv,gboolean negotiate,void (* cb)(net_t *,const char *,int))1006 void net_settls(net_t *n, gboolean serv, gboolean negotiate, void (*cb)(net_t *, const char *, int)) {
1007 g_return_if_fail(n->state == NETST_ASY);
1008 g_return_if_fail(!n->wbuf->len);
1009 g_return_if_fail(!n->tls);
1010 if(n->rbuf->len) {
1011 n->tlsrbuf = n->rbuf;
1012 n->rbuf = g_string_sized_new(1024);
1013 }
1014 gnutls_init(&n->tls, serv ? GNUTLS_SERVER : GNUTLS_CLIENT);
1015 gnutls_credentials_set(n->tls, GNUTLS_CRD_CERTIFICATE, db_certificate);
1016 const char *pos;
1017 gnutls_priority_set_direct(n->tls, var_get(0, VAR_tls_priority), &pos);
1018
1019 gnutls_transport_set_ptr(n->tls, n);
1020 gnutls_transport_set_push_function(n->tls, tls_push);
1021 gnutls_transport_set_pull_function(n->tls, tls_pull);
1022
1023 #if GNUTLS_VERSION_NUMBER >= 0x030200
1024 if(negotiate) {
1025 gnutls_alpn_set_protocols(n->tls, alpn_protos, 2, 0);
1026 }
1027 #endif
1028
1029 n->cb_handshake = cb;
1030 n->tls_handshake = TRUE;
1031 asy_handshake(n);
1032 }
1033
1034
net_connected(net_t * n,int sock,const char * addr,gboolean v6)1035 void net_connected(net_t *n, int sock, const char *addr, gboolean v6) {
1036 g_return_if_fail(n->state == NETST_IDL || n->state == NETST_CON);
1037 g_debug("%s: Connected.", addr);
1038 n->state = NETST_ASY;
1039 n->sock = sock;
1040 if(addr != n->addr)
1041 strncpy(n->addr, addr, sizeof(n->addr));
1042 n->v6 = v6;
1043 n->wbuf = g_string_sized_new(1024);
1044 n->rbuf = g_string_sized_new(1024);
1045
1046 if(v6) {
1047 struct sockaddr_in6 a;
1048 socklen_t l = sizeof(a);
1049 getsockname(sock, (void *)&a, &l);
1050 strcpy(n->laddr, ip6_unpack(a.sin6_addr));
1051 } else {
1052 struct sockaddr_in a;
1053 socklen_t l = sizeof(a);
1054 getsockname(sock, (void *)&a, &l);
1055 strcpy(n->laddr, ip4_unpack(a.sin_addr));
1056 }
1057
1058 ratecalc_reset(&n->rate_in);
1059 ratecalc_reset(&n->rate_out);
1060 ratecalc_register(&n->rate_in, RCC_DOWN);
1061 ratecalc_register(&n->rate_out, RCC_UP);
1062 time(&n->timeout_last);
1063 if(!n->timeout_src)
1064 n->timeout_src = g_timeout_add_seconds(5, handle_timer, n);
1065
1066 asy_setuppoll(n); // Always make sure we're polling for read, to catch an async disconnect.
1067 }
1068
1069
1070
1071
1072
1073
1074 // DNS resolution and connecting
1075
1076 struct dnscon_t {
1077 net_t *net;
1078 char *addr;
1079 char *laddr;
1080 unsigned short port;
1081 struct addrinfo *nfo;
1082 struct addrinfo *next;
1083 char *err;
1084 void(*cb)(net_t *, const char *);
1085 };
1086
1087
1088 static GThreadPool *dns_pool = NULL;
1089
1090
dnscon_free(dnscon_t * r)1091 static void dnscon_free(dnscon_t *r) {
1092 g_free(r->err);
1093 g_free(r->addr);
1094 g_free(r->laddr);
1095 if(r->nfo)
1096 freeaddrinfo(r->nfo);
1097 g_slice_free(dnscon_t, r);
1098 }
1099
1100
1101 static void dnscon_tryconn(net_t *n);
1102
dnsconn_handleconn(net_t * n,int err)1103 static void dnsconn_handleconn(net_t *n, int err) {
1104 // Successful.
1105 if(err == 0) {
1106 net_connected(n, n->sock, n->addr, n->dnscon->next->ai_family == AF_INET6);
1107
1108 if(n->dnscon->cb)
1109 n->dnscon->cb(n, NULL);
1110 dnscon_free(n->dnscon);
1111 n->dnscon = NULL;
1112 return;
1113 }
1114
1115 close(n->sock);
1116 n->sock = 0;
1117
1118 // Error, but we've got more addresses to try!
1119 if(n->dnscon->next->ai_next) {
1120 n->dnscon->next = n->dnscon->next->ai_next;
1121 dnscon_tryconn(n);
1122 return;
1123 }
1124
1125 // Error on the last try, time to give up.
1126 g_debug("%s: Connect error: %s", net_remoteaddr(n), g_strerror(err));
1127 n->cb_err(n, NETERR_CONN, g_strerror(err));
1128 }
1129
1130
dnscon_conresult(gpointer dat)1131 static gboolean dnscon_conresult(gpointer dat) {
1132 net_t *n = dat;
1133 n->socksrc = 0;
1134
1135 int err = 0;
1136 socklen_t len = sizeof(err);
1137 getsockopt(n->sock, SOL_SOCKET, SO_ERROR, &err, &len);
1138 dnsconn_handleconn(n, err);
1139
1140 return FALSE;
1141 }
1142
1143
dnscon_tryconn(net_t * n)1144 static void dnscon_tryconn(net_t *n) {
1145 struct addrinfo *c = n->dnscon->next;
1146
1147 time(&n->timeout_last);
1148 // Set n->addr
1149 if(c->ai_family == AF_INET)
1150 g_snprintf(n->addr, sizeof(n->addr), "%s:%d", inet_ntoa(((struct sockaddr_in *)c->ai_addr)->sin_addr), (int)ntohs(((struct sockaddr_in *)c->ai_addr)->sin_port));
1151 else {
1152 n->addr[0] = '[';
1153 inet_ntop(AF_INET6, &((struct sockaddr_in6 *)c->ai_addr)->sin6_addr, n->addr+1, sizeof(n->addr)-1);
1154 snprintf(n->addr+strlen(n->addr), sizeof(n->addr)-strlen(n->addr), "]:%d", (int)ntohs(((struct sockaddr_in6 *)c->ai_addr)->sin6_port));
1155 }
1156
1157 if(n->dnscon->cb)
1158 n->dnscon->cb(n, n->addr);
1159
1160 // Create new socket and connect.
1161 n->sock = socket(c->ai_family, SOCK_STREAM, 0);
1162 fcntl(n->sock, F_SETFL, fcntl(n->sock, F_GETFL, 0)|O_NONBLOCK);
1163
1164 if(net_sock_bind(c->ai_family, n->sock, n->dnscon->laddr) < 0) {
1165 char *e = g_strdup_printf("Can't bind to local address: %s", g_strerror(errno));
1166 g_debug("%s: %s", net_remoteaddr(n), e);
1167 n->cb_err(n, NETERR_CONN, e);
1168 g_free(e);
1169 return;
1170 }
1171
1172 int r = connect(n->sock, n->dnscon->next->ai_addr, n->dnscon->next->ai_addrlen);
1173
1174 // The common case, I guess
1175 if(r && errno == EINPROGRESS) {
1176 GSource *src = fdsrc_new(n->sock, G_IO_OUT);
1177 g_source_set_callback(src, dnscon_conresult, n, NULL);
1178 n->socksrc = g_source_attach(src, NULL);
1179 g_source_unref(src);
1180 return;
1181 }
1182
1183 dnsconn_handleconn(n, r == 0 ? 0 : errno);
1184 }
1185
1186
1187 // Called as an idle function from the dnscon_thread.
dnscon_gotdns(gpointer dat)1188 static gboolean dnscon_gotdns(gpointer dat) {
1189 dnscon_t *r = dat;
1190 net_t *n = r->net;
1191 // It's possible that a net_disconnect() has happened in the mean time. Free
1192 // and ignore the results in that case.
1193 if(!n) {
1194 dnscon_free(r);
1195 return FALSE;
1196 }
1197
1198 // Handle error
1199 if(r->err) {
1200 g_debug("%s: DNS resolve: %s", net_remoteaddr(n), r->err);
1201 n->cb_err(n, NETERR_CONN, r->err);
1202 return FALSE;
1203 }
1204
1205 // Is it possible for getaddrinfo() to return an empty result set without an error?
1206 g_return_val_if_fail(r->nfo, FALSE);
1207
1208 // Try connecting to each of the addresses.
1209 n->state = NETST_CON;
1210 r->next = r->nfo;
1211 dnscon_tryconn(n);
1212 return FALSE;
1213 }
1214
1215
1216 // Async DNS resolution in a background thread
dnscon_thread(gpointer dat,gpointer udat)1217 static void dnscon_thread(gpointer dat, gpointer udat) {
1218 dnscon_t *r = dat;
1219 struct addrinfo hint = {};
1220 hint.ai_family = AF_UNSPEC;
1221 hint.ai_socktype = SOCK_STREAM;
1222 hint.ai_protocol = 0;
1223 hint.ai_flags = 0;
1224 char port[20];
1225 g_snprintf(port, sizeof(port), "%d", (int)r->port);
1226 int n = getaddrinfo(r->addr, port, &hint, &r->nfo);
1227 if(n)
1228 r->err = g_strdup(n == EAI_SYSTEM ? g_strerror(errno) : gai_strerror(n));
1229 g_idle_add(dnscon_gotdns, r);
1230 }
1231
1232
1233
1234
1235
1236
1237 // Connection management
1238
net_last_activity(net_t * n)1239 time_t net_last_activity(net_t *n) {
1240 if(n->syn)
1241 g_static_mutex_lock(&n->syn->lock);
1242 time_t last = n->timeout_last;
1243 if(n->syn)
1244 g_static_mutex_unlock(&n->syn->lock);
1245 return last;
1246 }
1247
1248
1249 // Set to non-NULL to enable keepalive in the ASY state. Will automatically
1250 // send *msg over the socket after a certain period of inactivity. *msg is
1251 // assumed to be some statically allocated string.
net_set_keepalive(net_t * n,const char * msg)1252 void net_set_keepalive(net_t *n, const char *msg) {
1253 n->timeout_msg = msg;
1254 }
1255
1256
net_remoteaddr(net_t * n)1257 const char *net_remoteaddr(net_t *n) { return n->addr; }
net_localaddr(net_t * n)1258 const char *net_localaddr(net_t *n) { return n->laddr; }
net_rate_in(net_t * n)1259 ratecalc_t *net_rate_in(net_t *n) { return &n->rate_in; }
net_rate_out(net_t * n)1260 ratecalc_t *net_rate_out(net_t *n) { return &n->rate_out; }
net_handle(net_t * n)1261 void *net_handle(net_t *n) { return n->handle; }
1262
net_is_asy(net_t * n)1263 gboolean net_is_asy(net_t *n) { return n->state == NETST_ASY; }
net_is_connected(net_t * n)1264 gboolean net_is_connected(net_t *n) { return n->state == NETST_ASY || n->state == NETST_SYN; }
net_is_connecting(net_t * n)1265 gboolean net_is_connecting(net_t *n) { return n->state == NETST_DNS || n->state == NETST_CON; }
net_is_disconnecting(net_t * n)1266 gboolean net_is_disconnecting(net_t *n) { return n->state == NETST_DIS; }
net_is_idle(net_t * n)1267 gboolean net_is_idle(net_t *n) { return n->state == NETST_IDL; }
net_is_ipv6(net_t * n)1268 gboolean net_is_ipv6(net_t *n) { return n->v6; }
1269
1270
handle_timer(gpointer dat)1271 static gboolean handle_timer(gpointer dat) {
1272 net_t *n = dat;
1273 time_t intv = time(NULL)-net_last_activity(n);
1274
1275 // time() isn't that reliable.
1276 if(intv < 0) {
1277 time(&n->timeout_last);
1278 return TRUE;
1279 }
1280
1281 // 30 second timeout on connecting, disconnecting, synchronous transfers, and
1282 // non-keepalive ASY connections.
1283 if(intv > 30 && (n->state == NETST_DNS || n->state == NETST_CON || n->state == NETST_DIS || n->state == NETST_SYN || (n->state == NETST_ASY && !n->timeout_msg))) {
1284 if(n->state == NETST_DNS || n->state == NETST_CON)
1285 n->cb_err(n, NETERR_TIMEOUT, g_strerror(ETIMEDOUT));
1286 else {
1287 g_debug("%s: Timeout.", net_remoteaddr(n));
1288 n->cb_err(n, NETERR_TIMEOUT, "Idle timeout");
1289 }
1290 n->timeout_src = 0;
1291 return FALSE;
1292 }
1293
1294 // For keepalive ASY connections, send the timeout_msg after 2 minutes
1295 if(intv > 120 && n->state == NETST_ASY && n->timeout_msg)
1296 net_writestr(n, n->timeout_msg);
1297
1298 return TRUE;
1299 }
1300
1301
net_new(void * handle,void (* err)(net_t *,int,const char *))1302 net_t *net_new(void *handle, void(*err)(net_t *, int, const char *)) {
1303 net_t *n = g_new0(net_t, 1);
1304 n->ref = 1;
1305 n->handle = handle;
1306 n->cb_err = err;
1307 ratecalc_init(&n->rate_in);
1308 ratecalc_init(&n->rate_out);
1309 time(&n->timeout_last);
1310 return n;
1311 }
1312
1313
1314 // 'host' can be either a hostname or IP address. The callback is called with
1315 // an address each time a connection attempt is made. It is called with NULL
1316 // when the connection was successful (at which point net_remoteaddr() should
1317 // work).
net_connect(net_t * n,const char * host,unsigned short port,const char * laddr,void (* cb)(net_t *,const char *))1318 void net_connect(net_t *n, const char *host, unsigned short port, const char *laddr, void(*cb)(net_t *, const char *)) {
1319 g_return_if_fail(n->state == NETST_IDL);
1320
1321 dnscon_t *r = g_slice_new0(dnscon_t);
1322 r->addr = g_strdup(host);
1323 r->laddr = g_strdup(laddr);
1324 r->port = port;
1325 r->net = n;
1326 r->cb = cb;
1327
1328 if(!n->timeout_src)
1329 n->timeout_src = g_timeout_add_seconds(5, handle_timer, n);
1330 time(&n->timeout_last);
1331 n->dnscon = r;
1332 n->state = NETST_DNS;
1333 g_thread_pool_push(dns_pool, r, NULL);
1334 }
1335
1336
1337 // Force-disconnect. Can be called from any state.
net_disconnect(net_t * n)1338 void net_disconnect(net_t *n) {
1339 synfer_t *s = NULL;
1340
1341 switch(n->state) {
1342
1343 case NETST_DNS:
1344 n->dnscon->net = NULL;
1345 n->dnscon = NULL;
1346 break;
1347
1348 case NETST_CON:
1349 dnscon_free(n->dnscon);
1350 n->dnscon = NULL;
1351 break;
1352
1353 case NETST_ASY:
1354 case NETST_DIS:
1355 n->rd_cb = NULL;
1356 s = n->syn;
1357 if(s) {
1358 syn_cancel(n);
1359 syn_free(s);
1360 }
1361 break;
1362
1363 case NETST_SYN:
1364 s = n->syn;
1365 if(s)
1366 syn_cancel(n);
1367 break;
1368 }
1369
1370 // If we're in the SYN state, then the socket and tls session are in control
1371 // of the file transfer thread. Hence the need for the conditional locks.
1372 if(s)
1373 g_static_mutex_lock(&s->lock);
1374 if(n->tls) {
1375 gnutls_deinit(n->tls);
1376 n->tls = NULL;
1377 }
1378 if(n->sock) {
1379 close(n->sock);
1380 n->sock = 0;
1381 }
1382 time(&n->timeout_last);
1383 if(s)
1384 g_static_mutex_unlock(&s->lock);
1385
1386 if(n->rbuf) {
1387 g_string_free(n->rbuf, TRUE);
1388 g_string_free(n->wbuf, TRUE);
1389 n->rbuf = n->wbuf = NULL;
1390 }
1391
1392 if(n->tlsrbuf) {
1393 g_string_free(n->tlsrbuf, TRUE);
1394 n->tlsrbuf = NULL;
1395 }
1396
1397 if(n->socksrc) {
1398 g_source_remove(n->socksrc);
1399 n->socksrc = 0;
1400 }
1401 if(n->timeout_src) {
1402 g_source_remove(n->timeout_src);
1403 n->timeout_src = 0;
1404 }
1405
1406 ratecalc_unregister(&n->rate_in);
1407 ratecalc_unregister(&n->rate_out);
1408
1409 if(n->state == NETST_ASY || n->state == NETST_SYN || n->state == NETST_DIS)
1410 g_debug("%s: Disconnected.", net_remoteaddr(n));
1411 n->addr[0] = 0;
1412 n->wantwrite = n->writing = n->tls_handshake = n->shutdown_closed = FALSE;
1413 n->state = NETST_IDL;
1414 }
1415
1416
net_ref(net_t * n)1417 void net_ref(net_t *n) {
1418 g_atomic_int_inc(&(n->ref));
1419 }
1420
1421
net_unref(net_t * n)1422 void net_unref(net_t *n) {
1423 if(!g_atomic_int_dec_and_test(&n->ref))
1424 return;
1425 g_return_if_fail(n->state == NETST_IDL);
1426 g_free(n);
1427 }
1428
1429
1430
1431
1432
1433 // Simple API for sending UDP packets
1434
1435 #if INTERFACE
1436
1437 struct net_udp_t {
1438 char addr[62];
1439 int sock;
1440 };
1441
1442 #endif
1443
1444
1445 // Creates a new UDP socket for sending messages to the given destination.
1446 // host is assumed to be a valid IPv4 or IPv6 address.
net_udp_init(net_udp_t * udp,const char * host,unsigned short port,char * laddr)1447 void net_udp_init(net_udp_t *udp, const char *host, unsigned short port, char *laddr) {
1448 int af = ip4_isvalid(host) ? AF_INET : AF_INET6;
1449 snprintf(udp->addr, sizeof(udp->addr), af == AF_INET ? "%s:%d" : "[%s]:%d", host, (int)port);
1450
1451 udp->sock = socket(af, SOCK_DGRAM, 0);
1452 fcntl(udp->sock, F_SETFL, fcntl(udp->sock, F_GETFL, 0)|O_NONBLOCK);
1453
1454 if(net_sock_bind(af, udp->sock, laddr) < 0) {
1455 g_message("Can't bind UDP socket for '%s' to local address '%s': %s", udp->addr, laddr, g_strerror(errno));
1456 close(udp->sock);
1457 return;
1458 }
1459
1460 int n;
1461 if(af == AF_INET) {
1462 struct in_addr a = ip4_pack(host);
1463 n = connect(udp->sock, ip4_sockaddr(a, port), sizeof(struct sockaddr_in));
1464 } else {
1465 struct in6_addr a = ip6_pack(host);
1466 n = connect(udp->sock, ip6_sockaddr(a, port), sizeof(struct sockaddr_in6));
1467 }
1468 if(n < 0) {
1469 g_message("Can't associate UDP socket with '%s': %s", udp->addr, g_strerror(errno));
1470 close(udp->sock);
1471 return;
1472 }
1473 }
1474
1475
net_udp_destroy(net_udp_t * udp)1476 void net_udp_destroy(net_udp_t *udp) {
1477 if(udp->sock >= 0)
1478 close(udp->sock);
1479 }
1480
1481
1482 // Send a message to a UDP socket, logs but otherwise ignores errors. Note that
1483 // the socket is created as non-blocking and this function does not attempt to
1484 // retry the send() on EWOULDBLOCK or EAGAIN. It is assumed that the kernel
1485 // buffers are large enough that we can burst-queue several messages, and that,
1486 // if the kernel buffers are full, we might be better off dropping some
1487 // messages than queueing them until infinity.
net_udp_send_raw(net_udp_t * udp,const char * msg,int len)1488 void net_udp_send_raw(net_udp_t *udp, const char *msg, int len) {
1489 int r = send(udp->sock, msg, len, 0);
1490 if(r != len)
1491 g_message("Error sending UDP message to '%s': %s", udp->addr, g_strerror(errno));
1492 else
1493 ratecalc_add(&net_out, len);
1494 }
1495
1496
net_udp_send(net_udp_t * udp,const char * msg)1497 void net_udp_send(net_udp_t *udp, const char *msg) {
1498 int len = strlen(msg);
1499 if(len) {
1500 g_debug("UDP:%s> %.*s", udp->addr, msg[len-1] == '\n' ? len-1 : len, msg);
1501 net_udp_send_raw(udp, msg, len);
1502 }
1503 }
1504
1505
net_udp_sendf(net_udp_t * udp,const char * fmt,...)1506 void net_udp_sendf(net_udp_t *udp, const char *fmt, ...) {
1507 va_list va;
1508 va_start(va, fmt);
1509 char *str = g_strdup_vprintf(fmt, va);
1510 va_end(va);
1511 net_udp_send(udp, str);
1512 g_free(str);
1513 }
1514
1515
1516
1517
1518
1519 // initialize some global structures
1520
net_init_global()1521 void net_init_global() {
1522 ratecalc_init(&net_in);
1523 ratecalc_init(&net_out);
1524 // Don't group these with RCC_UP or RCC_DOWN, otherwise bandwidth will be counted twice.
1525 ratecalc_register(&net_in, RCC_NONE);
1526 ratecalc_register(&net_out, RCC_NONE);
1527
1528 dns_pool = g_thread_pool_new(dnscon_thread, NULL, -1, FALSE, NULL);
1529 syn_pool = g_thread_pool_new(syn_thread, NULL, -1, FALSE, NULL);
1530 }
1531
1532