2
* $Id: sockets.c,v 1.36 2005/06/25 01:37:41 daichik Exp $
4
* Copyright (c) 2001-2003, Raphael Manfredi
5
* Copyright (c) 2000 Daniel Walker (dwalker@cats.ucsc.edu)
7
*----------------------------------------------------------------------
8
* This file is part of gtk-gnutella.
10
* gtk-gnutella is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
15
* gtk-gnutella is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with gtk-gnutella; if not, write to the Free Software
23
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
*----------------------------------------------------------------------
33
* @author Daniel Walker (dwalker@cats.ucsc.edu)
35
* @author Raphael Manfredi
41
RCSID("$Id: sockets.c,v 1.36 2005/06/25 01:37:41 daichik Exp $");
47
#include "downloads.h"
60
#ifdef USE_REMOTE_CTRL
64
#include "if/gnet_property.h"
65
#include "if/gnet_property_priv.h"
68
#include "lib/getline.h"
69
#include "lib/glib-missing.h"
70
#include "lib/endian.h"
71
#include "lib/header.h"
72
#include "lib/walloc.h"
74
#include "lib/override.h" /* Must be the last header included */
77
#define TLS_DH_BITS 768
81
/* XXX: This should be handled by Configure because SHUT_* are sometimes
82
* enums instead of macro definitions.
84
#define SHUT_WR 1 /**< Shutdown TX side */
87
#define RQST_LINE_LENGTH 256 /**< Reasonable estimate for request line */
88
#define SOCK_UDP_RECV_BUF 131072 /**< 128K -- Large to avoid loosing dgrams */
90
#define SOCK_ADNS_PENDING 0x01 /**< Don't free() the socket too early */
91
#define SOCK_ADNS_FAILED 0x02 /**< Signals error in the ADNS callback */
92
#define SOCK_ADNS_BADNAME 0x04 /**< Signals bad host name */
94
struct gnutella_socket *s_tcp_listen = NULL;
95
struct gnutella_socket *s_udp_listen = NULL;
97
typedef union socket_addr {
98
struct sockaddr_in inet4;
100
/* The IPv6 hack might be useful for machines with IPv6 only. It is a
101
* hack because it will only work with IPv4 addresses that are mapped
102
* to IPv6 i.e., "::FFFF:<IPv4 address>". It is not tested so far.
104
#define SOCKET_AF AF_INET6
105
struct sockaddr_in6 inet6;
107
#define SOCKET_AF AF_INET
112
* Initializes addr with an IPv4 address and a port number.
114
* @param addr a pointer to a socket_addr_t
115
* @param ip an IPv4 address in host(!) byte order
116
* @param port a 16-bit port number in host byte order
119
socket_addr_set(socket_addr_t *addr, guint32 ip, guint16 port)
121
static socket_addr_t zero_addr;
123
g_assert(addr != NULL);
128
addr->inet6.sin6_family = AF_INET6; /* host byte order */
129
addr->inet6.sin6_port = htons(port);
130
addr->inet6.sin6_addr.s6_addr[10] = 0xff;
131
addr->inet6.sin6_addr.s6_addr[11] = 0xff;
132
WRITE_GUINT32_BE(ip, &addr->inet6.sin6_addr.s6_addr[12]);
134
addr->inet4.sin_family = AF_INET; /* host byte order */
135
addr->inet4.sin_port = htons(port);
136
addr->inet4.sin_addr.s_addr = htonl(ip);
141
* Retrieves the IPv4 address from a socket_addr_t.
143
* @param addr a pointer to an initialized socket_addr_t
144
* @return the IPv4 address in host(!) byte order
146
static inline guint32
147
socket_addr_get_ip(const socket_addr_t *addr)
151
g_assert(addr != NULL);
154
READ_GUINT32_BE(&addr->inet6.sin6_addr.s6_addr[12], ip);
156
ip = htonl(addr->inet4.sin_addr.s_addr);
163
* Retrieves the port number from a socket_addr_t.
165
* @param addr a pointer to an initialized socket_addr_t
166
* @return the port number in host byte order
168
static inline guint16
169
socket_addr_get_port(const socket_addr_t *addr)
171
g_assert(addr != NULL);
174
return ntohs(addr->inet6.sin6_port);
176
return ntohs(addr->inet4.sin_port);
181
* In order to avoid having a dependency between sockets.c and ban.c,
182
* we have ban.c register a callback to reclaim file descriptors
186
static reclaim_fd_t reclaim_fd = NULL;
189
* Register fd reclaiming callback.
190
* Use NULL to unregister it.
193
socket_register_fd_reclaimer(reclaim_fd_t callback)
195
reclaim_fd = callback;
199
* UDP address information for datagrams.
202
struct sockaddr ud_addr;
203
socklen_t ud_addrlen;
211
/* A null terminated username goes here */
212
} __attribute__((__packed__));
219
} __attribute__((__packed__));
222
static gboolean ip_computed = FALSE;
224
static GSList *sl_incoming = (GSList *) NULL; /* To spot inactive sockets */
226
static void guess_local_ip(int sd);
227
static void socket_destroy(struct gnutella_socket *s, const gchar *reason);
228
static void socket_connected(gpointer data, gint source, inputevt_cond_t cond);
229
static void socket_wio_link(struct gnutella_socket *s);
232
* SOL_TCP and SOL_IP aren't standards. Some platforms define them, on
233
* some it's safe to assume they're the same as IPPROTO_*, but the
234
* only way to be portably safe is to use protoent functions.
236
* If the user changes /etc/protocols while running gtkg, things may
239
static gboolean sol_got = FALSE;
240
static gint sol_tcp_cached = -1;
241
static gint sol_ip_cached = -1;
244
* Compute and cache values for SOL_TCP and SOL_IP.
249
struct protoent *pent;
251
pent = getprotobyname("tcp");
253
sol_tcp_cached = pent->p_proto;
254
pent = getprotobyname("ip");
256
sol_ip_cached = pent->p_proto;
267
return sol_tcp_cached;
277
return sol_ip_cached;
283
* Set the TOS on the socket. Routers can use this information to
284
* better route the IP datagrams.
287
socket_tos(struct gnutella_socket *s, gint tos)
292
if (-1 == setsockopt(s->file_desc, sol_ip(), IP_TOS, &tos, sizeof tos)) {
293
const gchar *tosname = "default";
297
case IPTOS_LOWDELAY: tosname = "low delay"; break;
298
case IPTOS_THROUGHPUT: tosname = "throughput"; break;
300
g_assert_not_reached();
303
if (errno != ECONNRESET)
304
g_warning("unable to set IP_TOS to %s (%d) on fd#%d: %s",
305
tosname, tos, s->file_desc, g_strerror(errno));
310
* Pick an appropriate default TOS for packets on the socket, based
311
* on the socket's type.
313
void socket_tos_default(struct gnutella_socket *s)
316
case SOCK_TYPE_DOWNLOAD: /* ACKs w/ low latency => higher transfer rates */
317
socket_tos_lowdelay(s);
319
case SOCK_TYPE_UPLOAD:
320
socket_tos_throughput(s);
322
case SOCK_TYPE_CONTROL:
324
case SOCK_TYPE_PPROXY:
326
socket_tos_normal(s);
331
socket_tos(struct gnutella_socket *unused_s, gint unused_tos)
339
socket_tos_default(struct gnutella_socket *unused_s)
344
#endif /* USE_IP_TOS */
347
* Set the Type of Service (TOS) field to "normal."
350
socket_tos_normal(struct gnutella_socket *s)
356
* Set the Type of Service (TOS) field to "lowdelay." This may cause
357
* your host and/or any routers along the path to put its packets in
358
* a higher-priority queue, and/or to route them along the lowest-
359
* latency path without regard for bandwidth.
362
socket_tos_lowdelay(struct gnutella_socket *s)
364
socket_tos(s, IPTOS_LOWDELAY);
368
* Set the Type of Service (TOS) field to "throughput." This may cause
369
* your host and/or any routers along the path to put its packets in
370
* a lower-priority queue, and/or to route them along the highest-
371
* bandwidth path without regard for latency.
374
socket_tos_throughput(struct gnutella_socket *s)
376
socket_tos(s, IPTOS_THROUGHPUT);
380
* Got an EOF condition on the socket.
383
socket_eof(struct gnutella_socket *s)
387
s->flags |= SOCK_F_EOF;
391
proxy_connect_helper(guint32 addr, gpointer udata)
393
gboolean *in_progress = udata;
395
*in_progress = FALSE;
396
gnet_prop_set_guint32(PROP_PROXY_IP, &addr, 0, 1);
397
g_message("Resolved proxy name \"%s\" to %s", proxy_hostname,
398
ip_to_gchar(proxy_ip));
402
* The socks 4/5 code was taken from tsocks 1.16 Copyright (C) 2000 Shaun Clowes
403
* It was modified to work with gtk_gnutella and non-blocking sockets. --DW
406
proxy_connect(int fd)
408
static gboolean in_progress = FALSE;
409
socket_addr_t server;
413
proxy_hostname[0] != '\0'
417
g_warning("Resolving proxy name \"%s\"", proxy_hostname);
418
adns_resolve(proxy_hostname, proxy_connect_helper, &in_progress);
427
if (!proxy_ip || !proxy_port) {
432
socket_addr_set(&server, proxy_ip, proxy_port);
434
return connect(fd, (struct sockaddr *) &server, sizeof server);
438
send_socks(struct gnutella_socket *s)
441
struct sockreq *thisreq;
443
size_t name_size, length = 0;
447
/* XXX: Shouldn't this use the configured username instead? */
448
/* Determine the current username */
449
user = getpwuid(getuid());
450
name = user != NULL ? user->pw_name : "";
451
name_size = strlen(name) + 1;
453
/* Allocate enough space for the request and the null */
454
/* terminated username */
455
length = sizeof(struct sockreq) + name_size;
456
realreq = g_malloc(length);
460
/* Copy the username */
461
strncpy(&realreq[sizeof(struct sockreq)], name, name_size);
463
/* Create the request */
464
thisreq = (struct sockreq *) realreq;
465
thisreq->version = 4;
466
thisreq->command = 1;
467
thisreq->dstport = htons(s->port);
468
thisreq->dstip = htonl(s->ip);
470
/* Send the socks header info */
471
ret = write(s->file_desc, realreq, length);
472
G_FREE_NULL(realreq);
473
if ((size_t) ret != length) {
474
g_warning("Error attempting to send SOCKS request (%s)",
475
ret == (ssize_t) -1 ? strerror(errno) : "Partial write");
483
recv_socks(struct gnutella_socket *s)
486
struct sockrep thisrep;
487
size_t size = sizeof thisrep;
489
ret = read(s->file_desc, (void *) &thisrep, size);
490
if (ret == (ssize_t) -1) {
491
g_warning("Error attempting to receive SOCKS reply (%s)",
495
if ((size_t) ret != size) {
496
g_warning("Short reply from SOCKS server");
497
/* Let the application try and see how they go */
502
if (thisrep.result == 91) {
503
g_warning("SOCKS server refused connection");
504
} else if (thisrep.result == 92) {
505
g_warning("SOCKS server refused connection "
506
"because of failed connect to identd "
508
} else if (thisrep.result == 93) {
509
g_warning("SOCKS server refused connection "
510
"because identd and this library "
511
"reported different user-ids");
517
errno = ECONNREFUSED;
525
connect_http(struct gnutella_socket *s)
535
const gchar *host = ip_port_to_gchar(s->ip, s->port);
538
size = gm_snprintf(s->buffer, sizeof(s->buffer),
539
"CONNECT %s HTTP/1.0\r\nHost: %s\r\n\r\n", host, host);
540
ret = write(s->file_desc, s->buffer, size);
541
if ((size_t) ret != size) {
542
g_warning("Sending info to HTTP proxy failed: %s",
543
ret == (ssize_t) -1 ? g_strerror(errno) : "Partial write");
550
ret = read(s->file_desc, s->buffer, sizeof(s->buffer) - 1);
551
if (ret == (ssize_t) -1) {
552
g_warning("Receiving answer from HTTP proxy faild: %s",
556
s->getline = getline_make(HEAD_MAX_SIZE);
557
switch (getline_read(s->getline, s->buffer, ret, &parsed)) {
559
g_warning("HTTP proxy returned a too long line");
563
memmove(s->buffer, s->buffer + parsed, ret - parsed);
568
g_assert(parsed == ret);
571
str = getline_str(s->getline);
572
if ((status = http_status_parse(str, NULL, NULL, NULL, NULL)) < 0) {
573
g_warning("Bad status line");
576
if ((status / 100) != 2) {
577
g_warning("Cannot use HTTP proxy: \"%s\"", str);
583
getline_reset(s->getline);
584
switch (getline_read(s->getline, s->buffer, ret, &parsed)) {
586
g_warning("HTTP proxy returned a too long line");
590
memmove(s->buffer, s->buffer + parsed, ret - parsed);
592
if (getline_length(s->getline) == 0) {
594
getline_free(s->getline);
601
g_assert(parsed == ret);
607
ret = read(s->file_desc, s->buffer, sizeof(s->buffer) - 1);
608
if (ret == (ssize_t) -1) {
609
g_warning("Receiving answer from HTTP proxy failed: %s",
614
getline_reset(s->getline);
615
switch (getline_read(s->getline, s->buffer, ret, &parsed)) {
617
g_warning("HTTP proxy returned a too long line");
621
memmove(s->buffer, s->buffer + parsed, ret - parsed);
623
if (getline_length(s->getline) == 0) {
625
getline_free(s->getline);
632
g_assert(parsed == ret);
653
connect_socksv5(struct gnutella_socket *s)
657
static const gchar verstring[] = "\x05\x02\x02";
661
sockid = s->file_desc;
665
/* Now send the method negotiation */
666
size = sizeof verstring;
667
ret = write(sockid, verstring, size);
668
if ((size_t) ret != size) {
669
g_warning("Sending SOCKS method negotiation failed: %s",
670
ret == (ssize_t) -1 ? g_strerror(errno) : "Partial write");
677
/* Now receive the reply as to which method we're using */
679
ret = read(sockid, s->buffer, size);
680
if (ret == (ssize_t) -1) {
681
g_warning("Receiving SOCKS method negotiation reply failed: %s",
686
if ((size_t) ret != size) {
687
g_warning("Short reply from SOCKS server");
691
/* See if we offered an acceptable method */
692
if (s->buffer[1] == '\xff') {
693
g_warning("SOCKS server refused authentication methods");
697
if (s->buffer[1] == 2 && socks_user != NULL && socks_user[0] != '\0') {
698
/* has provided user info */
705
/* If the socks server chose username/password authentication */
706
/* (method 2) then do that */
708
if (socks_user != NULL) {
711
const struct passwd *pw;
713
/* Determine the current *nix username */
714
pw = getpwuid(getuid());
715
name = pw != NULL ? pw->pw_name : NULL;
719
g_warning("No Username to authenticate with.");
723
if (socks_pass == NULL) {
724
g_warning("No Password to authenticate with.");
728
if (strlen(name) > 255 || strlen(socks_pass) > 255) {
729
g_warning("Username or password exceeds 255 characters.");
733
size = gm_snprintf(s->buffer, sizeof s->buffer, "\x01%c%s%c%s",
734
(guchar) strlen(name), name,
735
(guchar) strlen(socks_pass), socks_pass);
737
/* Send out the authentication */
738
ret = write(sockid, s->buffer, size);
739
if ((size_t) ret != size) {
740
g_warning("Sending SOCKS authentication failed: %s",
741
ret == (ssize_t) -1 ? g_strerror(errno) : "Partial write");
749
/* Receive the authentication response */
751
ret = read(sockid, s->buffer, size);
752
if (ret == (ssize_t) -1) {
753
g_warning("Receiving SOCKS authentication reply failed: %s",
758
if ((size_t) ret != size) {
759
g_warning("Short reply from SOCKS server");
763
if (s->buffer[1] != '\0') {
764
g_warning("SOCKS authentication failed, "
765
"check username and password");
771
/* Now send the connect */
772
s->buffer[0] = '\x05'; /* Version 5 SOCKS */
773
s->buffer[1] = '\x01'; /* Connect request */
774
s->buffer[2] = '\x00'; /* Reserved */
775
s->buffer[3] = '\x01'; /* IP version 4 */
776
WRITE_GUINT32_BE(s->ip, &s->buffer[4]);
777
WRITE_GUINT16_BE(s->port, &s->buffer[8]);
779
/* Now send the connection */
782
ret = write(sockid, s->buffer, size);
783
if ((size_t) ret != size) {
784
g_warning("Send SOCKS connect command failed: %s",
785
ret == (ssize_t) -1 ? g_strerror(errno) : "Partial write");
792
/* Now receive the reply to see if we connected */
795
ret = read(sockid, s->buffer, size);
796
if (ret == (ssize_t) -1) {
797
g_warning("Receiving SOCKS connection reply failed: %s",
802
g_message("connect_socksv5: Step 5, bytes recv'd %d\n", (int) ret);
803
if ((size_t) ret != size) {
804
g_warning("Short reply from SOCKS server");
808
/* See the connection succeeded */
809
if (s->buffer[1] != '\0') {
810
g_warning("SOCKS connect failed: ");
811
switch (s->buffer[1]) {
813
g_warning("General SOCKS server failure");
816
g_warning("Connection denied by rule");
819
g_warning("Network unreachable");
822
g_warning("Host unreachable");
825
g_warning("Connection refused");
828
g_warning("TTL Expired");
831
g_warning("Command not supported");
834
g_warning("Address type not supported");
837
g_warning("Unknown error");
851
* Called by main timer.
852
* Expires inactive sockets.
855
socket_timer(time_t now)
858
GSList *to_remove = NULL;
860
for (l = sl_incoming; l; l = g_slist_next(l)) {
861
struct gnutella_socket *s = (struct gnutella_socket *) l->data;
864
g_assert(s->last_update);
866
* Last_update can be in the feature due to parq. This is needed
867
* to avoid dropping the connection
869
delta = delta_time(now, s->last_update);
870
if (delta > (gint32) incoming_connecting_timeout) {
872
g_warning("connection from %s timed out (%d bytes read)",
873
ip_to_gchar(s->ip), (int) s->pos);
875
dump_hex(stderr, "Connection Header",
876
s->buffer, MIN(s->pos, 80));
878
to_remove = g_slist_prepend(to_remove, s);
882
for (l = to_remove; l; l = g_slist_next(l)) {
883
struct gnutella_socket *s = (struct gnutella_socket *) l->data;
884
socket_destroy(s, "Connection timeout");
887
g_slist_free(to_remove);
891
* Cleanup data structures on shutdown.
894
socket_shutdown(void)
897
socket_destroy((struct gnutella_socket *) sl_incoming->data, NULL);
900
socket_free(s_tcp_listen); /* No longer accept connections */
905
socket_free(s_udp_listen); /* No longer accept connections */
910
/* ----------------------------------------- */
915
* If there is an attached resource, call the resource's termination routine
916
* with the supplied reason.
919
socket_destroy(struct gnutella_socket *s, const gchar *reason)
924
* If there is an attached resource, its removal routine is responsible
925
* for calling back socket_free().
929
case SOCK_TYPE_CONTROL:
930
if (s->resource.node) {
931
node_remove(s->resource.node, "%s", reason);
935
case SOCK_TYPE_DOWNLOAD:
936
if (s->resource.download) {
937
download_stop(s->resource.download, GTA_DL_ERROR, "%s", reason);
941
case SOCK_TYPE_UPLOAD:
942
if (s->resource.upload) {
943
upload_remove(s->resource.upload, "%s", reason);
947
case SOCK_TYPE_PPROXY:
948
if (s->resource.pproxy) {
949
pproxy_remove(s->resource.pproxy, "%s", reason);
954
if (s->resource.handle) {
955
http_async_error(s->resource.handle, HTTP_ASYNC_IO_ERROR);
964
* No attached resource, we can simply free this socket then.
970
struct socket_linger {
971
guint tag; /* Holds the result of inputevt_add() */
975
socket_linger_cb(gpointer data, gint fd, inputevt_cond_t unused_cond)
977
struct socket_linger *ctx = data;
981
g_assert(NULL != data);
982
g_assert(0 != ctx->tag);
987
if (EAGAIN != e && EINTR != e)
988
g_warning("close(%d) failed: %s", fd, g_strerror(e));
990
/* remove the handler in case of EBADF because it would
991
* cause looping otherwise */
995
g_message("socket_linger_cb: close() succeeded");
998
g_source_remove(ctx->tag);
999
wfree(ctx, sizeof *ctx);
1003
socket_linger_close(gint fd)
1005
struct socket_linger *ctx;
1009
ctx = walloc(sizeof *ctx);
1010
ctx->tag = inputevt_add(fd,
1011
INPUT_EVENT_READ | INPUT_EVENT_WRITE | INPUT_EVENT_EXCEPTION,
1012
socket_linger_cb, ctx);
1013
g_assert(0 != ctx->tag);
1017
* Dispose of socket, closing connection, removing input callback, and
1018
* reclaiming attached getline buffer.
1021
socket_free(struct gnutella_socket *s)
1025
if (s->flags & SOCK_F_EOF)
1026
bws_sock_closed(s->type, TRUE);
1027
else if (s->flags & SOCK_F_ESTABLISHED)
1028
bws_sock_closed(s->type, FALSE);
1030
bws_sock_connect_timeout(s->type);
1032
if (s->flags & SOCK_F_UDP) {
1033
if (s->resource.handle)
1034
wfree(s->resource.handle, sizeof(struct udp_addr));
1036
if (s->last_update) {
1037
g_assert(sl_incoming);
1038
sl_incoming = g_slist_remove(sl_incoming, s);
1042
g_source_remove(s->gdk_tag);
1045
if (s->adns & SOCK_ADNS_PENDING) {
1046
s->type = SOCK_TYPE_DESTROYING;
1050
getline_free(s->getline);
1055
if (s->tls.stage > SOCK_TLS_NONE) {
1056
if (s->file_desc != -1) {
1057
gnutls_bye(s->tls.session, s->direction == SOCK_CONN_INCOMING
1058
? GNUTLS_SHUT_WR : GNUTLS_SHUT_RDWR);
1060
gnutls_deinit(s->tls.session);
1061
s->tls.stage = SOCK_TLS_NONE;
1063
#endif /* USE_TLS */
1065
if (s->file_desc != -1) {
1067
sock_cork(s, FALSE);
1068
sock_tx_shutdown(s);
1069
if (close(s->file_desc)) {
1072
if (EAGAIN != e && EINTR != e)
1073
g_warning("close(%d) failed: %s", s->file_desc, g_strerror(e));
1075
if (EBADF != e) /* just in case, as it would cause looping */
1076
socket_linger_close(s->file_desc);
1080
wfree(s, sizeof *s);
1084
static gnutls_dh_params
1087
static gnutls_dh_params dh_params;
1088
static gboolean initialized = FALSE;
1091
if (gnutls_dh_params_init(&dh_params)) {
1092
g_warning("%s: gnutls_dh_params_init() failed", __func__);
1095
if (gnutls_dh_params_generate2(dh_params, TLS_DH_BITS)) {
1096
g_warning("%s: gnutls_dh_params_generate2() failed", __func__);
1105
socket_tls_setup(struct gnutella_socket *s)
1107
g_assert(s != NULL);
1109
if (!s->tls.enabled) {
1113
if (s->tls.stage < SOCK_TLS_INITIALIZED) {
1114
static const int cipher_list[] = {
1115
GNUTLS_CIPHER_AES_256_CBC, GNUTLS_CIPHER_AES_128_CBC,
1118
static const int kx_list[] = {
1122
static const int mac_list[] = {
1123
GNUTLS_MAC_MD5, GNUTLS_MAC_SHA, GNUTLS_MAC_RMD160,
1126
gnutls_anon_server_credentials server_cred;
1127
gnutls_anon_client_credentials client_cred;
1130
if (s->direction == SOCK_CONN_INCOMING) {
1132
if (gnutls_anon_allocate_server_credentials(&server_cred)) {
1133
g_warning("gnutls_anon_allocate_server_credentials() failed");
1137
gnutls_anon_set_server_dh_params(server_cred, get_dh_params());
1140
if (gnutls_init(&s->tls.session, GNUTLS_SERVER)) {
1141
g_warning("gnutls_init() failed");
1144
gnutls_dh_set_prime_bits(s->tls.session, TLS_DH_BITS);
1147
if (gnutls_anon_allocate_client_credentials(&client_cred)) {
1148
g_warning("gnutls_anon_allocate_client_credentials() failed");
1153
if (gnutls_init(&s->tls.session, GNUTLS_CLIENT)) {
1154
g_warning("gnutls_init() failed");
1159
if (gnutls_credentials_set(s->tls.session, GNUTLS_CRD_ANON, cred)) {
1160
g_warning("gnutls_credentials_set() failed");
1165
if (gnutls_set_default_priority(s->tls.session)) {
1166
g_warning("gnutls_set_default_priority() failed");
1171
gnutls_set_default_priority(s->tls.session);
1172
if (gnutls_cipher_set_priority(s->tls.session, cipher_list)) {
1173
g_warning("gnutls_cipher_set_priority() failed");
1176
if (gnutls_kx_set_priority(s->tls.session, kx_list)) {
1177
g_warning("gnutls_kx_set_priority() failed");
1180
if (gnutls_mac_set_priority(s->tls.session, mac_list)) {
1181
g_warning("gnutls_mac_set_priority() failed");
1185
gnutls_transport_set_ptr(s->tls.session,
1186
(gnutls_transport_ptr) s->file_desc);
1188
s->tls.stage = SOCK_TLS_INITIALIZED;
1191
if (s->tls.stage < SOCK_TLS_ESTABLISHED) {
1194
ret = gnutls_handshake(s->tls.session);
1195
if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) {
1197
} else if (ret < 0) {
1198
g_warning("gnutls_handshake() failed");
1202
s->tls.stage = SOCK_TLS_ESTABLISHED;
1203
g_message("TLS handshake succeeded");
1204
socket_wio_link(s); /* Link to the TLS I/O functions */
1211
socket_destroy(s, "TLS handshake failed");
1214
#endif /* USE_TLS */
1217
* Used for incoming connections, for outgoing too??
1218
* Read bytes on an unknown incoming socket. When the first line
1219
* has been read it's decided on what type cof connection this is.
1220
* If the first line is not complete on the first call, this function
1221
* will be called as often as necessary to fetch a full line.
1224
socket_read(gpointer data, gint source, inputevt_cond_t cond)
1227
struct gnutella_socket *s = (struct gnutella_socket *) data;
1235
if (cond & INPUT_EVENT_EXCEPTION) {
1236
socket_destroy(s, "Input exception");
1240
g_assert(s->pos == 0); /* We read a line, then leave this callback */
1243
if (s->tls.enabled && s->direction == SOCK_CONN_INCOMING) {
1248
/* Peek at the socket buffer to check whether the incoming
1249
* connection uses TLS or not. */
1250
ret = recv(s->file_desc, buf, sizeof buf, MSG_PEEK);
1252
static const gchar * const shakes[] = {
1253
"GET ", /* HTTP GET request */
1254
"GIV ", /* Gnutella PUSH upload */
1255
"HEAD ", /* HTTP HEAD request */
1256
"\n\n", /* Gnutella connect back */
1257
"HELO ", /* GTKG remote shell */
1258
"GNUTELLA CONNECT/",
1261
/* We use strncmp() but the buffer might contain dirt. */
1262
g_assert(ret > 0 && (size_t) ret <= sizeof buf);
1263
buf[ret - 1] = '\0';
1265
g_message("buf=\"%s\"", buf);
1267
/* Check whether the buffer contents match a known clear
1268
* text handshake. */
1269
for (i = 0; i < G_N_ELEMENTS(shakes); i++) {
1270
if (is_strprefix(buf, shakes[i])) {
1271
/* The socket doesn't use TLS. */
1272
s->tls.enabled = FALSE;
1278
if (ret == 0 || (errno != EINTR && errno != EAGAIN)) {
1279
socket_destroy(s, "Connection reset");
1282
/* If recv() failed only temporarily, wait for further data. */
1286
if (s->tls.enabled && !socket_tls_setup(s))
1289
#endif /* USE_TLS */
1291
g_assert(sizeof(s->buffer) >= s->pos);
1292
count = sizeof(s->buffer) - s->pos;
1294
/* 1 to allow trailing NUL */
1296
g_warning("socket_read(): incoming buffer full, disconnecting from %s",
1297
ip_to_gchar(s->ip));
1298
dump_hex(stderr, "Leading Data", s->buffer, MIN(s->pos, 256));
1299
socket_destroy(s, "Incoming buffer full");
1302
count--; /* Account for trailing NUL */
1305
* Don't read too much data. We're solely interested in getting
1306
* the leading line. If we don't read the whole line, we'll come
1307
* back later on to read the remaining data.
1311
count = MIN(count, RQST_LINE_LENGTH);
1313
r = bws_read(bws.in, &s->wio, s->buffer + s->pos, count);
1315
socket_destroy(s, "Got EOF");
1317
} else if ((ssize_t) -1 == r) {
1318
if (errno != EAGAIN)
1319
socket_destroy(s, _("Read error"));
1323
s->last_update = time(NULL);
1330
switch (getline_read(s->getline, s->buffer, s->pos, &parsed)) {
1332
g_warning("socket_read(): first line too long, disconnecting from %s",
1333
ip_to_gchar(s->ip));
1334
dump_hex(stderr, "Leading Data",
1335
getline_str(s->getline), MIN(getline_length(s->getline), 256));
1337
is_strprefix(s->buffer, "GET ") ||
1338
is_strprefix(s->buffer, "HEAD ")
1340
http_send_status(s, 414, FALSE, NULL, 0, "Requested URL Too Large");
1341
socket_destroy(s, "Requested URL too large");
1344
if (s->pos != (guint) parsed)
1345
memmove(s->buffer, s->buffer + parsed, s->pos - parsed);
1348
case READ_MORE: /* ok, but needs more data */
1350
g_assert((guint) parsed == s->pos);
1356
* We come here only when we got the first line of data.
1358
* Whatever happens now, we're not going to use the existing read
1359
* callback, and we'll no longer monitor the socket via the `sl_incoming'
1360
* list: if it's a node connection, we'll monitor the node, if it's
1361
* an upload, we'll monitor the upload.
1364
g_source_remove(s->gdk_tag);
1366
sl_incoming = g_slist_remove(sl_incoming, s);
1369
first = getline_str(s->getline);
1372
* Always authorize replies for our PUSH requests.
1373
* Likewise for PARQ download resuming.
1376
if (is_strprefix(first, "GIV ")) {
1377
download_push_ack(s);
1381
if (is_strprefix(first, "QUEUE ")) {
1382
parq_download_queue_ack(s);
1387
* Check for banning.
1390
switch (ban_allow(s->ip)) {
1391
case BAN_OK: /* Connection authorized */
1393
case BAN_FORCE: /* Connection refused, no ack */
1396
case BAN_MSG: /* Send specific 403 error message */
1398
gchar *msg = ban_message(s->ip);
1401
g_message("rejecting connection from banned %s (%s still): %s",
1402
ip_to_gchar(s->ip), short_time(ban_delay(s->ip)), msg);
1405
if (is_strprefix(first, GNUTELLA_HELLO))
1406
send_node_error(s, 403, "%s", msg);
1408
http_send_status(s, 403, FALSE, NULL, 0, "%s", msg);
1411
case BAN_FIRST: /* Connection refused, negative ack */
1412
if (is_strprefix(first, GNUTELLA_HELLO))
1413
send_node_error(s, 550, "Banned for %s",
1414
short_time(ban_delay(s->ip)));
1416
gint delay = ban_delay(s->ip);
1418
http_extra_desc_t hev;
1420
gm_snprintf(msg, sizeof(msg)-1, "Retry-After: %d\r\n", delay);
1422
hev.he_type = HTTP_EXTRA_LINE;
1425
http_send_status(s, 550, FALSE, &hev, 1, "Banned for %s",
1430
g_assert(0); /* Not reached */
1434
* Check for PARQ banning.
1438
banlimit = parq_banned_source_expire(s->ip);
1442
g_warning("[sockets] PARQ has banned ip %s until %d",
1443
ip_to_gchar(s->ip), (gint) banlimit);
1449
* Deny connections from hostile IP addresses.
1451
* We do this after banning checks so that if they hammer us, they
1452
* get banned silently.
1455
if (hostiles_check(s->ip)) {
1456
static const gchar msg[] = "Hostile IP address banned";
1459
g_warning("denying connection from hostile %s: \"%s\"",
1460
ip_to_gchar(s->ip), first);
1461
if (is_strprefix(first, GNUTELLA_HELLO))
1462
send_node_error(s, 550, msg);
1464
http_send_status(s, 550, FALSE, NULL, 0, msg);
1469
* Dispatch request. Here we decide what kind of connection this is.
1472
if (is_strprefix(first, GNUTELLA_HELLO))
1473
node_add_socket(s, s->ip, s->port); /* Incoming control connection */
1474
else if (is_strprefix(first, "GET ") || is_strprefix(first, "HEAD ")) {
1478
* We have to decide whether this is an upload request or a
1479
* push-proxyfication request.
1481
* In the following code, since sizeof("GET") accounts for the
1482
* trailing NUL, we will skip the space after the request type.
1485
uri = first + ((first[0] == 'G') ? sizeof("GET") : sizeof("HEAD"));
1486
uri = skip_ascii_blanks(uri);
1488
if (is_strprefix(uri, "/gnutella/") || is_strprefix(uri, "/gnet/"))
1493
#ifdef USE_REMOTE_CTRL
1494
else if (is_strprefix(first, "HELO "))
1500
/* Socket might be free'ed now */
1506
gint len = getline_length(s->getline);
1507
g_warning("socket_read(): got unknown incoming connection from %s, "
1508
"dropping!", ip_to_gchar(s->ip));
1510
dump_hex(stderr, "First Line", first, MIN(len, 160));
1512
if (strstr(first, "HTTP"))
1513
http_send_status(s, 501, FALSE, NULL, 0, "Method Not Implemented");
1517
socket_destroy(s, NULL);
1521
* Callback for outgoing connections!
1523
* Called when a socket is connected. Checks type of connection and hands
1524
* control over the connetion over to more specialized handlers. If no
1525
* handler was found the connection is terminated.
1526
* This is the place to hook up handlers for new communication types.
1527
* So far there are CONTROL, UPLOAD, DOWNLOAD and HTTP handlers.
1530
socket_connected(gpointer data, gint source, inputevt_cond_t cond)
1532
/* We are connected to somebody */
1534
struct gnutella_socket *s = (struct gnutella_socket *) data;
1536
g_assert(source == s->file_desc);
1538
if (cond & INPUT_EVENT_EXCEPTION) { /* Error while connecting */
1539
bws_sock_connect_failed(s->type);
1540
if (s->type == SOCK_TYPE_DOWNLOAD && s->resource.download)
1541
download_fallback_to_push(s->resource.download, FALSE, FALSE);
1543
socket_destroy(s, _("Connection failed"));
1547
s->flags |= SOCK_F_ESTABLISHED;
1548
bws_sock_connected(s->type);
1551
if (!socket_tls_setup(s)) {
1554
#endif /* USE_TLS */
1556
if (cond & INPUT_EVENT_READ) {
1558
proxy_protocol != PROXY_NONE
1559
&& s->direction == SOCK_CONN_PROXY_OUTGOING
1561
g_source_remove(s->gdk_tag);
1564
if (proxy_protocol == PROXY_SOCKSV4) {
1565
if (recv_socks(s) != 0) {
1566
socket_destroy(s, "Error receiving from SOCKS 4 proxy");
1570
s->direction = SOCK_CONN_OUTGOING;
1573
inputevt_add(s->file_desc,
1574
INPUT_EVENT_READ | INPUT_EVENT_WRITE |
1575
INPUT_EVENT_EXCEPTION, socket_connected,
1578
} else if (proxy_protocol == PROXY_SOCKSV5) {
1579
if (connect_socksv5(s) != 0) {
1580
socket_destroy(s, "Error conneting to SOCKS 5 proxy");
1585
s->direction = SOCK_CONN_OUTGOING;
1588
inputevt_add(s->file_desc,
1589
INPUT_EVENT_READ | INPUT_EVENT_WRITE |
1590
INPUT_EVENT_EXCEPTION,
1591
socket_connected, (gpointer) s);
1596
inputevt_add(s->file_desc,
1598
INPUT_EVENT_EXCEPTION,
1599
socket_connected, (gpointer) s);
1603
} else if (proxy_protocol == PROXY_HTTP) {
1604
if (connect_http(s) != 0) {
1605
socket_destroy(s, "Unable to connect to HTTP proxy");
1610
s->direction = SOCK_CONN_OUTGOING;
1611
s->gdk_tag = inputevt_add(s->file_desc,
1612
INPUT_EVENT_READ | INPUT_EVENT_WRITE |
1613
INPUT_EVENT_EXCEPTION,
1614
socket_connected, (gpointer) s);
1617
s->gdk_tag = inputevt_add(s->file_desc,
1618
INPUT_EVENT_READ | INPUT_EVENT_EXCEPTION,
1619
socket_connected, (gpointer) s);
1626
if (0 != (cond & INPUT_EVENT_WRITE)) {
1627
/* We are just connected to our partner */
1629
socklen_t size = sizeof option;
1631
g_source_remove(s->gdk_tag);
1634
/* Check whether the socket is really connected */
1636
res = getsockopt(s->file_desc, SOL_SOCKET, SO_ERROR,
1637
(void *) &option, &size);
1639
if (res == -1 || option) {
1641
s->type == SOCK_TYPE_DOWNLOAD &&
1642
s->resource.download &&
1643
!(is_firewalled || !send_pushes)
1645
download_fallback_to_push(s->resource.download, FALSE, FALSE);
1647
socket_destroy(s, _("Connection failed"));
1651
if (proxy_protocol != PROXY_NONE
1652
&& s->direction == SOCK_CONN_PROXY_OUTGOING) {
1653
if (proxy_protocol == PROXY_SOCKSV4) {
1655
if (send_socks(s) != 0) {
1656
socket_destroy(s, "Error sending to SOCKS 4 proxy");
1659
} else if (proxy_protocol == PROXY_SOCKSV5) {
1660
if (connect_socksv5(s) != 0) {
1661
socket_destroy(s, "Error connecting to SOCKS 5 proxy");
1665
} else if (proxy_protocol == PROXY_HTTP) {
1666
if (connect_http(s) != 0) {
1667
socket_destroy(s, "Error connecting to HTTP proxy");
1672
s->gdk_tag = inputevt_add(s->file_desc,
1673
INPUT_EVENT_READ | INPUT_EVENT_EXCEPTION,
1674
socket_connected, (gpointer) s);
1678
inet_connection_succeeded(s->ip);
1681
memset(s->buffer, 0, sizeof(s->buffer));
1683
g_assert(s->gdk_tag == 0);
1686
* Even though local_ip is persistent, we refresh it after startup,
1687
* in case the IP changed since last time.
1691
guess_local_ip(s->file_desc);
1694
case SOCK_TYPE_CONTROL:
1696
struct gnutella_node *n = s->resource.node;
1698
g_assert(n->socket == s);
1699
node_init_outgoing(n);
1703
case SOCK_TYPE_DOWNLOAD:
1705
struct download *d = s->resource.download;
1707
g_assert(d->socket == s);
1708
download_send_request(d);
1712
case SOCK_TYPE_UPLOAD:
1714
struct upload *u = s->resource.upload;
1716
g_assert(u->socket == s);
1717
upload_connect_conf(u);
1721
case SOCK_TYPE_HTTP:
1722
http_async_connected(s->resource.handle);
1725
case SOCK_TYPE_CONNBACK:
1726
node_connected_back(s);
1729
#ifdef USE_REMOTE_CTRL
1730
case SOCK_TYPE_SHELL:
1731
g_assert_not_reached(); /* FIXME: add code here? */
1736
g_warning("socket_connected(): Unknown socket type %d !", s->type);
1737
socket_destroy(s, NULL); /* ? */
1745
* Tries to guess the local IP address.
1748
guess_local_ip(int sd)
1751
socklen_t len = sizeof addr;
1754
if (-1 != getsockname(sd, (struct sockaddr *) &addr, &len)) {
1755
gboolean can_supersede;
1757
ip = socket_addr_get_ip(&addr);
1760
* If local IP was unknown, keep what we got here, even if it's a
1761
* private IP. Otherwise, we discard private IPs unless the previous
1766
can_supersede = !is_private_ip(ip) || is_private_ip(local_ip);
1769
if (!local_ip || can_supersede)
1770
gnet_prop_set_guint32_val(PROP_LOCAL_IP, ip);
1772
} else if (can_supersede)
1773
gnet_prop_set_guint32_val(PROP_LOCAL_IP, ip);
1778
* @return socket's local port, or -1 on error.
1781
socket_local_port(struct gnutella_socket *s)
1784
socklen_t len = sizeof addr;
1786
if (getsockname(s->file_desc, (struct sockaddr *) &addr, &len) == -1)
1789
return socket_addr_get_port(&addr);
1793
* Someone is connecting to us.
1796
socket_accept(gpointer data, gint unused_source, inputevt_cond_t cond)
1799
socklen_t len = sizeof addr;
1800
struct gnutella_socket *s = (struct gnutella_socket *) data;
1801
struct gnutella_socket *t = NULL;
1804
(void) unused_source;
1805
g_assert(s->flags & SOCK_F_TCP);
1807
if (cond & INPUT_EVENT_EXCEPTION) {
1808
g_warning("Input exception on TCP listening socket #%d!", s->file_desc);
1809
return; /* Ignore it, what else can we do? */
1813
case SOCK_TYPE_CONTROL:
1816
g_warning("socket_accept(): Unknown listening socket type %d !",
1818
socket_destroy(s, NULL);
1822
sd = accept(s->file_desc, (struct sockaddr *) &addr, &len);
1825
* If we ran out of file descriptors, try to reclaim one from the
1826
* banning pool and retry.
1830
(errno == EMFILE || errno == ENFILE) &&
1831
reclaim_fd != NULL && (*reclaim_fd)()
1833
sd = accept(s->file_desc, (struct sockaddr *) &addr, &len);
1835
g_warning("had to close a banned fd to accept new connection");
1840
g_warning("accept() failed (%s)", g_strerror(errno));
1845
bws_sock_accepted(SOCK_TYPE_HTTP); /* Do not charge Gnet b/w for that */
1850
/* Create a new struct socket for this incoming connection */
1852
fcntl(sd, F_SETFL, O_NONBLOCK); /* Set the file descriptor non blocking */
1854
t = (struct gnutella_socket *) walloc0(sizeof *t);
1857
t->ip = socket_addr_get_ip(&addr);
1858
t->port = socket_addr_get_port(&addr);
1859
t->direction = SOCK_CONN_INCOMING;
1861
t->local_port = s->local_port;
1862
t->getline = getline_make(MAX_LINE_SIZE);
1863
t->flags |= SOCK_F_TCP;
1866
t->tls.enabled = s->tls.enabled; /* Inherit from listening socket */
1867
t->tls.stage = SOCK_TLS_NONE;
1868
t->tls.session = NULL;
1871
g_message("Incoming connection");
1872
#endif /* USE_TLS */
1876
t->flags |= SOCK_F_ESTABLISHED;
1879
case SOCK_TYPE_CONTROL:
1881
inputevt_add(sd, INPUT_EVENT_READ | INPUT_EVENT_EXCEPTION,
1884
* Whilst the socket is attached to that callback, it has been
1885
* freshly accepted and we don't know what we're going to do with
1886
* it. Is it an incoming node connection or an upload request?
1887
* Can't tell until we have read enough bytes.
1889
* However, we must guard against a subtle DOS attack whereby
1890
* someone would connect to us and then send only one byte (say),
1891
* then nothing. The socket would remain connected, without
1892
* being monitored for timeout by the node/upload code.
1894
* Insert the socket to the `sl_incoming' list, and have it
1895
* monitored periodically. We know the socket is on the list
1896
* as soon as it has a non-zero last_update field.
1900
sl_incoming = g_slist_prepend(sl_incoming, t);
1901
t->last_update = time(NULL);
1905
g_assert(0); /* Can't happen */
1909
inet_got_incoming(t->ip); /* Signal we got an incoming connection */
1913
* Someone is sending us a datagram.
1916
socket_udp_accept(gpointer data, gint unused_source, inputevt_cond_t cond)
1918
struct gnutella_socket *s = (struct gnutella_socket *) data;
1919
struct udp_addr *addr;
1920
const socket_addr_t *inaddr;
1923
(void) unused_source;
1924
g_assert(s->flags & SOCK_F_UDP);
1925
g_assert(s->type == SOCK_TYPE_UDP);
1927
if (cond & INPUT_EVENT_EXCEPTION) {
1929
socklen_t error_len = sizeof error;
1931
getsockopt(s->file_desc, SOL_SOCKET, SO_ERROR, &error, &error_len);
1932
g_warning("Input Exception for UDP listening socket #%d: %s",
1933
s->file_desc, g_strerror(error));
1938
* Receive the datagram in the socket's buffer.
1941
addr = (struct udp_addr *) s->resource.handle;
1942
addr->ud_addrlen = sizeof(addr->ud_addr);
1944
r = recvfrom(s->file_desc, s->buffer, sizeof(s->buffer), 0,
1945
&addr->ud_addr, &addr->ud_addrlen);
1947
if (r == (ssize_t) -1) {
1948
g_warning("ignoring datagram reception error: %s", g_strerror(errno));
1952
bws_udp_count_read(r);
1956
* Record remote address.
1959
g_assert(addr->ud_addrlen == sizeof(*inaddr));
1961
inaddr = (const socket_addr_t *) &addr->ud_addr;
1962
s->ip = socket_addr_get_ip(inaddr);
1963
s->port = socket_addr_get_port(inaddr);
1966
* Signal reception of a datagram to the UDP layer.
1973
socket_set_linger(gint fd)
1982
gint timeout = 20; /* timeout in seconds for FIN_WAIT_2 */
1984
if (setsockopt(fd, SOL_TCP, TCP_LINGER2, &timeout, sizeof timeout))
1985
g_warning("setsockopt() for TCP_LINGER2 failed: %s",
1990
static const struct linger zero_linger;
1995
lb.l_linger = 0; /* closes connections with RST */
1996
if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &lb, sizeof lb))
1997
g_warning("setsockopt() for SO_LINGER failed: %s",
2000
#endif /* TCP_LINGER */
2008
* Called to prepare the creation of the socket connection.
2009
* @returns NULL in case of failure.
2011
static struct gnutella_socket *
2012
socket_connect_prepare(guint16 port, enum socket_type type)
2014
struct gnutella_socket *s;
2017
sd = socket(SOCKET_AF, SOCK_STREAM, 0);
2021
* If we ran out of file descriptors, try to reclaim one from the
2022
* banning pool and retry.
2026
(errno == EMFILE || errno == ENFILE) &&
2027
reclaim_fd != NULL && (*reclaim_fd)()
2029
sd = socket(SOCKET_AF, SOCK_STREAM, 0);
2031
g_warning("had to close a banned fd to prepare new connection");
2036
g_warning("unable to create a socket (%s)", g_strerror(errno));
2041
s = walloc0(sizeof *s);
2044
s->direction = SOCK_CONN_OUTGOING;
2047
s->flags |= SOCK_F_TCP;
2050
s->tls.enabled = tls_enforce;
2051
s->tls.stage = SOCK_TLS_NONE;
2052
s->tls.session = NULL;
2054
#endif /* USE_TLS */
2059
setsockopt(s->file_desc, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof option);
2061
setsockopt(s->file_desc, SOL_SOCKET, SO_REUSEADDR, &option, sizeof option);
2063
socket_set_linger(s->file_desc);
2065
/* Set the file descriptor non blocking */
2066
fcntl(s->file_desc, F_SETFL, O_NONBLOCK);
2068
socket_tos_normal(s);
2073
* Called to finalize the creation of the socket connection, which is done
2074
* in two steps since DNS resolving is asynchronous.
2076
static struct gnutella_socket *
2077
socket_connect_finalize(struct gnutella_socket *s, guint32 ip_addr)
2082
g_assert(NULL != s);
2084
if (hostiles_check(ip_addr)) {
2085
g_warning("Not connecting to hostile host %s", ip_to_gchar(ip_addr));
2086
socket_destroy(s, "Not connecting to hostile host");
2091
socket_addr_set(&addr, s->ip, s->port);
2093
inet_connection_attempted(s->ip);
2096
* Now we check if we're forcing a local IP, and make it happen if so.
2099
if (force_local_ip) {
2100
socket_addr_t lcladdr;
2102
socket_addr_set(&lcladdr, forced_local_ip, 0);
2105
* Note: we ignore failures: it will be automatic at connect()
2106
* It's useful only for people forcing the IP without being
2107
* behind a masquerading firewall --RAM.
2109
(void) bind(s->file_desc, (struct sockaddr *) &lcladdr, sizeof lcladdr);
2112
if (proxy_protocol != PROXY_NONE) {
2113
s->direction = SOCK_CONN_PROXY_OUTGOING;
2114
res = proxy_connect(s->file_desc);
2116
res = connect(s->file_desc, (struct sockaddr *) &addr, sizeof addr);
2118
if (res == -1 && errno != EINPROGRESS) {
2119
if (proxy_protocol != PROXY_NONE && (!proxy_ip || !proxy_port)) {
2120
if (errno != EAGAIN) {
2121
g_warning("Proxy isn't properly configured (%s)",
2122
ip_port_to_gchar(proxy_ip, proxy_port));
2124
socket_destroy(s, "Check the proxy configuration");
2128
g_warning("Unable to connect to %s: (%s)",
2129
ip_port_to_gchar(s->ip, s->port), g_strerror(errno));
2131
if (s->adns & SOCK_ADNS_PENDING)
2132
s->adns_msg = "Connection failed";
2134
socket_destroy(s, _("Connection failed"));
2138
s->local_port = socket_local_port(s);
2139
bws_sock_connect(s->type);
2141
/* Set the file descriptor non blocking */
2142
fcntl(s->file_desc, F_SETFL, O_NONBLOCK);
2144
g_assert(0 == s->gdk_tag);
2146
if (proxy_protocol != PROXY_NONE)
2147
s->gdk_tag = inputevt_add(s->file_desc,
2148
INPUT_EVENT_READ | INPUT_EVENT_WRITE | INPUT_EVENT_EXCEPTION,
2149
socket_connected, s);
2151
s->gdk_tag = inputevt_add(s->file_desc,
2152
INPUT_EVENT_WRITE | INPUT_EVENT_EXCEPTION,
2153
socket_connected, s);
2159
* Creates a connected socket with an attached resource of `type'.
2161
* Connection happens in the background, the connection callback being
2162
* determined by the resource type.
2164
struct gnutella_socket *
2165
socket_connect(guint32 ip_addr, guint16 port, enum socket_type type)
2167
/* Create a socket and try to connect it to ip:port */
2169
struct gnutella_socket *s;
2171
s = socket_connect_prepare(port, type);
2174
return socket_connect_finalize(s, ip_addr);
2178
* @returns whether bad hostname was reported after a DNS lookup.
2181
socket_bad_hostname(struct gnutella_socket *s)
2183
g_assert(NULL != s);
2185
return (s->adns & SOCK_ADNS_BADNAME) ? TRUE : FALSE;
2189
* Called when we got a reply from the ADNS process.
2192
socket_connect_by_name_helper(guint32 ip_addr, gpointer user_data)
2194
struct gnutella_socket *s = user_data;
2196
g_assert(NULL != s);
2198
if (0 == ip_addr || s->type == SOCK_TYPE_DESTROYING) {
2199
s->adns &= ~SOCK_ADNS_PENDING;
2200
s->adns |= SOCK_ADNS_FAILED | SOCK_ADNS_BADNAME;
2201
s->adns_msg = "Could not resolve address";
2204
if (NULL == socket_connect_finalize(s, ip_addr)) {
2205
s->adns &= ~SOCK_ADNS_PENDING;
2206
s->adns |= SOCK_ADNS_FAILED;
2209
s->adns &= ~SOCK_ADNS_PENDING;
2213
* Like socket_connect() but the remote address is not known and must be
2214
* resolved through async DNS calls.
2216
struct gnutella_socket *
2217
socket_connect_by_name(const gchar *host, guint16 port, enum socket_type type)
2219
/* Create a socket and try to connect it to host:port */
2221
struct gnutella_socket *s;
2223
g_assert(NULL != host);
2224
s = socket_connect_prepare(port, type);
2225
g_return_val_if_fail(NULL != s, NULL);
2226
s->adns |= SOCK_ADNS_PENDING;
2228
!adns_resolve(host, &socket_connect_by_name_helper, s)
2229
&& (s->adns & SOCK_ADNS_FAILED)
2231
/* socket_connect_by_name_helper() was already invoked! */
2233
g_warning("socket_connect_by_name: "
2234
"adns_resolve() failed in synchronous mode");
2235
socket_destroy(s, s->adns_msg);
2243
* Creates a non-blocking TCP listening socket with an attached
2244
* resource of `type'.
2246
struct gnutella_socket *
2247
socket_tcp_listen(guint32 ip, guint16 port, enum socket_type type)
2249
/* Create a socket, then bind() and listen() it */
2253
struct gnutella_socket *s;
2258
sd = socket(SOCKET_AF, SOCK_STREAM, 0);
2260
g_warning("Unable to create a socket (%s)", g_strerror(errno));
2264
s = (struct gnutella_socket *) walloc0(sizeof *s);
2267
s->direction = SOCK_CONN_LISTENING;
2270
s->flags |= SOCK_F_TCP;
2273
setsockopt(sd, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof option);
2275
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof option);
2277
socket_set_linger(s->file_desc);
2279
fcntl(sd, F_SETFL, O_NONBLOCK); /* Set the file descriptor non blocking */
2281
socket_addr_set(&addr, ip ? ip : INADDR_ANY, port);
2283
/* bind() the socket */
2285
if (bind(sd, (struct sockaddr *) &addr, sizeof addr) == -1) {
2286
g_warning("Unable to bind() the socket on port %u (%s)",
2287
(unsigned int) port, g_strerror(errno));
2288
socket_destroy(s, "Unable to bind socket");
2292
/* listen() the socket */
2294
if (listen(sd, 5) == -1) {
2295
g_warning("Unable to listen() the socket (%s)", g_strerror(errno));
2296
socket_destroy(s, "Unable to listen on socket");
2300
/* Get the port of the socket, if needed */
2303
socklen_t len = sizeof addr;
2305
if (getsockname(sd, (struct sockaddr *) &addr, &len) == -1) {
2306
g_warning("Unable to get the port of the socket: "
2307
"getsockname() failed (%s)", g_strerror(errno));
2308
socket_destroy(s, "Can't probe socket for port");
2312
s->local_port = socket_addr_get_port(&addr);
2314
s->local_port = port;
2317
s->tls.enabled = TRUE;
2318
#endif /* USE_TLS */
2320
s->gdk_tag = inputevt_add(sd, INPUT_EVENT_READ | INPUT_EVENT_EXCEPTION,
2327
* Creates a non-blocking listening UDP socket.
2329
struct gnutella_socket *
2330
socket_udp_listen(guint32 ip, guint16 port)
2332
/* Create a socket, then bind() it */
2336
struct gnutella_socket *s;
2338
sd = socket(SOCKET_AF, SOCK_DGRAM, 0);
2340
g_warning("Unable to create a socket (%s)", g_strerror(errno));
2344
s = (struct gnutella_socket *) walloc0(sizeof *s);
2346
s->type = SOCK_TYPE_UDP;
2347
s->direction = SOCK_CONN_LISTENING;
2350
s->flags |= SOCK_F_UDP;
2352
socket_wio_link(s); /* Link to the I/O functions */
2355
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof option);
2357
fcntl(sd, F_SETFL, O_NONBLOCK); /* Set the file descriptor non blocking */
2359
socket_addr_set(&addr, ip ? ip : INADDR_ANY, port);
2361
/* bind() the socket */
2363
if (bind(sd, (struct sockaddr *) &addr, sizeof addr) == -1) {
2364
g_warning("Unable to bind() the socket on port %u (%s)",
2365
port, g_strerror(errno));
2366
socket_destroy(s, "Unable to bind socket");
2371
* Attach the socket information so that we may record the origin
2372
* of the datagrams we receive.
2375
s->resource.handle = walloc(sizeof(struct udp_addr));
2377
/* Get the port of the socket, if needed */
2380
socklen_t len = sizeof addr;
2382
if (getsockname(sd, (struct sockaddr *) &addr, &len) == -1) {
2383
g_warning("Unable to get the port of the socket: "
2384
"getsockname() failed (%s)", g_strerror(errno));
2385
socket_destroy(s, "Can't probe socket for port");
2389
s->local_port = socket_addr_get_port(&addr);
2391
s->local_port = port;
2393
s->gdk_tag = inputevt_add(sd, INPUT_EVENT_READ, socket_udp_accept, s);
2396
* Enlarge the RX buffer on the UDP socket to avoid loosing incoming
2397
* datagrams if we are not able to read them during some time.
2400
sock_recv_buf(s, SOCK_UDP_RECV_BUF, FALSE);
2406
* Set/clear TCP_CORK on the socket.
2408
* When set, TCP will only send out full TCP/IP frames.
2409
* The exact size depends on your LAN interface, but on Ethernet,
2410
* it's about 1500 bytes.
2413
sock_cork(struct gnutella_socket *s, gboolean on)
2415
#if !defined(TCP_CORK) && defined(TCP_NOPUSH)
2416
#define TCP_CORK TCP_NOPUSH /* FreeBSD names it TCP_NOPUSH */
2420
gint arg = on ? 1 : 0;
2422
if (-1 == setsockopt(s->file_desc, sol_tcp(), TCP_CORK, &arg, sizeof(arg)))
2423
g_warning("unable to %s TCP_CORK on fd#%d: %s",
2424
on ? "set" : "clear", s->file_desc, g_strerror(errno));
2428
static gboolean warned = FALSE;
2434
g_warning("TCP_CORK is not implemented on this system");
2437
#endif /* TCP_CORK */
2441
* Internal routine for sock_send_buf() and sock_recv_buf().
2442
* Set send/receive buffer to specified size, and warn if it cannot be done.
2443
* If `shrink' is false, refuse to shrink the buffer if its size is larger.
2446
sock_set_intern(gint fd, gint option, gint size, gchar *type, gboolean shrink)
2452
size = (size + 1) & ~0x1; /* Must be even, round to upper boundary */
2454
len = sizeof(old_len);
2455
if (-1 == getsockopt(fd, SOL_SOCKET, option, &old_len, &len))
2456
g_warning("cannot read old %s buffer length on fd #%d: %s",
2457
type, fd, g_strerror(errno));
2459
/* XXX needs to add metaconfig test */
2461
old_len >>= 1; /* Linux returns twice the real amount */
2464
if (!shrink && old_len >= size) {
2466
printf("socket %s buffer on fd #%d NOT shrank to %d bytes (is %d)\n",
2467
type, fd, size, old_len);
2471
if (-1 == setsockopt(fd, SOL_SOCKET, option, &size, sizeof(size)))
2472
g_warning("cannot set new %s buffer length to %d on fd #%d: %s",
2473
type, size, fd, g_strerror(errno));
2475
len = sizeof(new_len);
2476
if (-1 == getsockopt(fd, SOL_SOCKET, option, &new_len, &len))
2477
g_warning("cannot read new %s buffer length on fd #%d: %s",
2478
type, fd, g_strerror(errno));
2481
new_len >>= 1; /* Linux returns twice the real amount */
2485
printf("socket %s buffer on fd #%d: %d -> %d bytes (now %d) %s\n",
2486
type, fd, old_len, size, new_len,
2487
(new_len == size) ? "OK" : "FAILED");
2491
* Set socket's send buffer to specified size.
2492
* If `shrink' is false, refuse to shrink the buffer if its size is larger.
2495
sock_send_buf(struct gnutella_socket *s, gint size, gboolean shrink)
2497
sock_set_intern(s->file_desc, SO_SNDBUF, size, "send", shrink);
2501
* Set socket's receive buffer to specified size.
2502
* If `shrink' is false, refuse to shrink the buffer if its size is larger.
2505
sock_recv_buf(struct gnutella_socket *s, gint size, gboolean shrink)
2507
sock_set_intern(s->file_desc, SO_RCVBUF, size, "receive", shrink);
2511
* Turn TCP_NODELAY on or off on the socket.
2514
sock_nodelay(struct gnutella_socket *s, gboolean on)
2516
gint arg = on ? 1 : 0;
2519
-1 == setsockopt(s->file_desc, sol_tcp(), TCP_NODELAY, &arg, sizeof arg)
2521
if (errno != ECONNRESET)
2522
g_warning("unable to %s TCP_NODELAY on fd#%d: %s",
2523
on ? "set" : "clear", s->file_desc, g_strerror(errno));
2528
* Shutdown the TX side of the socket.
2531
sock_tx_shutdown(struct gnutella_socket *s)
2533
g_assert(-1 != s->file_desc);
2535
if (s->was_shutdown)
2538
/* EINVAL and ENOTCONN may occur if connect() didn't succeed */
2540
-1 == shutdown(s->file_desc, SHUT_WR) &&
2544
g_warning("unable to shutdown TX on fd#%d: %s",
2545
s->file_desc, g_strerror(errno));
2547
s->was_shutdown = TRUE;
2551
socket_get_fd(struct wrap_io *wio)
2553
struct gnutella_socket *s = wio->ctx;
2554
return s->file_desc;
2558
socket_plain_write(struct wrap_io *wio, gconstpointer buf, size_t size)
2560
struct gnutella_socket *s = wio->ctx;
2563
g_assert(!SOCKET_USES_TLS(s));
2566
return write(s->file_desc, buf, size);
2570
socket_plain_read(struct wrap_io *wio, gpointer buf, size_t size)
2572
struct gnutella_socket *s = wio->ctx;
2575
g_assert(!SOCKET_USES_TLS(s));
2578
return read(s->file_desc, buf, size);
2582
socket_plain_writev(struct wrap_io *wio, const struct iovec *iov, int iovcnt)
2584
struct gnutella_socket *s = wio->ctx;
2587
g_assert(!SOCKET_USES_TLS(s));
2590
return writev(s->file_desc, iov, iovcnt);
2594
socket_plain_readv(struct wrap_io *wio, struct iovec *iov, int iovcnt)
2596
struct gnutella_socket *s = wio->ctx;
2599
g_assert(!SOCKET_USES_TLS(s));
2602
return readv(s->file_desc, iov, iovcnt);
2606
socket_plain_sendto(
2607
struct wrap_io *wio, gnet_host_t *to, gconstpointer buf, size_t size)
2609
struct gnutella_socket *s = wio->ctx;
2614
g_assert(!SOCKET_USES_TLS(s));
2617
socket_addr_set(&addr, to->ip, to->port);
2619
ret = sendto(s->file_desc, buf, size, 0,
2620
(const struct sockaddr *) &addr, sizeof addr);
2622
if ((ssize_t) -1 == ret && udp_debug) {
2625
g_warning("sendto() failed: %s", g_strerror(e));
2632
socket_no_sendto(struct wrap_io *unused_wio, gnet_host_t *unused_to,
2633
gconstpointer unused_buf, size_t unused_size)
2639
g_error("no sendto() routine allowed");
2644
socket_no_write(struct wrap_io *unused_wio,
2645
gconstpointer unused_buf, size_t unused_size)
2650
g_error("no write() routine allowed");
2655
socket_no_writev(struct wrap_io *unused_wio,
2656
const struct iovec *unused_iov, int unused_iovcnt)
2660
(void) unused_iovcnt;
2661
g_error("no writev() routine allowed");
2667
socket_tls_write(struct wrap_io *wio, gconstpointer buf, size_t size)
2669
struct gnutella_socket *s = wio->ctx;
2674
g_assert(size <= INT_MAX);
2675
g_assert(s != NULL);
2676
g_assert(buf != NULL);
2678
g_assert(SOCKET_USES_TLS(s));
2680
if (0 != s->tls.snarf) {
2686
g_assert(NULL != p && 0 != len);
2689
ret = gnutls_record_send(s->tls.session, p, len);
2694
case GNUTLS_E_INTERRUPTED:
2695
case GNUTLS_E_AGAIN:
2696
if (0 == s->tls.snarf) {
2704
case GNUTLS_E_PULL_ERROR:
2705
case GNUTLS_E_PUSH_ERROR:
2706
g_message("%s: errno=\"%s\"", __func__, g_strerror(errno));
2716
if (0 != s->tls.snarf) {
2717
s->tls.snarf -= ret;
2723
g_assert(ret == (ssize_t) -1 || (size_t) ret <= size);
2728
socket_tls_read(struct wrap_io *wio, gpointer buf, size_t size)
2730
struct gnutella_socket *s = wio->ctx;
2733
g_assert(size <= INT_MAX);
2734
g_assert(s != NULL);
2735
g_assert(buf != NULL);
2737
g_assert(SOCKET_USES_TLS(s));
2739
ret = gnutls_record_recv(s->tls.session, buf, size);
2742
case GNUTLS_E_INTERRUPTED:
2743
case GNUTLS_E_AGAIN:
2746
case GNUTLS_E_PULL_ERROR:
2747
case GNUTLS_E_PUSH_ERROR:
2748
g_message("%s: errno=\"%s\"", __func__, g_strerror(errno));
2758
g_assert(ret == (ssize_t) -1 || (size_t) ret <= size);
2763
socket_tls_writev(struct wrap_io *wio, const struct iovec *iov, int iovcnt)
2765
struct gnutella_socket *s = wio->ctx;
2766
ssize_t ret, written;
2769
g_assert(SOCKET_USES_TLS(s));
2770
g_assert(iovcnt > 0);
2772
if (0 != s->tls.snarf) {
2773
ret = gnutls_record_send(s->tls.session, NULL, 0);
2775
g_assert((ssize_t) s->tls.snarf >= ret);
2776
s->tls.snarf -= ret;
2777
if (0 != s->tls.snarf) {
2785
case GNUTLS_E_INTERRUPTED:
2786
case GNUTLS_E_AGAIN:
2789
case GNUTLS_E_PULL_ERROR:
2790
case GNUTLS_E_PUSH_ERROR:
2791
g_message("%s: errno=\"%s\"", __func__, g_strerror(errno));
2802
ret = -2; /* Shut the compiler: iovcnt could still be 0 */
2804
for (i = 0; i < iovcnt; ++i) {
2808
p = iov[i].iov_base;
2809
len = iov[i].iov_len;
2810
g_assert(NULL != p && 0 != len);
2811
ret = gnutls_record_send(s->tls.session, p, len);
2817
case GNUTLS_E_INTERRUPTED:
2818
case GNUTLS_E_AGAIN:
2820
ret = written + len;
2822
case GNUTLS_E_PULL_ERROR:
2823
case GNUTLS_E_PUSH_ERROR:
2824
g_message("%s: errno=\"%s\"", __func__, g_strerror(errno));
2840
g_assert(ret == (ssize_t) -1 || ret >= 0);
2845
socket_tls_readv(struct wrap_io *wio, struct iovec *iov, int iovcnt)
2847
struct gnutella_socket *s = wio->ctx;
2852
g_assert(SOCKET_USES_TLS(s));
2853
g_assert(iovcnt > 0);
2855
ret = 0; /* Shut the compiler: iovcnt could still be 0 */
2856
for (i = 0; i < iovcnt; ++i) {
2860
p = iov[i].iov_base;
2861
len = iov[i].iov_len;
2862
g_assert(NULL != p && 0 != len);
2863
ret = gnutls_record_recv(s->tls.session, p, len);
2867
if ((size_t) ret != len) {
2876
case GNUTLS_E_INTERRUPTED:
2877
case GNUTLS_E_AGAIN:
2885
case GNUTLS_E_PULL_ERROR:
2886
case GNUTLS_E_PUSH_ERROR:
2887
g_message("%s: errno=\"%s\"", __func__, g_strerror(errno));
2898
g_assert(ret == (ssize_t) -1 || ret >= 0);
2901
#endif /* USE_TLS */
2904
socket_wio_link(struct gnutella_socket *s)
2906
g_assert(s->flags & (SOCK_F_TCP | SOCK_F_UDP));
2909
s->wio.fd = socket_get_fd;
2912
if (SOCKET_USES_TLS(s)) {
2913
s->wio.write = socket_tls_write;
2914
s->wio.read = socket_tls_read;
2915
s->wio.writev = socket_tls_writev;
2916
s->wio.readv = socket_tls_readv;
2917
s->wio.sendto = socket_no_sendto;
2919
#endif /* USE_TLS */
2920
if (s->flags & SOCK_F_TCP) {
2921
s->wio.write = socket_plain_write;
2922
s->wio.read = socket_plain_read;
2923
s->wio.writev = socket_plain_writev;
2924
s->wio.readv = socket_plain_readv;
2925
s->wio.sendto = socket_no_sendto;
2926
} else if (s->flags & SOCK_F_UDP) {
2927
s->wio.write = socket_no_write;
2928
s->wio.read = socket_plain_read;
2929
s->wio.writev = socket_no_writev;
2930
s->wio.readv = socket_plain_readv;
2931
s->wio.sendto = socket_plain_sendto;
2941
if (gnutls_global_init()) {
2942
g_warning("%s: gnutls_global_init() failed", __func__);
2945
#endif /* USE_TLS */
2948
/* vi: set ts=4 sw=4 cindent: */