~ubuntu-branches/ubuntu/karmic/gtk-gnutella/karmic

« back to all changes in this revision

Viewing changes to src/core/sockets.c

  • Committer: Bazaar Package Importer
  • Author(s): Anand Kumria
  • Date: 2005-08-04 11:32:05 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050804113205-q746i4lgo3rtlegn
Tags: 0.95.4-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: sockets.c,v 1.36 2005/06/25 01:37:41 daichik Exp $
 
3
 *
 
4
 * Copyright (c) 2001-2003, Raphael Manfredi
 
5
 * Copyright (c) 2000 Daniel Walker (dwalker@cats.ucsc.edu)
 
6
 *
 
7
 *----------------------------------------------------------------------
 
8
 * This file is part of gtk-gnutella.
 
9
 *
 
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.
 
14
 *
 
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.
 
19
 *
 
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
 
22
 *  Foundation, Inc.:
 
23
 *      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
24
 *----------------------------------------------------------------------
 
25
 */
 
26
 
 
27
/**
 
28
 * @ingroup core
 
29
 * @file
 
30
 *
 
31
 * Socket management.
 
32
 *
 
33
 * @author Daniel Walker (dwalker@cats.ucsc.edu)
 
34
 * @date 2000
 
35
 * @author Raphael Manfredi
 
36
 * @date 2001-2003
 
37
 */
 
38
 
 
39
#include "common.h"
 
40
 
 
41
RCSID("$Id: sockets.c,v 1.36 2005/06/25 01:37:41 daichik Exp $");
 
42
 
 
43
#include <netdb.h>
 
44
#include <pwd.h>
 
45
 
 
46
#include "sockets.h"
 
47
#include "downloads.h"
 
48
#include "uploads.h"
 
49
#include "parq.h"
 
50
#include "nodes.h"
 
51
#include "bsched.h"
 
52
#include "ban.h"
 
53
#include "http.h"
 
54
#include "inet.h"
 
55
#include "hostiles.h"
 
56
#include "pproxy.h"
 
57
#include "udp.h"
 
58
#include "settings.h"
 
59
 
 
60
#ifdef USE_REMOTE_CTRL
 
61
#include "shell.h"
 
62
#endif
 
63
 
 
64
#include "if/gnet_property.h"
 
65
#include "if/gnet_property_priv.h"
 
66
 
 
67
#include "lib/adns.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"
 
73
 
 
74
#include "lib/override.h"               /* Must be the last header included */
 
75
 
 
76
#ifdef USE_TLS
 
77
#define TLS_DH_BITS 768
 
78
#endif /* USE_TLS */
 
79
 
 
80
#ifndef SHUT_WR
 
81
/* XXX: This should be handled by Configure because SHUT_* are sometimes
 
82
 *              enums instead of macro definitions.
 
83
 */
 
84
#define SHUT_WR 1                                       /**< Shutdown TX side */
 
85
#endif
 
86
 
 
87
#define RQST_LINE_LENGTH        256             /**< Reasonable estimate for request line */
 
88
#define SOCK_UDP_RECV_BUF       131072  /**< 128K -- Large to avoid loosing dgrams */
 
89
 
 
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 */
 
93
 
 
94
struct gnutella_socket *s_tcp_listen = NULL;
 
95
struct gnutella_socket *s_udp_listen = NULL;
 
96
 
 
97
typedef union socket_addr {
 
98
        struct sockaddr_in inet4;
 
99
#ifdef USE_IPV6_HACK
 
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.
 
103
         */
 
104
#define SOCKET_AF AF_INET6
 
105
        struct sockaddr_in6 inet6;
 
106
#else
 
107
#define SOCKET_AF AF_INET
 
108
#endif
 
109
} socket_addr_t;
 
110
 
 
111
/**
 
112
 * Initializes addr with an IPv4 address and a port number.
 
113
 *
 
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
 
117
 */
 
118
static void
 
119
socket_addr_set(socket_addr_t *addr, guint32 ip, guint16 port)
 
120
{
 
121
        static socket_addr_t zero_addr;
 
122
 
 
123
        g_assert(addr != NULL);
 
124
 
 
125
        *addr = zero_addr;
 
126
        
 
127
#ifdef USE_IPV6_HACK
 
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]);
 
133
#else
 
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);
 
137
#endif
 
138
}
 
139
 
 
140
/**
 
141
 * Retrieves the IPv4 address from a socket_addr_t.
 
142
 *
 
143
 * @param addr a pointer to an initialized socket_addr_t
 
144
 * @return the IPv4 address in host(!) byte order
 
145
 */
 
146
static inline guint32
 
147
socket_addr_get_ip(const socket_addr_t *addr)
 
148
{
 
149
        guint32 ip;
 
150
 
 
151
        g_assert(addr != NULL);
 
152
        
 
153
#ifdef USE_IPV6_HACK
 
154
        READ_GUINT32_BE(&addr->inet6.sin6_addr.s6_addr[12], ip);
 
155
#else
 
156
        ip = htonl(addr->inet4.sin_addr.s_addr);
 
157
#endif
 
158
 
 
159
        return ip;
 
160
}
 
161
 
 
162
/**
 
163
 * Retrieves the port number from a socket_addr_t.
 
164
 *
 
165
 * @param addr a pointer to an initialized socket_addr_t
 
166
 * @return the port number in host byte order
 
167
 */
 
168
static inline guint16
 
169
socket_addr_get_port(const socket_addr_t *addr)
 
170
{
 
171
        g_assert(addr != NULL);
 
172
 
 
173
#ifdef USE_IPV6_HACK
 
174
        return ntohs(addr->inet6.sin6_port);
 
175
#else
 
176
        return ntohs(addr->inet4.sin_port);
 
177
#endif
 
178
}
 
179
 
 
180
/*
 
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
 
183
 * at init time.
 
184
 *              --RAM, 2004-08-18
 
185
 */
 
186
static reclaim_fd_t reclaim_fd = NULL;
 
187
 
 
188
/**
 
189
 * Register fd reclaiming callback.
 
190
 * Use NULL to unregister it.
 
191
 */
 
192
void
 
193
socket_register_fd_reclaimer(reclaim_fd_t callback)
 
194
{
 
195
        reclaim_fd = callback;
 
196
}
 
197
 
 
198
/*
 
199
 * UDP address information for datagrams.
 
200
 */
 
201
struct udp_addr {
 
202
        struct sockaddr ud_addr;
 
203
        socklen_t ud_addrlen;
 
204
};
 
205
 
 
206
struct sockreq {
 
207
        gint8 version;
 
208
        gint8 command;
 
209
        gint16 dstport;
 
210
        gint32 dstip;
 
211
        /* A null terminated username goes here */
 
212
} __attribute__((__packed__));
 
213
 
 
214
struct sockrep {
 
215
        gint8 version;
 
216
        gint8 result;
 
217
        gint16 ignore1;
 
218
        gint32 ignore2;
 
219
} __attribute__((__packed__));
 
220
 
 
221
 
 
222
static gboolean ip_computed = FALSE;
 
223
 
 
224
static GSList *sl_incoming = (GSList *) NULL;   /* To spot inactive sockets */
 
225
 
 
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);
 
230
 
 
231
/*
 
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.
 
235
 *
 
236
 * If the user changes /etc/protocols while running gtkg, things may
 
237
 * go badly.
 
238
 */
 
239
static gboolean sol_got = FALSE;
 
240
static gint sol_tcp_cached = -1;
 
241
static gint sol_ip_cached = -1;
 
242
 
 
243
/**
 
244
 * Compute and cache values for SOL_TCP and SOL_IP.
 
245
 */
 
246
static void
 
247
get_sol(void)
 
248
{
 
249
        struct protoent *pent;
 
250
 
 
251
        pent = getprotobyname("tcp");
 
252
        if (NULL != pent)
 
253
                sol_tcp_cached = pent->p_proto;
 
254
        pent = getprotobyname("ip");
 
255
        if (NULL != pent)
 
256
                sol_ip_cached = pent->p_proto;
 
257
        sol_got = TRUE;
 
258
}
 
259
 
 
260
/**
 
261
 * @returns SOL_TCP.
 
262
 */
 
263
static gint
 
264
sol_tcp(void)
 
265
{
 
266
        g_assert(sol_got);
 
267
        return sol_tcp_cached;
 
268
}
 
269
 
 
270
/**
 
271
 * @returns SOL_IP.
 
272
 */
 
273
static gint
 
274
sol_ip(void)
 
275
{
 
276
        g_assert(sol_got);
 
277
        return sol_ip_cached;
 
278
}
 
279
 
 
280
#ifdef USE_IP_TOS
 
281
 
 
282
/**
 
283
 * Set the TOS on the socket.  Routers can use this information to
 
284
 * better route the IP datagrams.
 
285
 */
 
286
static void
 
287
socket_tos(struct gnutella_socket *s, gint tos)
 
288
{
 
289
        if (!use_ip_tos)
 
290
                return;
 
291
 
 
292
        if (-1 == setsockopt(s->file_desc, sol_ip(), IP_TOS, &tos, sizeof tos)) {
 
293
                const gchar *tosname = "default";
 
294
 
 
295
                switch (tos) {
 
296
                        case 0: break;
 
297
                        case IPTOS_LOWDELAY: tosname = "low delay"; break;
 
298
                        case IPTOS_THROUGHPUT: tosname = "throughput"; break;
 
299
                        default:
 
300
                                g_assert_not_reached();
 
301
                }
 
302
 
 
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));
 
306
        }
 
307
}
 
308
 
 
309
/**
 
310
 * Pick an appropriate default TOS for packets on the socket, based
 
311
 * on the socket's type.
 
312
 */
 
313
void socket_tos_default(struct gnutella_socket *s)
 
314
{
 
315
        switch (s->type) {
 
316
        case SOCK_TYPE_DOWNLOAD: /* ACKs w/ low latency => higher transfer rates */
 
317
                socket_tos_lowdelay(s);
 
318
                break;
 
319
        case SOCK_TYPE_UPLOAD:
 
320
                socket_tos_throughput(s);
 
321
                break;
 
322
        case SOCK_TYPE_CONTROL:
 
323
        case SOCK_TYPE_HTTP:
 
324
        case SOCK_TYPE_PPROXY:
 
325
        default:
 
326
                socket_tos_normal(s);
 
327
        }
 
328
}
 
329
#else
 
330
static void
 
331
socket_tos(struct gnutella_socket *unused_s, gint unused_tos)
 
332
{
 
333
        (void) unused_s;
 
334
        (void) unused_tos;
 
335
        /* Empty */
 
336
}
 
337
 
 
338
void
 
339
socket_tos_default(struct gnutella_socket *unused_s)
 
340
{
 
341
        (void) unused_s;
 
342
        /* Empty */
 
343
}
 
344
#endif /* USE_IP_TOS */
 
345
 
 
346
/**
 
347
 * Set the Type of Service (TOS) field to "normal."
 
348
 */
 
349
void
 
350
socket_tos_normal(struct gnutella_socket *s)
 
351
{
 
352
        socket_tos(s, 0);
 
353
}
 
354
 
 
355
/**
 
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.
 
360
 */
 
361
void
 
362
socket_tos_lowdelay(struct gnutella_socket *s)
 
363
{
 
364
        socket_tos(s, IPTOS_LOWDELAY);
 
365
}
 
366
 
 
367
/**
 
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.
 
372
 */
 
373
void
 
374
socket_tos_throughput(struct gnutella_socket *s)
 
375
{
 
376
        socket_tos(s, IPTOS_THROUGHPUT);
 
377
}
 
378
 
 
379
/**
 
380
 * Got an EOF condition on the socket.
 
381
 */
 
382
void
 
383
socket_eof(struct gnutella_socket *s)
 
384
{
 
385
        g_assert(s != NULL);
 
386
 
 
387
        s->flags |= SOCK_F_EOF;
 
388
}
 
389
 
 
390
static void
 
391
proxy_connect_helper(guint32 addr, gpointer udata)
 
392
{
 
393
        gboolean *in_progress = udata;
 
394
 
 
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));
 
399
}
 
400
 
 
401
/*
 
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
 
404
 */
 
405
static int
 
406
proxy_connect(int fd)
 
407
{
 
408
        static gboolean in_progress = FALSE;
 
409
        socket_addr_t server;
 
410
 
 
411
        if (!proxy_ip &&
 
412
                proxy_port != 0 &&
 
413
                proxy_hostname[0] != '\0'
 
414
        ) {
 
415
                if (!in_progress) {
 
416
                        in_progress = TRUE;
 
417
                        g_warning("Resolving proxy name \"%s\"", proxy_hostname);
 
418
                        adns_resolve(proxy_hostname, proxy_connect_helper, &in_progress);
 
419
                }
 
420
 
 
421
                if (in_progress) {
 
422
                        errno = EAGAIN;
 
423
                        return -1;
 
424
                }
 
425
        }
 
426
 
 
427
        if (!proxy_ip || !proxy_port) {
 
428
                errno = EINVAL;
 
429
                return -1;
 
430
        }
 
431
 
 
432
        socket_addr_set(&server, proxy_ip, proxy_port);
 
433
 
 
434
        return connect(fd, (struct sockaddr *) &server, sizeof server);
 
435
}
 
436
 
 
437
static gint
 
438
send_socks(struct gnutella_socket *s)
 
439
{
 
440
        struct passwd *user;
 
441
        struct sockreq *thisreq;
 
442
        const gchar *name;
 
443
        size_t name_size, length = 0;
 
444
        ssize_t ret;
 
445
        gchar *realreq;
 
446
 
 
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;
 
452
 
 
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);
 
457
        if (!realreq)
 
458
                return -1;
 
459
 
 
460
        /* Copy the username */
 
461
        strncpy(&realreq[sizeof(struct sockreq)], name, name_size);
 
462
 
 
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);
 
469
 
 
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");
 
476
                return -1;
 
477
        }
 
478
 
 
479
        return 0;
 
480
}
 
481
 
 
482
static gint
 
483
recv_socks(struct gnutella_socket *s)
 
484
{
 
485
        ssize_t ret;
 
486
        struct sockrep thisrep;
 
487
        size_t size = sizeof thisrep;
 
488
 
 
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)",
 
492
                        g_strerror(errno));
 
493
                return ECONNREFUSED;
 
494
        }
 
495
        if ((size_t) ret != size) {
 
496
                g_warning("Short reply from SOCKS server");
 
497
                /* Let the application try and see how they go */
 
498
                return ECONNREFUSED;
 
499
        }
 
500
 
 
501
        ret = (ssize_t) -1;
 
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 "
 
507
                                   "on this machine");
 
508
        } else if (thisrep.result == 93) {
 
509
                g_warning("SOCKS server refused connection "
 
510
                                   "because identd and this library "
 
511
                                   "reported different user-ids");
 
512
        } else {
 
513
                ret = 0;
 
514
        }
 
515
 
 
516
        if (ret != 0) {
 
517
                errno = ECONNREFUSED;
 
518
                return -1;
 
519
        }
 
520
 
 
521
        return 0;
 
522
}
 
523
 
 
524
static gint
 
525
connect_http(struct gnutella_socket *s)
 
526
{
 
527
        ssize_t ret;
 
528
        gint parsed;
 
529
        gint status;
 
530
        gchar *str;
 
531
 
 
532
        switch (s->pos) {
 
533
        case 0:
 
534
                {
 
535
                        const gchar *host = ip_port_to_gchar(s->ip, s->port);
 
536
                        size_t size;
 
537
 
 
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");
 
544
                                return -1;
 
545
                        }
 
546
                        s->pos++;
 
547
                        break;
 
548
                }
 
549
        case 1:
 
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",
 
553
                                g_strerror(errno));
 
554
                        return -1;
 
555
                }
 
556
                s->getline = getline_make(HEAD_MAX_SIZE);
 
557
                switch (getline_read(s->getline, s->buffer, ret, &parsed)) {
 
558
                case READ_OVERFLOW:
 
559
                        g_warning("HTTP proxy returned a too long line");
 
560
                        return -1;
 
561
                case READ_DONE:
 
562
                        if (ret != parsed)
 
563
                                memmove(s->buffer, s->buffer + parsed, ret - parsed);
 
564
                        ret -= parsed;
 
565
                        break;
 
566
                case READ_MORE:
 
567
                default:
 
568
                        g_assert(parsed == ret);
 
569
                        return 0;
 
570
                }
 
571
                str = getline_str(s->getline);
 
572
                if ((status = http_status_parse(str, NULL, NULL, NULL, NULL)) < 0) {
 
573
                        g_warning("Bad status line");
 
574
                        return -1;
 
575
                }
 
576
                if ((status / 100) != 2) {
 
577
                        g_warning("Cannot use HTTP proxy: \"%s\"", str);
 
578
                        return -1;
 
579
                }
 
580
                s->pos++;
 
581
 
 
582
                while (ret != 0) {
 
583
                        getline_reset(s->getline);
 
584
                        switch (getline_read(s->getline, s->buffer, ret, &parsed)) {
 
585
                        case READ_OVERFLOW:
 
586
                                g_warning("HTTP proxy returned a too long line");
 
587
                                return -1;
 
588
                        case READ_DONE:
 
589
                                if (ret != parsed)
 
590
                                        memmove(s->buffer, s->buffer + parsed, ret - parsed);
 
591
                                ret -= parsed;
 
592
                                if (getline_length(s->getline) == 0) {
 
593
                                        s->pos++;
 
594
                                        getline_free(s->getline);
 
595
                                        s->getline = NULL;
 
596
                                        return 0;
 
597
                                }
 
598
                                break;
 
599
                        case READ_MORE:
 
600
                        default:
 
601
                                g_assert(parsed == ret);
 
602
                                return 0;
 
603
                        }
 
604
                }
 
605
                break;
 
606
        case 2:
 
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",
 
610
                                g_strerror(errno));
 
611
                        return -1;
 
612
                }
 
613
                while (ret != 0) {
 
614
                        getline_reset(s->getline);
 
615
                        switch (getline_read(s->getline, s->buffer, ret, &parsed)) {
 
616
                        case READ_OVERFLOW:
 
617
                                g_warning("HTTP proxy returned a too long line");
 
618
                                return -1;
 
619
                        case READ_DONE:
 
620
                                if (ret != parsed)
 
621
                                        memmove(s->buffer, s->buffer + parsed, ret - parsed);
 
622
                                ret -= parsed;
 
623
                                if (getline_length(s->getline) == 0) {
 
624
                                        s->pos++;
 
625
                                        getline_free(s->getline);
 
626
                                        s->getline = NULL;
 
627
                                        return 0;
 
628
                                }
 
629
                                break;
 
630
                        case READ_MORE:
 
631
                        default:
 
632
                                g_assert(parsed == ret);
 
633
                                return 0;
 
634
                        }
 
635
                }
 
636
                break;
 
637
        }
 
638
 
 
639
        return 0;
 
640
}
 
641
 
 
642
/*
 
643
0: Send
 
644
1: Recv
 
645
..
 
646
4: Send
 
647
5: Recv
 
648
 
 
649
6: Done
 
650
*/
 
651
 
 
652
static gint
 
653
connect_socksv5(struct gnutella_socket *s)
 
654
{
 
655
        ssize_t ret = 0;
 
656
        size_t size;
 
657
        static const gchar verstring[] = "\x05\x02\x02";
 
658
        const gchar *name;
 
659
        gint sockid;
 
660
 
 
661
        sockid = s->file_desc;
 
662
 
 
663
        switch (s->pos) {
 
664
        case 0:
 
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");
 
671
                        return -1;
 
672
                }
 
673
                s->pos++;
 
674
                break;
 
675
 
 
676
        case 1:
 
677
                /* Now receive the reply as to which method we're using */
 
678
                size = 2;
 
679
                ret = read(sockid, s->buffer, size);
 
680
                if (ret == (ssize_t) -1) {
 
681
                        g_warning("Receiving SOCKS method negotiation reply failed: %s",
 
682
                                g_strerror(errno));
 
683
                        return ECONNREFUSED;
 
684
                }
 
685
 
 
686
                if ((size_t) ret != size) {
 
687
                        g_warning("Short reply from SOCKS server");
 
688
                        return ECONNREFUSED;
 
689
                }
 
690
 
 
691
                /* See if we offered an acceptable method */
 
692
                if (s->buffer[1] == '\xff') {
 
693
                        g_warning("SOCKS server refused authentication methods");
 
694
                        return ECONNREFUSED;
 
695
                }
 
696
 
 
697
                if (s->buffer[1] == 2 && socks_user != NULL && socks_user[0] != '\0') {
 
698
                        /* has provided user info */
 
699
                        s->pos++;
 
700
                } else {
 
701
                        s->pos += 3;
 
702
                }
 
703
                break;
 
704
        case 2:
 
705
                /* If the socks server chose username/password authentication */
 
706
                /* (method 2) then do that */
 
707
 
 
708
                if (socks_user != NULL) {
 
709
                        name = socks_user;
 
710
                } else {
 
711
                        const struct passwd *pw;
 
712
 
 
713
                        /* Determine the current *nix username */
 
714
                        pw = getpwuid(getuid());
 
715
                        name = pw != NULL ? pw->pw_name : NULL;
 
716
                }
 
717
 
 
718
                if (name == NULL) {
 
719
                        g_warning("No Username to authenticate with.");
 
720
                        return ECONNREFUSED;
 
721
                }
 
722
 
 
723
                if (socks_pass == NULL) {
 
724
                        g_warning("No Password to authenticate with.");
 
725
                        return ECONNREFUSED;
 
726
                }
 
727
 
 
728
                if (strlen(name) > 255 || strlen(socks_pass) > 255) {
 
729
                        g_warning("Username or password exceeds 255 characters.");
 
730
                        return ECONNREFUSED;
 
731
                }
 
732
 
 
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);
 
736
 
 
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");
 
742
                        return -1;
 
743
                }
 
744
 
 
745
                s->pos++;
 
746
 
 
747
                break;
 
748
        case 3:
 
749
                /* Receive the authentication response */
 
750
                size = 2;
 
751
                ret = read(sockid, s->buffer, size);
 
752
                if (ret == (ssize_t) -1) {
 
753
                        g_warning("Receiving SOCKS authentication reply failed: %s",
 
754
                                g_strerror(errno));
 
755
                        return ECONNREFUSED;
 
756
                }
 
757
 
 
758
                if ((size_t) ret != size) {
 
759
                        g_warning("Short reply from SOCKS server");
 
760
                        return ECONNREFUSED;
 
761
                }
 
762
 
 
763
                if (s->buffer[1] != '\0') {
 
764
                        g_warning("SOCKS authentication failed, "
 
765
                                           "check username and password");
 
766
                        return ECONNREFUSED;
 
767
                }
 
768
                s->pos++;
 
769
                break;
 
770
        case 4:
 
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]);
 
778
 
 
779
                /* Now send the connection */
 
780
 
 
781
                size = 10;
 
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");
 
786
                        return (-1);
 
787
                }
 
788
 
 
789
                s->pos++;
 
790
                break;
 
791
        case 5:
 
792
                /* Now receive the reply to see if we connected */
 
793
 
 
794
                size = 10;
 
795
                ret = read(sockid, s->buffer, size);
 
796
                if (ret == (ssize_t) -1) {
 
797
                        g_warning("Receiving SOCKS connection reply failed: %s",
 
798
                                g_strerror(errno));
 
799
                        return ECONNREFUSED;
 
800
                }
 
801
                if (dbg)
 
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");
 
805
                        return ECONNREFUSED;
 
806
                }
 
807
 
 
808
                /* See the connection succeeded */
 
809
                if (s->buffer[1] != '\0') {
 
810
                        g_warning("SOCKS connect failed: ");
 
811
                        switch (s->buffer[1]) {
 
812
                        case 1:
 
813
                                g_warning("General SOCKS server failure");
 
814
                                return ECONNABORTED;
 
815
                        case 2:
 
816
                                g_warning("Connection denied by rule");
 
817
                                return ECONNABORTED;
 
818
                        case 3:
 
819
                                g_warning("Network unreachable");
 
820
                                return ENETUNREACH;
 
821
                        case 4:
 
822
                                g_warning("Host unreachable");
 
823
                                return EHOSTUNREACH;
 
824
                        case 5:
 
825
                                g_warning("Connection refused");
 
826
                                return ECONNREFUSED;
 
827
                        case 6:
 
828
                                g_warning("TTL Expired");
 
829
                                return ETIMEDOUT;
 
830
                        case 7:
 
831
                                g_warning("Command not supported");
 
832
                                return ECONNABORTED;
 
833
                        case 8:
 
834
                                g_warning("Address type not supported");
 
835
                                return ECONNABORTED;
 
836
                        default:
 
837
                                g_warning("Unknown error");
 
838
                                return ECONNABORTED;
 
839
                        }
 
840
                }
 
841
 
 
842
                s->pos++;
 
843
                break;
 
844
        }
 
845
 
 
846
        return 0;
 
847
}
 
848
 
 
849
 
 
850
/**
 
851
 * Called by main timer.
 
852
 * Expires inactive sockets.
 
853
 */
 
854
void
 
855
socket_timer(time_t now)
 
856
{
 
857
        GSList *l;
 
858
        GSList *to_remove = NULL;
 
859
 
 
860
        for (l = sl_incoming; l; l = g_slist_next(l)) {
 
861
                struct gnutella_socket *s = (struct gnutella_socket *) l->data;
 
862
                gint32 delta;
 
863
 
 
864
                g_assert(s->last_update);
 
865
                /*
 
866
                 * Last_update can be in the feature due to parq. This is needed
 
867
                 * to avoid dropping the connection
 
868
                 */
 
869
                delta = delta_time(now, s->last_update);
 
870
                if (delta > (gint32) incoming_connecting_timeout) {
 
871
                        if (dbg) {
 
872
                                g_warning("connection from %s timed out (%d bytes read)",
 
873
                                                  ip_to_gchar(s->ip), (int) s->pos);
 
874
                                if (s->pos > 0)
 
875
                                        dump_hex(stderr, "Connection Header",
 
876
                                                s->buffer, MIN(s->pos, 80));
 
877
                        }
 
878
                        to_remove = g_slist_prepend(to_remove, s);
 
879
                }
 
880
        }
 
881
 
 
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");
 
885
        }
 
886
 
 
887
        g_slist_free(to_remove);
 
888
}
 
889
 
 
890
/**
 
891
 * Cleanup data structures on shutdown.
 
892
 */
 
893
void
 
894
socket_shutdown(void)
 
895
{
 
896
        while (sl_incoming)
 
897
                socket_destroy((struct gnutella_socket *) sl_incoming->data, NULL);
 
898
 
 
899
        if (s_tcp_listen) {
 
900
                socket_free(s_tcp_listen);              /* No longer accept connections */
 
901
                s_tcp_listen = NULL;
 
902
        }
 
903
 
 
904
        if (s_udp_listen) {
 
905
                socket_free(s_udp_listen);              /* No longer accept connections */
 
906
                s_udp_listen = NULL;
 
907
        }
 
908
}
 
909
 
 
910
/* ----------------------------------------- */
 
911
 
 
912
/**
 
913
 * Destroy a socket.
 
914
 *
 
915
 * If there is an attached resource, call the resource's termination routine
 
916
 * with the supplied reason.
 
917
 */
 
918
static void
 
919
socket_destroy(struct gnutella_socket *s, const gchar *reason)
 
920
{
 
921
        g_assert(s);
 
922
 
 
923
        /*
 
924
         * If there is an attached resource, its removal routine is responsible
 
925
         * for calling back socket_free().
 
926
         */
 
927
 
 
928
        switch (s->type) {
 
929
        case SOCK_TYPE_CONTROL:
 
930
                if (s->resource.node) {
 
931
                        node_remove(s->resource.node, "%s", reason);
 
932
                        return;
 
933
                }
 
934
                break;
 
935
        case SOCK_TYPE_DOWNLOAD:
 
936
                if (s->resource.download) {
 
937
                        download_stop(s->resource.download, GTA_DL_ERROR, "%s", reason);
 
938
                        return;
 
939
                }
 
940
                break;
 
941
        case SOCK_TYPE_UPLOAD:
 
942
                if (s->resource.upload) {
 
943
                        upload_remove(s->resource.upload, "%s", reason);
 
944
                        return;
 
945
                }
 
946
                break;
 
947
        case SOCK_TYPE_PPROXY:
 
948
                if (s->resource.pproxy) {
 
949
                        pproxy_remove(s->resource.pproxy, "%s", reason);
 
950
                        return;
 
951
                }
 
952
                break;
 
953
        case SOCK_TYPE_HTTP:
 
954
                if (s->resource.handle) {
 
955
                        http_async_error(s->resource.handle, HTTP_ASYNC_IO_ERROR);
 
956
                        return;
 
957
                }
 
958
                break;
 
959
        default:
 
960
                break;
 
961
        }
 
962
 
 
963
        /*
 
964
         * No attached resource, we can simply free this socket then.
 
965
         */
 
966
 
 
967
        socket_free(s);
 
968
}
 
969
 
 
970
struct socket_linger {
 
971
        guint tag;      /* Holds the result of inputevt_add() */        
 
972
};
 
973
 
 
974
static void
 
975
socket_linger_cb(gpointer data, gint fd, inputevt_cond_t unused_cond)
 
976
{
 
977
        struct socket_linger *ctx = data;
 
978
 
 
979
        (void) unused_cond;
 
980
        g_assert(fd >= 0);
 
981
        g_assert(NULL != data);
 
982
        g_assert(0 != ctx->tag);
 
983
 
 
984
        if (close(fd)) {
 
985
                gint e = errno;
 
986
                
 
987
                if (EAGAIN != e && EINTR != e)
 
988
                        g_warning("close(%d) failed: %s", fd, g_strerror(e));
 
989
 
 
990
                /* remove the handler in case of EBADF because it would
 
991
                 * cause looping otherwise */
 
992
                if (EBADF != e)
 
993
                        return;
 
994
        } else {
 
995
                g_message("socket_linger_cb: close() succeeded");
 
996
        }
 
997
 
 
998
        g_source_remove(ctx->tag);
 
999
        wfree(ctx, sizeof *ctx);
 
1000
}
 
1001
 
 
1002
static void
 
1003
socket_linger_close(gint fd)
 
1004
{
 
1005
        struct socket_linger *ctx;
 
1006
 
 
1007
        g_assert(fd >= 0);
 
1008
 
 
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);
 
1014
}
 
1015
 
 
1016
/**
 
1017
 * Dispose of socket, closing connection, removing input callback, and
 
1018
 * reclaiming attached getline buffer.
 
1019
 */
 
1020
void
 
1021
socket_free(struct gnutella_socket *s)
 
1022
{
 
1023
        g_assert(s);
 
1024
 
 
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);
 
1029
        else
 
1030
                bws_sock_connect_timeout(s->type);
 
1031
 
 
1032
        if (s->flags & SOCK_F_UDP) {
 
1033
                if (s->resource.handle)
 
1034
                        wfree(s->resource.handle, sizeof(struct udp_addr));
 
1035
        }
 
1036
        if (s->last_update) {
 
1037
                g_assert(sl_incoming);
 
1038
                sl_incoming = g_slist_remove(sl_incoming, s);
 
1039
                s->last_update = 0;
 
1040
        }
 
1041
        if (s->gdk_tag) {
 
1042
                g_source_remove(s->gdk_tag);
 
1043
                s->gdk_tag = 0;
 
1044
        }
 
1045
        if (s->adns & SOCK_ADNS_PENDING) {
 
1046
                s->type = SOCK_TYPE_DESTROYING;
 
1047
                return;
 
1048
        }
 
1049
        if (s->getline) {
 
1050
                getline_free(s->getline);
 
1051
                s->getline = NULL;
 
1052
        }
 
1053
 
 
1054
#ifdef USE_TLS
 
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);
 
1059
                }
 
1060
                gnutls_deinit(s->tls.session);
 
1061
                s->tls.stage = SOCK_TLS_NONE;
 
1062
        }
 
1063
#endif /* USE_TLS */
 
1064
 
 
1065
        if (s->file_desc != -1) {
 
1066
                if (s->corked)
 
1067
                        sock_cork(s, FALSE);
 
1068
                sock_tx_shutdown(s);
 
1069
                if (close(s->file_desc)) {
 
1070
                        gint e = errno;
 
1071
                        
 
1072
                        if (EAGAIN != e && EINTR != e)
 
1073
                                g_warning("close(%d) failed: %s", s->file_desc, g_strerror(e));
 
1074
 
 
1075
                        if (EBADF != e) /* just in case, as it would cause looping */
 
1076
                                socket_linger_close(s->file_desc);
 
1077
                }
 
1078
                s->file_desc = -1;
 
1079
        }
 
1080
        wfree(s, sizeof *s);
 
1081
}
 
1082
 
 
1083
#ifdef USE_TLS
 
1084
static gnutls_dh_params
 
1085
get_dh_params(void)
 
1086
{
 
1087
        static gnutls_dh_params dh_params;
 
1088
        static gboolean initialized = FALSE;
 
1089
 
 
1090
        if (!initialized) {
 
1091
                if (gnutls_dh_params_init(&dh_params)) {
 
1092
                        g_warning("%s: gnutls_dh_params_init() failed", __func__);
 
1093
                        return NULL;
 
1094
                }
 
1095
        if (gnutls_dh_params_generate2(dh_params, TLS_DH_BITS)) {
 
1096
                        g_warning("%s: gnutls_dh_params_generate2() failed", __func__);
 
1097
                        return NULL;
 
1098
                }
 
1099
                initialized = TRUE;
 
1100
        }
 
1101
        return dh_params;
 
1102
}
 
1103
 
 
1104
static int
 
1105
socket_tls_setup(struct gnutella_socket *s)
 
1106
{
 
1107
        g_assert(s != NULL);
 
1108
 
 
1109
        if (!s->tls.enabled) {
 
1110
                return 1;
 
1111
        }
 
1112
 
 
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,
 
1116
                        0
 
1117
                };
 
1118
                static const int kx_list[] = {
 
1119
                        GNUTLS_KX_ANON_DH,
 
1120
                        0
 
1121
                };
 
1122
                static const int mac_list[] = {
 
1123
                        GNUTLS_MAC_MD5, GNUTLS_MAC_SHA, GNUTLS_MAC_RMD160,
 
1124
                        0
 
1125
                };
 
1126
                gnutls_anon_server_credentials server_cred;
 
1127
                gnutls_anon_client_credentials client_cred;
 
1128
                void *cred;
 
1129
 
 
1130
                if (s->direction == SOCK_CONN_INCOMING) {
 
1131
 
 
1132
                        if (gnutls_anon_allocate_server_credentials(&server_cred)) {
 
1133
                                g_warning("gnutls_anon_allocate_server_credentials() failed");
 
1134
                                goto destroy;
 
1135
                        }
 
1136
 
 
1137
                        gnutls_anon_set_server_dh_params(server_cred, get_dh_params());
 
1138
                        cred = server_cred;
 
1139
 
 
1140
                        if (gnutls_init(&s->tls.session, GNUTLS_SERVER)) {
 
1141
                                g_warning("gnutls_init() failed");
 
1142
                                goto destroy;
 
1143
                        }
 
1144
                        gnutls_dh_set_prime_bits(s->tls.session, TLS_DH_BITS);
 
1145
 
 
1146
                } else {
 
1147
                        if (gnutls_anon_allocate_client_credentials(&client_cred)) {
 
1148
                                g_warning("gnutls_anon_allocate_client_credentials() failed");
 
1149
                                goto destroy;
 
1150
                        }
 
1151
                        cred = client_cred;
 
1152
 
 
1153
                        if (gnutls_init(&s->tls.session, GNUTLS_CLIENT)) {
 
1154
                                g_warning("gnutls_init() failed");
 
1155
                                goto destroy;
 
1156
                        }
 
1157
                }
 
1158
 
 
1159
                if (gnutls_credentials_set(s->tls.session, GNUTLS_CRD_ANON, cred)) {
 
1160
                        g_warning("gnutls_credentials_set() failed");
 
1161
                        goto destroy;
 
1162
                }
 
1163
 
 
1164
#if 0
 
1165
                if (gnutls_set_default_priority(s->tls.session)) {
 
1166
                        g_warning("gnutls_set_default_priority() failed");
 
1167
                        goto destroy;
 
1168
                }
 
1169
#endif
 
1170
 
 
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");
 
1174
                        goto destroy;
 
1175
                }
 
1176
                if (gnutls_kx_set_priority(s->tls.session, kx_list)) {
 
1177
                        g_warning("gnutls_kx_set_priority() failed");
 
1178
                        goto destroy;
 
1179
                }
 
1180
                if (gnutls_mac_set_priority(s->tls.session, mac_list)) {
 
1181
                        g_warning("gnutls_mac_set_priority() failed");
 
1182
                        goto destroy;
 
1183
                }
 
1184
 
 
1185
                gnutls_transport_set_ptr(s->tls.session,
 
1186
                                (gnutls_transport_ptr) s->file_desc);
 
1187
 
 
1188
                s->tls.stage = SOCK_TLS_INITIALIZED;
 
1189
        }
 
1190
 
 
1191
        if (s->tls.stage < SOCK_TLS_ESTABLISHED) {
 
1192
                gint ret;
 
1193
 
 
1194
                ret = gnutls_handshake(s->tls.session);
 
1195
                if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) {
 
1196
                        return 0;
 
1197
                } else if (ret < 0) {
 
1198
                        g_warning("gnutls_handshake() failed");
 
1199
                        gnutls_perror(ret);
 
1200
                        goto destroy;
 
1201
                }
 
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 */
 
1205
        }
 
1206
 
 
1207
        return 1;
 
1208
 
 
1209
destroy:
 
1210
 
 
1211
        socket_destroy(s, "TLS handshake failed");
 
1212
        return 0;
 
1213
}
 
1214
#endif /* USE_TLS */
 
1215
 
 
1216
/**
 
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.
 
1222
 */
 
1223
static void
 
1224
socket_read(gpointer data, gint source, inputevt_cond_t cond)
 
1225
{
 
1226
        ssize_t r;
 
1227
        struct gnutella_socket *s = (struct gnutella_socket *) data;
 
1228
        size_t count;
 
1229
        gint parsed;
 
1230
        gchar *first;
 
1231
        time_t banlimit;
 
1232
 
 
1233
        (void) source;
 
1234
 
 
1235
        if (cond & INPUT_EVENT_EXCEPTION) {
 
1236
                socket_destroy(s, "Input exception");
 
1237
                return;
 
1238
        }
 
1239
 
 
1240
        g_assert(s->pos == 0);          /* We read a line, then leave this callback */
 
1241
 
 
1242
#ifdef USE_TLS
 
1243
        if (s->tls.enabled && s->direction == SOCK_CONN_INCOMING) {
 
1244
                ssize_t ret;
 
1245
                size_t i;
 
1246
                gchar buf[32];
 
1247
 
 
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);
 
1251
                if (ret > 0) {
 
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/",
 
1259
                        };
 
1260
 
 
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';
 
1264
 
 
1265
                        g_message("buf=\"%s\"", buf);
 
1266
 
 
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;
 
1273
                                        break;
 
1274
                                }
 
1275
                        }
 
1276
                } else {
 
1277
 
 
1278
                        if (ret == 0 || (errno != EINTR && errno != EAGAIN)) {
 
1279
                                socket_destroy(s, "Connection reset");
 
1280
                        }
 
1281
 
 
1282
                        /* If recv() failed only temporarily, wait for further data. */
 
1283
                        return;
 
1284
                }
 
1285
 
 
1286
                if (s->tls.enabled && !socket_tls_setup(s))
 
1287
                        return;
 
1288
        }
 
1289
#endif /* USE_TLS */
 
1290
 
 
1291
        g_assert(sizeof(s->buffer) >= s->pos);
 
1292
        count = sizeof(s->buffer) - s->pos;
 
1293
 
 
1294
        /* 1 to allow trailing NUL */
 
1295
        if (count < 1) {
 
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");
 
1300
                return;
 
1301
        }
 
1302
        count--; /* Account for trailing NUL */
 
1303
 
 
1304
        /*
 
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.
 
1308
         *              --RAM, 23/05/2002
 
1309
         */
 
1310
 
 
1311
        count = MIN(count, RQST_LINE_LENGTH);
 
1312
 
 
1313
        r = bws_read(bws.in, &s->wio, s->buffer + s->pos, count);
 
1314
        if (r == 0) {
 
1315
                socket_destroy(s, "Got EOF");
 
1316
                return;
 
1317
        } else if ((ssize_t) -1 == r) {
 
1318
                if (errno != EAGAIN)
 
1319
                        socket_destroy(s, _("Read error"));
 
1320
                return;
 
1321
        }
 
1322
 
 
1323
        s->last_update = time(NULL);
 
1324
        s->pos += r;
 
1325
 
 
1326
        /*
 
1327
         * Get first line.
 
1328
         */
 
1329
 
 
1330
        switch (getline_read(s->getline, s->buffer, s->pos, &parsed)) {
 
1331
        case READ_OVERFLOW:
 
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));
 
1336
                if (
 
1337
                        is_strprefix(s->buffer, "GET ") ||
 
1338
                        is_strprefix(s->buffer, "HEAD ")
 
1339
                )
 
1340
                        http_send_status(s, 414, FALSE, NULL, 0, "Requested URL Too Large");
 
1341
                socket_destroy(s, "Requested URL too large");
 
1342
                return;
 
1343
        case READ_DONE:
 
1344
                if (s->pos != (guint) parsed)
 
1345
                        memmove(s->buffer, s->buffer + parsed, s->pos - parsed);
 
1346
                s->pos -= parsed;
 
1347
                break;
 
1348
        case READ_MORE:         /* ok, but needs more data */
 
1349
        default:
 
1350
                g_assert((guint) parsed == s->pos);
 
1351
                s->pos = 0;
 
1352
                return;
 
1353
        }
 
1354
 
 
1355
        /*
 
1356
         * We come here only when we got the first line of data.
 
1357
         *
 
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.
 
1362
         */
 
1363
 
 
1364
        g_source_remove(s->gdk_tag);
 
1365
        s->gdk_tag = 0;
 
1366
        sl_incoming = g_slist_remove(sl_incoming, s);
 
1367
        s->last_update = 0;
 
1368
 
 
1369
        first = getline_str(s->getline);
 
1370
 
 
1371
        /*
 
1372
         * Always authorize replies for our PUSH requests.
 
1373
         * Likewise for PARQ download resuming.
 
1374
         */
 
1375
 
 
1376
        if (is_strprefix(first, "GIV ")) {
 
1377
                download_push_ack(s);
 
1378
                return;
 
1379
        }
 
1380
 
 
1381
        if (is_strprefix(first, "QUEUE ")) {
 
1382
                parq_download_queue_ack(s);
 
1383
                return;
 
1384
        }
 
1385
 
 
1386
        /*
 
1387
         * Check for banning.
 
1388
         */
 
1389
 
 
1390
        switch (ban_allow(s->ip)) {
 
1391
        case BAN_OK:                            /* Connection authorized */
 
1392
                break;
 
1393
        case BAN_FORCE:                         /* Connection refused, no ack */
 
1394
                ban_force(s);
 
1395
                goto cleanup;
 
1396
        case BAN_MSG:                           /* Send specific 403 error message */
 
1397
                {
 
1398
                        gchar *msg = ban_message(s->ip);
 
1399
 
 
1400
            if (dbg) {
 
1401
                g_message("rejecting connection from banned %s (%s still): %s",
 
1402
                    ip_to_gchar(s->ip), short_time(ban_delay(s->ip)), msg);
 
1403
            }
 
1404
 
 
1405
                        if (is_strprefix(first, GNUTELLA_HELLO))
 
1406
                                send_node_error(s, 403, "%s", msg);
 
1407
                        else
 
1408
                                http_send_status(s, 403, FALSE, NULL, 0, "%s", msg);
 
1409
                }
 
1410
                goto cleanup;
 
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)));
 
1415
                else {
 
1416
                        gint delay = ban_delay(s->ip);
 
1417
                        gchar msg[80];
 
1418
                        http_extra_desc_t hev;
 
1419
 
 
1420
                        gm_snprintf(msg, sizeof(msg)-1, "Retry-After: %d\r\n", delay);
 
1421
 
 
1422
                        hev.he_type = HTTP_EXTRA_LINE;
 
1423
                        hev.he_msg = msg;
 
1424
 
 
1425
                        http_send_status(s, 550, FALSE, &hev, 1, "Banned for %s",
 
1426
                                short_time(delay));
 
1427
                }
 
1428
                goto cleanup;
 
1429
        default:
 
1430
                g_assert(0);                    /* Not reached */
 
1431
        }
 
1432
 
 
1433
        /*
 
1434
         * Check for PARQ banning.
 
1435
         *              -- JA, 29/07/2003
 
1436
         */
 
1437
 
 
1438
        banlimit = parq_banned_source_expire(s->ip);
 
1439
 
 
1440
        if (banlimit > 0) {
 
1441
                if (dbg)
 
1442
                        g_warning("[sockets] PARQ has banned ip %s until %d",
 
1443
                                ip_to_gchar(s->ip), (gint) banlimit);
 
1444
                ban_force(s);
 
1445
                goto cleanup;
 
1446
        }
 
1447
 
 
1448
        /*
 
1449
         * Deny connections from hostile IP addresses.
 
1450
         *
 
1451
         * We do this after banning checks so that if they hammer us, they
 
1452
         * get banned silently.
 
1453
         */
 
1454
 
 
1455
        if (hostiles_check(s->ip)) {
 
1456
                static const gchar msg[] = "Hostile IP address banned";
 
1457
 
 
1458
                if (dbg)
 
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);
 
1463
                else
 
1464
                        http_send_status(s, 550, FALSE, NULL, 0, msg);
 
1465
                goto cleanup;
 
1466
        }
 
1467
 
 
1468
        /*
 
1469
         * Dispatch request. Here we decide what kind of connection this is.
 
1470
         */
 
1471
 
 
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 ")) {
 
1475
                gchar *uri;
 
1476
 
 
1477
                /*
 
1478
                 * We have to decide whether this is an upload request or a
 
1479
                 * push-proxyfication request.
 
1480
                 *
 
1481
                 * In the following code, since sizeof("GET") accounts for the
 
1482
                 * trailing NUL, we will skip the space after the request type.
 
1483
                 */
 
1484
 
 
1485
                uri = first + ((first[0] == 'G') ? sizeof("GET") : sizeof("HEAD"));
 
1486
                uri = skip_ascii_blanks(uri);
 
1487
 
 
1488
                if (is_strprefix(uri, "/gnutella/") || is_strprefix(uri, "/gnet/"))
 
1489
                        pproxy_add(s);
 
1490
                else
 
1491
                        upload_add(s);
 
1492
        }
 
1493
#ifdef USE_REMOTE_CTRL
 
1494
        else if (is_strprefix(first, "HELO "))
 
1495
        shell_add(s);
 
1496
#endif
 
1497
    else
 
1498
                goto unknown;
 
1499
 
 
1500
        /* Socket might be free'ed now */
 
1501
 
 
1502
        return;
 
1503
 
 
1504
unknown:
 
1505
        if (dbg) {
 
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));
 
1509
                if (len > 0)
 
1510
                        dump_hex(stderr, "First Line", first, MIN(len, 160));
 
1511
        }
 
1512
        if (strstr(first, "HTTP"))
 
1513
                http_send_status(s, 501, FALSE, NULL, 0, "Method Not Implemented");
 
1514
        /* FALL THROUGH */
 
1515
 
 
1516
cleanup:
 
1517
        socket_destroy(s, NULL);
 
1518
}
 
1519
 
 
1520
/**
 
1521
 * Callback for outgoing connections!
 
1522
 *
 
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.
 
1528
 */
 
1529
static void
 
1530
socket_connected(gpointer data, gint source, inputevt_cond_t cond)
 
1531
{
 
1532
        /* We are connected to somebody */
 
1533
 
 
1534
        struct gnutella_socket *s = (struct gnutella_socket *) data;
 
1535
 
 
1536
        g_assert(source == s->file_desc);
 
1537
 
 
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);
 
1542
                else
 
1543
                        socket_destroy(s, _("Connection failed"));
 
1544
                return;
 
1545
        }
 
1546
 
 
1547
        s->flags |= SOCK_F_ESTABLISHED;
 
1548
        bws_sock_connected(s->type);
 
1549
 
 
1550
#ifdef USE_TLS
 
1551
        if (!socket_tls_setup(s)) {
 
1552
                return;
 
1553
        }
 
1554
#endif /* USE_TLS */
 
1555
 
 
1556
        if (cond & INPUT_EVENT_READ) {
 
1557
                if (
 
1558
                        proxy_protocol != PROXY_NONE
 
1559
                        && s->direction == SOCK_CONN_PROXY_OUTGOING
 
1560
                ) {
 
1561
                        g_source_remove(s->gdk_tag);
 
1562
                        s->gdk_tag = 0;
 
1563
 
 
1564
                        if (proxy_protocol == PROXY_SOCKSV4) {
 
1565
                                if (recv_socks(s) != 0) {
 
1566
                                        socket_destroy(s, "Error receiving from SOCKS 4 proxy");
 
1567
                                        return;
 
1568
                                }
 
1569
 
 
1570
                                s->direction = SOCK_CONN_OUTGOING;
 
1571
 
 
1572
                                s->gdk_tag =
 
1573
                                        inputevt_add(s->file_desc,
 
1574
                                                                  INPUT_EVENT_READ | INPUT_EVENT_WRITE |
 
1575
                                                                  INPUT_EVENT_EXCEPTION, socket_connected,
 
1576
                                                                  (gpointer) s);
 
1577
                                return;
 
1578
                        } else if (proxy_protocol == PROXY_SOCKSV5) {
 
1579
                                if (connect_socksv5(s) != 0) {
 
1580
                                        socket_destroy(s, "Error conneting to SOCKS 5 proxy");
 
1581
                                        return;
 
1582
                                }
 
1583
 
 
1584
                                if (s->pos > 5) {
 
1585
                                        s->direction = SOCK_CONN_OUTGOING;
 
1586
 
 
1587
                                        s->gdk_tag =
 
1588
                                                inputevt_add(s->file_desc,
 
1589
                                                                          INPUT_EVENT_READ | INPUT_EVENT_WRITE |
 
1590
                                                                          INPUT_EVENT_EXCEPTION,
 
1591
                                                                          socket_connected, (gpointer) s);
 
1592
 
 
1593
                                        return;
 
1594
                                } else
 
1595
                                        s->gdk_tag =
 
1596
                                                inputevt_add(s->file_desc,
 
1597
                                                                          INPUT_EVENT_WRITE |
 
1598
                                                                          INPUT_EVENT_EXCEPTION,
 
1599
                                                                          socket_connected, (gpointer) s);
 
1600
 
 
1601
                                return;
 
1602
 
 
1603
                        } else if (proxy_protocol == PROXY_HTTP) {
 
1604
                                if (connect_http(s) != 0) {
 
1605
                                        socket_destroy(s, "Unable to connect to HTTP proxy");
 
1606
                                        return;
 
1607
                                }
 
1608
 
 
1609
                                if (s->pos > 2) {
 
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);
 
1615
                                        return;
 
1616
                                } else {
 
1617
                                        s->gdk_tag = inputevt_add(s->file_desc,
 
1618
                                                                          INPUT_EVENT_READ | INPUT_EVENT_EXCEPTION,
 
1619
                                                                          socket_connected, (gpointer) s);
 
1620
                                        return;
 
1621
                                }
 
1622
                        }
 
1623
                }
 
1624
        }
 
1625
 
 
1626
        if (0 != (cond & INPUT_EVENT_WRITE)) {
 
1627
                /* We are just connected to our partner */
 
1628
                gint res, option;
 
1629
                socklen_t size = sizeof option;
 
1630
 
 
1631
                g_source_remove(s->gdk_tag);
 
1632
                s->gdk_tag = 0;
 
1633
 
 
1634
                /* Check whether the socket is really connected */
 
1635
 
 
1636
                res = getsockopt(s->file_desc, SOL_SOCKET, SO_ERROR,
 
1637
                                           (void *) &option, &size);
 
1638
 
 
1639
                if (res == -1 || option) {
 
1640
                        if (
 
1641
                                s->type == SOCK_TYPE_DOWNLOAD &&
 
1642
                                s->resource.download &&
 
1643
                                !(is_firewalled || !send_pushes)
 
1644
                        )
 
1645
                                download_fallback_to_push(s->resource.download, FALSE, FALSE);
 
1646
                        else
 
1647
                                socket_destroy(s, _("Connection failed"));
 
1648
                        return;
 
1649
                }
 
1650
 
 
1651
                if (proxy_protocol != PROXY_NONE
 
1652
                        && s->direction == SOCK_CONN_PROXY_OUTGOING) {
 
1653
                        if (proxy_protocol == PROXY_SOCKSV4) {
 
1654
 
 
1655
                                if (send_socks(s) != 0) {
 
1656
                                        socket_destroy(s, "Error sending to SOCKS 4 proxy");
 
1657
                                        return;
 
1658
                                }
 
1659
                        } else if (proxy_protocol == PROXY_SOCKSV5) {
 
1660
                                if (connect_socksv5(s) != 0) {
 
1661
                                        socket_destroy(s, "Error connecting to SOCKS 5 proxy");
 
1662
                                        return;
 
1663
                                }
 
1664
 
 
1665
                        } else if (proxy_protocol == PROXY_HTTP) {
 
1666
                                if (connect_http(s) != 0) {
 
1667
                                        socket_destroy(s, "Error connecting to HTTP proxy");
 
1668
                                        return;
 
1669
                                }
 
1670
                        }
 
1671
 
 
1672
                        s->gdk_tag = inputevt_add(s->file_desc,
 
1673
                                                          INPUT_EVENT_READ | INPUT_EVENT_EXCEPTION,
 
1674
                                                          socket_connected, (gpointer) s);
 
1675
                        return;
 
1676
                }
 
1677
 
 
1678
                inet_connection_succeeded(s->ip);
 
1679
 
 
1680
                s->pos = 0;
 
1681
                memset(s->buffer, 0, sizeof(s->buffer));
 
1682
 
 
1683
                g_assert(s->gdk_tag == 0);
 
1684
 
 
1685
                /*
 
1686
                 * Even though local_ip is persistent, we refresh it after startup,
 
1687
                 * in case the IP changed since last time.
 
1688
                 *              --RAM, 07/05/2002
 
1689
                 */
 
1690
 
 
1691
                guess_local_ip(s->file_desc);
 
1692
 
 
1693
                switch (s->type) {
 
1694
                case SOCK_TYPE_CONTROL:
 
1695
                        {
 
1696
                                struct gnutella_node *n = s->resource.node;
 
1697
 
 
1698
                                g_assert(n->socket == s);
 
1699
                                node_init_outgoing(n);
 
1700
                        }
 
1701
                        break;
 
1702
 
 
1703
                case SOCK_TYPE_DOWNLOAD:
 
1704
                        {
 
1705
                                struct download *d = s->resource.download;
 
1706
 
 
1707
                                g_assert(d->socket == s);
 
1708
                                download_send_request(d);
 
1709
                        }
 
1710
                        break;
 
1711
 
 
1712
                case SOCK_TYPE_UPLOAD:
 
1713
                        {
 
1714
                                struct upload *u = s->resource.upload;
 
1715
 
 
1716
                                g_assert(u->socket == s);
 
1717
                                upload_connect_conf(u);
 
1718
                        }
 
1719
                        break;
 
1720
 
 
1721
                case SOCK_TYPE_HTTP:
 
1722
                        http_async_connected(s->resource.handle);
 
1723
                        break;
 
1724
 
 
1725
                case SOCK_TYPE_CONNBACK:
 
1726
                        node_connected_back(s);
 
1727
                        break;
 
1728
 
 
1729
#ifdef USE_REMOTE_CTRL
 
1730
        case SOCK_TYPE_SHELL:
 
1731
            g_assert_not_reached(); /* FIXME: add code here? */
 
1732
            break;
 
1733
#endif
 
1734
 
 
1735
                default:
 
1736
                        g_warning("socket_connected(): Unknown socket type %d !", s->type);
 
1737
                        socket_destroy(s, NULL);                /* ? */
 
1738
                        break;
 
1739
                }
 
1740
        }
 
1741
 
 
1742
}
 
1743
 
 
1744
/**
 
1745
 * Tries to guess the local IP address.
 
1746
 */
 
1747
static void
 
1748
guess_local_ip(int sd)
 
1749
{
 
1750
        socket_addr_t addr;
 
1751
        socklen_t len = sizeof addr;
 
1752
        guint32 ip;
 
1753
 
 
1754
        if (-1 != getsockname(sd, (struct sockaddr *) &addr, &len)) {
 
1755
                gboolean can_supersede;
 
1756
                
 
1757
                ip = socket_addr_get_ip(&addr);
 
1758
 
 
1759
                /*
 
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
 
1762
                 * IP was private.
 
1763
                 *              --RAM, 17/05/2002
 
1764
                 */
 
1765
 
 
1766
                can_supersede = !is_private_ip(ip) || is_private_ip(local_ip);
 
1767
 
 
1768
                if (!ip_computed) {
 
1769
                        if (!local_ip || can_supersede)
 
1770
                                gnet_prop_set_guint32_val(PROP_LOCAL_IP, ip);
 
1771
                        ip_computed = TRUE;
 
1772
                } else if (can_supersede)
 
1773
                        gnet_prop_set_guint32_val(PROP_LOCAL_IP, ip);
 
1774
        }
 
1775
}
 
1776
 
 
1777
/**
 
1778
 * @return socket's local port, or -1 on error.
 
1779
 */
 
1780
static int
 
1781
socket_local_port(struct gnutella_socket *s)
 
1782
{
 
1783
        socket_addr_t addr;
 
1784
        socklen_t len = sizeof addr;
 
1785
 
 
1786
        if (getsockname(s->file_desc, (struct sockaddr *) &addr, &len) == -1)
 
1787
                return -1;
 
1788
 
 
1789
        return socket_addr_get_port(&addr);
 
1790
}
 
1791
 
 
1792
/**
 
1793
 * Someone is connecting to us.
 
1794
 */
 
1795
static void
 
1796
socket_accept(gpointer data, gint unused_source, inputevt_cond_t cond)
 
1797
{
 
1798
        socket_addr_t addr;
 
1799
        socklen_t len = sizeof addr;
 
1800
        struct gnutella_socket *s = (struct gnutella_socket *) data;
 
1801
        struct gnutella_socket *t = NULL;
 
1802
        gint sd;
 
1803
 
 
1804
        (void) unused_source;
 
1805
        g_assert(s->flags & SOCK_F_TCP);
 
1806
 
 
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? */
 
1810
        }
 
1811
 
 
1812
        switch (s->type) {
 
1813
        case SOCK_TYPE_CONTROL:
 
1814
                break;
 
1815
        default:
 
1816
                g_warning("socket_accept(): Unknown listening socket type %d !",
 
1817
                                  s->type);
 
1818
                socket_destroy(s, NULL);
 
1819
                return;
 
1820
        }
 
1821
 
 
1822
        sd = accept(s->file_desc, (struct sockaddr *) &addr, &len);
 
1823
        if (sd == -1) {
 
1824
                /*
 
1825
                 * If we ran out of file descriptors, try to reclaim one from the
 
1826
                 * banning pool and retry.
 
1827
                 */
 
1828
 
 
1829
                if (
 
1830
                        (errno == EMFILE || errno == ENFILE) &&
 
1831
                        reclaim_fd != NULL && (*reclaim_fd)()
 
1832
                ) {
 
1833
                        sd = accept(s->file_desc, (struct sockaddr *) &addr, &len);
 
1834
                        if (sd >= 0) {
 
1835
                                g_warning("had to close a banned fd to accept new connection");
 
1836
                                goto accepted;
 
1837
                        }
 
1838
                }
 
1839
 
 
1840
                g_warning("accept() failed (%s)", g_strerror(errno));
 
1841
                return;
 
1842
        }
 
1843
 
 
1844
accepted:
 
1845
        bws_sock_accepted(SOCK_TYPE_HTTP);      /* Do not charge Gnet b/w for that */
 
1846
 
 
1847
        if (!local_ip)
 
1848
                guess_local_ip(sd);
 
1849
 
 
1850
        /* Create a new struct socket for this incoming connection */
 
1851
 
 
1852
        fcntl(sd, F_SETFL, O_NONBLOCK); /* Set the file descriptor non blocking */
 
1853
 
 
1854
        t = (struct gnutella_socket *) walloc0(sizeof *t);
 
1855
 
 
1856
        t->file_desc = sd;
 
1857
        t->ip = socket_addr_get_ip(&addr);
 
1858
        t->port = socket_addr_get_port(&addr);
 
1859
        t->direction = SOCK_CONN_INCOMING;
 
1860
        t->type = s->type;
 
1861
        t->local_port = s->local_port;
 
1862
        t->getline = getline_make(MAX_LINE_SIZE);
 
1863
        t->flags |= SOCK_F_TCP;
 
1864
 
 
1865
#ifdef USE_TLS
 
1866
        t->tls.enabled = s->tls.enabled; /* Inherit from listening socket */
 
1867
        t->tls.stage = SOCK_TLS_NONE;
 
1868
        t->tls.session = NULL;
 
1869
        t->tls.snarf = 0;
 
1870
 
 
1871
        g_message("Incoming connection");
 
1872
#endif /* USE_TLS */
 
1873
 
 
1874
        socket_wio_link(t);
 
1875
 
 
1876
        t->flags |= SOCK_F_ESTABLISHED;
 
1877
 
 
1878
        switch (s->type) {
 
1879
        case SOCK_TYPE_CONTROL:
 
1880
                t->gdk_tag =
 
1881
                        inputevt_add(sd, INPUT_EVENT_READ | INPUT_EVENT_EXCEPTION,
 
1882
                                                  socket_read, t);
 
1883
                /*
 
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.
 
1888
                 *
 
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.
 
1893
                 *
 
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.
 
1897
                 *                              --RAM, 07/09/2001
 
1898
                 */
 
1899
 
 
1900
                sl_incoming = g_slist_prepend(sl_incoming, t);
 
1901
                t->last_update = time(NULL);
 
1902
                break;
 
1903
 
 
1904
        default:
 
1905
                g_assert(0);                    /* Can't happen */
 
1906
                break;
 
1907
        }
 
1908
 
 
1909
        inet_got_incoming(t->ip);       /* Signal we got an incoming connection */
 
1910
}
 
1911
 
 
1912
/**
 
1913
 * Someone is sending us a datagram.
 
1914
 */
 
1915
static void
 
1916
socket_udp_accept(gpointer data, gint unused_source, inputevt_cond_t cond)
 
1917
{
 
1918
        struct gnutella_socket *s = (struct gnutella_socket *) data;
 
1919
        struct udp_addr *addr;
 
1920
        const socket_addr_t *inaddr;
 
1921
        ssize_t r;
 
1922
 
 
1923
        (void) unused_source;
 
1924
        g_assert(s->flags & SOCK_F_UDP);
 
1925
        g_assert(s->type == SOCK_TYPE_UDP);
 
1926
 
 
1927
        if (cond & INPUT_EVENT_EXCEPTION) {
 
1928
                gint error;
 
1929
                socklen_t error_len = sizeof error;
 
1930
 
 
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));
 
1934
                return;
 
1935
        }
 
1936
 
 
1937
        /*
 
1938
         * Receive the datagram in the socket's buffer.
 
1939
         */
 
1940
 
 
1941
        addr = (struct udp_addr *) s->resource.handle;
 
1942
        addr->ud_addrlen = sizeof(addr->ud_addr);
 
1943
 
 
1944
        r = recvfrom(s->file_desc, s->buffer, sizeof(s->buffer), 0,
 
1945
                &addr->ud_addr, &addr->ud_addrlen);
 
1946
 
 
1947
        if (r == (ssize_t) -1) {
 
1948
                g_warning("ignoring datagram reception error: %s", g_strerror(errno));
 
1949
                return;
 
1950
        }
 
1951
 
 
1952
        bws_udp_count_read(r);
 
1953
        s->pos = r;
 
1954
 
 
1955
        /*
 
1956
         * Record remote address.
 
1957
         */
 
1958
 
 
1959
        g_assert(addr->ud_addrlen == sizeof(*inaddr));
 
1960
 
 
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);
 
1964
 
 
1965
        /*
 
1966
         * Signal reception of a datagram to the UDP layer.
 
1967
         */
 
1968
 
 
1969
        udp_received(s);
 
1970
}
 
1971
 
 
1972
static inline void
 
1973
socket_set_linger(gint fd)
 
1974
{
 
1975
        g_assert(fd >= 0);
 
1976
 
 
1977
        if (!use_so_linger)
 
1978
                return;
 
1979
        
 
1980
#ifdef TCP_LINGER2
 
1981
        {
 
1982
                gint timeout = 20;      /* timeout in seconds for FIN_WAIT_2 */
 
1983
                
 
1984
                if (setsockopt(fd, SOL_TCP, TCP_LINGER2, &timeout, sizeof timeout))
 
1985
                        g_warning("setsockopt() for TCP_LINGER2 failed: %s",
 
1986
                                g_strerror(errno));
 
1987
        }
 
1988
#else
 
1989
        {
 
1990
                static const struct linger zero_linger;
 
1991
                struct linger lb;
 
1992
 
 
1993
                lb = zero_linger;
 
1994
                lb.l_onoff = 1;
 
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",
 
1998
                                g_strerror(errno));
 
1999
        }       
 
2000
#endif /* TCP_LINGER */
 
2001
}
 
2002
 
 
2003
/*
 
2004
 * Sockets creation
 
2005
 */
 
2006
 
 
2007
/**
 
2008
 * Called to prepare the creation of the socket connection.
 
2009
 * @returns NULL in case of failure.
 
2010
 */
 
2011
static struct gnutella_socket *
 
2012
socket_connect_prepare(guint16 port, enum socket_type type)
 
2013
{
 
2014
        struct gnutella_socket *s;
 
2015
        gint sd, option;
 
2016
 
 
2017
        sd = socket(SOCKET_AF, SOCK_STREAM, 0);
 
2018
 
 
2019
        if (sd == -1) {
 
2020
                /*
 
2021
                 * If we ran out of file descriptors, try to reclaim one from the
 
2022
                 * banning pool and retry.
 
2023
                 */
 
2024
 
 
2025
                if (
 
2026
                        (errno == EMFILE || errno == ENFILE) &&
 
2027
                        reclaim_fd != NULL && (*reclaim_fd)()
 
2028
                ) {
 
2029
                        sd = socket(SOCKET_AF, SOCK_STREAM, 0);
 
2030
                        if (sd >= 0) {
 
2031
                                g_warning("had to close a banned fd to prepare new connection");
 
2032
                                goto created;
 
2033
                        }
 
2034
                }
 
2035
 
 
2036
                g_warning("unable to create a socket (%s)", g_strerror(errno));
 
2037
                return NULL;
 
2038
        }
 
2039
 
 
2040
created:
 
2041
        s = walloc0(sizeof *s);
 
2042
 
 
2043
        s->type = type;
 
2044
        s->direction = SOCK_CONN_OUTGOING;
 
2045
        s->file_desc = sd;
 
2046
        s->port = port;
 
2047
        s->flags |= SOCK_F_TCP;
 
2048
 
 
2049
#ifdef USE_TLS
 
2050
        s->tls.enabled = tls_enforce;
 
2051
        s->tls.stage = SOCK_TLS_NONE;
 
2052
        s->tls.session = NULL;
 
2053
        s->tls.snarf = 0;
 
2054
#endif /* USE_TLS */
 
2055
 
 
2056
        socket_wio_link(s);
 
2057
 
 
2058
        option = 1;
 
2059
        setsockopt(s->file_desc, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof option);
 
2060
        option = 1;
 
2061
        setsockopt(s->file_desc, SOL_SOCKET, SO_REUSEADDR, &option, sizeof option);
 
2062
 
 
2063
        socket_set_linger(s->file_desc);
 
2064
 
 
2065
        /* Set the file descriptor non blocking */
 
2066
        fcntl(s->file_desc, F_SETFL, O_NONBLOCK);
 
2067
 
 
2068
        socket_tos_normal(s);
 
2069
        return s;
 
2070
}
 
2071
 
 
2072
/**
 
2073
 * Called to finalize the creation of the socket connection, which is done
 
2074
 * in two steps since DNS resolving is asynchronous.
 
2075
 */
 
2076
static struct gnutella_socket *
 
2077
socket_connect_finalize(struct gnutella_socket *s, guint32 ip_addr)
 
2078
{
 
2079
        gint res = 0;
 
2080
        socket_addr_t addr;
 
2081
 
 
2082
        g_assert(NULL != s);
 
2083
 
 
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");
 
2087
                return NULL;
 
2088
        }
 
2089
 
 
2090
        s->ip = ip_addr;
 
2091
        socket_addr_set(&addr, s->ip, s->port);
 
2092
 
 
2093
        inet_connection_attempted(s->ip);
 
2094
 
 
2095
        /*
 
2096
         * Now we check if we're forcing a local IP, and make it happen if so.
 
2097
         *   --JSL
 
2098
         */
 
2099
        if (force_local_ip) {
 
2100
                socket_addr_t lcladdr;
 
2101
 
 
2102
                socket_addr_set(&lcladdr, forced_local_ip, 0);
 
2103
 
 
2104
                /*
 
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.
 
2108
                 */
 
2109
                (void) bind(s->file_desc, (struct sockaddr *) &lcladdr, sizeof lcladdr);
 
2110
        }
 
2111
 
 
2112
        if (proxy_protocol != PROXY_NONE) {
 
2113
                s->direction = SOCK_CONN_PROXY_OUTGOING;
 
2114
                res = proxy_connect(s->file_desc);
 
2115
        } else
 
2116
                res = connect(s->file_desc, (struct sockaddr *) &addr, sizeof addr);
 
2117
 
 
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));
 
2123
                        }
 
2124
                        socket_destroy(s, "Check the proxy configuration");
 
2125
                        return NULL;
 
2126
                }
 
2127
 
 
2128
                g_warning("Unable to connect to %s: (%s)",
 
2129
                                ip_port_to_gchar(s->ip, s->port), g_strerror(errno));
 
2130
 
 
2131
                if (s->adns & SOCK_ADNS_PENDING)
 
2132
                        s->adns_msg = "Connection failed";
 
2133
                else
 
2134
                        socket_destroy(s, _("Connection failed"));
 
2135
                return NULL;
 
2136
        }
 
2137
 
 
2138
        s->local_port = socket_local_port(s);
 
2139
        bws_sock_connect(s->type);
 
2140
 
 
2141
        /* Set the file descriptor non blocking */
 
2142
        fcntl(s->file_desc, F_SETFL, O_NONBLOCK);
 
2143
 
 
2144
        g_assert(0 == s->gdk_tag);
 
2145
 
 
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);
 
2150
        else
 
2151
                s->gdk_tag = inputevt_add(s->file_desc,
 
2152
                        INPUT_EVENT_WRITE | INPUT_EVENT_EXCEPTION,
 
2153
                        socket_connected, s);
 
2154
 
 
2155
        return s;
 
2156
}
 
2157
 
 
2158
/**
 
2159
 * Creates a connected socket with an attached resource of `type'.
 
2160
 *
 
2161
 * Connection happens in the background, the connection callback being
 
2162
 * determined by the resource type.
 
2163
 */
 
2164
struct gnutella_socket *
 
2165
socket_connect(guint32 ip_addr, guint16 port, enum socket_type type)
 
2166
{
 
2167
        /* Create a socket and try to connect it to ip:port */
 
2168
 
 
2169
        struct gnutella_socket *s;
 
2170
 
 
2171
        s = socket_connect_prepare(port, type);
 
2172
        if (s == NULL)
 
2173
                return NULL;
 
2174
        return socket_connect_finalize(s, ip_addr);
 
2175
}
 
2176
 
 
2177
/**
 
2178
 * @returns whether bad hostname was reported after a DNS lookup.
 
2179
 */
 
2180
gboolean
 
2181
socket_bad_hostname(struct gnutella_socket *s)
 
2182
{
 
2183
        g_assert(NULL != s);
 
2184
 
 
2185
        return (s->adns & SOCK_ADNS_BADNAME) ? TRUE : FALSE;
 
2186
}
 
2187
 
 
2188
/**
 
2189
 * Called when we got a reply from the ADNS process.
 
2190
 */
 
2191
static void
 
2192
socket_connect_by_name_helper(guint32 ip_addr, gpointer user_data)
 
2193
{
 
2194
        struct gnutella_socket *s = user_data;
 
2195
 
 
2196
        g_assert(NULL != s);
 
2197
 
 
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";
 
2202
                return;
 
2203
        }
 
2204
        if (NULL == socket_connect_finalize(s, ip_addr)) {
 
2205
                s->adns &= ~SOCK_ADNS_PENDING;
 
2206
                s->adns |= SOCK_ADNS_FAILED;
 
2207
                return;
 
2208
        }
 
2209
        s->adns &= ~SOCK_ADNS_PENDING;
 
2210
}
 
2211
 
 
2212
/**
 
2213
 * Like socket_connect() but the remote address is not known and must be
 
2214
 * resolved through async DNS calls.
 
2215
 */
 
2216
struct gnutella_socket *
 
2217
socket_connect_by_name(const gchar *host, guint16 port, enum socket_type type)
 
2218
{
 
2219
        /* Create a socket and try to connect it to host:port */
 
2220
 
 
2221
        struct gnutella_socket *s;
 
2222
 
 
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;
 
2227
        if (
 
2228
                !adns_resolve(host, &socket_connect_by_name_helper, s)
 
2229
                && (s->adns & SOCK_ADNS_FAILED)
 
2230
        ) {
 
2231
                /*      socket_connect_by_name_helper() was already invoked! */
 
2232
                if (dbg > 0)
 
2233
                        g_warning("socket_connect_by_name: "
 
2234
                                "adns_resolve() failed in synchronous mode");
 
2235
                socket_destroy(s, s->adns_msg);
 
2236
                return NULL;
 
2237
        }
 
2238
 
 
2239
        return s;
 
2240
}
 
2241
 
 
2242
/**
 
2243
 * Creates a non-blocking TCP listening socket with an attached
 
2244
 * resource of `type'.
 
2245
 */
 
2246
struct gnutella_socket *
 
2247
socket_tcp_listen(guint32 ip, guint16 port, enum socket_type type)
 
2248
{
 
2249
        /* Create a socket, then bind() and listen() it */
 
2250
 
 
2251
        int sd, option;
 
2252
        socket_addr_t addr;
 
2253
        struct gnutella_socket *s;
 
2254
 
 
2255
        if (port < 1024)
 
2256
                return NULL;
 
2257
        
 
2258
        sd = socket(SOCKET_AF, SOCK_STREAM, 0);
 
2259
        if (sd == -1) {
 
2260
                g_warning("Unable to create a socket (%s)", g_strerror(errno));
 
2261
                return NULL;
 
2262
        }
 
2263
 
 
2264
        s = (struct gnutella_socket *) walloc0(sizeof *s);
 
2265
 
 
2266
        s->type = type;
 
2267
        s->direction = SOCK_CONN_LISTENING;
 
2268
        s->file_desc = sd;
 
2269
        s->pos = 0;
 
2270
        s->flags |= SOCK_F_TCP;
 
2271
 
 
2272
        option = 1;
 
2273
        setsockopt(sd, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof option);
 
2274
        option = 1;
 
2275
        setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof option);
 
2276
 
 
2277
        socket_set_linger(s->file_desc);
 
2278
 
 
2279
        fcntl(sd, F_SETFL, O_NONBLOCK); /* Set the file descriptor non blocking */
 
2280
 
 
2281
        socket_addr_set(&addr, ip ? ip : INADDR_ANY, port);
 
2282
 
 
2283
        /* bind() the socket */
 
2284
 
 
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");
 
2289
                return NULL;
 
2290
        }
 
2291
 
 
2292
        /* listen() the socket */
 
2293
 
 
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");
 
2297
                return NULL;
 
2298
        }
 
2299
 
 
2300
        /* Get the port of the socket, if needed */
 
2301
 
 
2302
        if (!port) {
 
2303
                socklen_t len = sizeof addr;
 
2304
 
 
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");
 
2309
                        return NULL;
 
2310
                }
 
2311
 
 
2312
                s->local_port = socket_addr_get_port(&addr);
 
2313
        } else
 
2314
                s->local_port = port;
 
2315
 
 
2316
#ifdef USE_TLS
 
2317
        s->tls.enabled = TRUE;
 
2318
#endif /* USE_TLS */
 
2319
 
 
2320
        s->gdk_tag = inputevt_add(sd, INPUT_EVENT_READ | INPUT_EVENT_EXCEPTION,
 
2321
                                          socket_accept, s);
 
2322
 
 
2323
        return s;
 
2324
}
 
2325
 
 
2326
/**
 
2327
 * Creates a non-blocking listening UDP socket.
 
2328
 */
 
2329
struct gnutella_socket *
 
2330
socket_udp_listen(guint32 ip, guint16 port)
 
2331
{
 
2332
        /* Create a socket, then bind() it */
 
2333
 
 
2334
        int sd, option;
 
2335
        socket_addr_t addr;
 
2336
        struct gnutella_socket *s;
 
2337
 
 
2338
        sd = socket(SOCKET_AF, SOCK_DGRAM, 0);
 
2339
        if (sd == -1) {
 
2340
                g_warning("Unable to create a socket (%s)", g_strerror(errno));
 
2341
                return NULL;
 
2342
        }
 
2343
 
 
2344
        s = (struct gnutella_socket *) walloc0(sizeof *s);
 
2345
 
 
2346
        s->type = SOCK_TYPE_UDP;
 
2347
        s->direction = SOCK_CONN_LISTENING;
 
2348
        s->file_desc = sd;
 
2349
        s->pos = 0;
 
2350
        s->flags |= SOCK_F_UDP;
 
2351
 
 
2352
        socket_wio_link(s);                             /* Link to the I/O functions */
 
2353
 
 
2354
        option = 1;
 
2355
        setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof option);
 
2356
 
 
2357
        fcntl(sd, F_SETFL, O_NONBLOCK); /* Set the file descriptor non blocking */
 
2358
 
 
2359
        socket_addr_set(&addr, ip ? ip : INADDR_ANY, port);
 
2360
 
 
2361
        /* bind() the socket */
 
2362
 
 
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");
 
2367
                return NULL;
 
2368
        }
 
2369
 
 
2370
        /*
 
2371
         * Attach the socket information so that we may record the origin
 
2372
         * of the datagrams we receive.
 
2373
         */
 
2374
 
 
2375
        s->resource.handle = walloc(sizeof(struct udp_addr));
 
2376
 
 
2377
        /* Get the port of the socket, if needed */
 
2378
 
 
2379
        if (!port) {
 
2380
                socklen_t len = sizeof addr;
 
2381
 
 
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");
 
2386
                        return NULL;
 
2387
                }
 
2388
 
 
2389
                s->local_port = socket_addr_get_port(&addr);
 
2390
        } else
 
2391
                s->local_port = port;
 
2392
 
 
2393
        s->gdk_tag = inputevt_add(sd, INPUT_EVENT_READ, socket_udp_accept, s);
 
2394
 
 
2395
        /*
 
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.
 
2398
         */
 
2399
 
 
2400
        sock_recv_buf(s, SOCK_UDP_RECV_BUF, FALSE);
 
2401
 
 
2402
        return s;
 
2403
}
 
2404
 
 
2405
/**
 
2406
 * Set/clear TCP_CORK on the socket.
 
2407
 *
 
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.
 
2411
 */
 
2412
void
 
2413
sock_cork(struct gnutella_socket *s, gboolean on)
 
2414
{
 
2415
#if !defined(TCP_CORK) && defined(TCP_NOPUSH)
 
2416
#define TCP_CORK TCP_NOPUSH             /* FreeBSD names it TCP_NOPUSH */
 
2417
#endif
 
2418
 
 
2419
#ifdef TCP_CORK
 
2420
        gint arg = on ? 1 : 0;
 
2421
 
 
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));
 
2425
        else
 
2426
                s->corked = on;
 
2427
#else
 
2428
        static gboolean warned = FALSE;
 
2429
 
 
2430
        (void) s;
 
2431
        (void) on;
 
2432
 
 
2433
        if (!warned)
 
2434
                g_warning("TCP_CORK is not implemented on this system");
 
2435
 
 
2436
        warned = TRUE;
 
2437
#endif /* TCP_CORK */
 
2438
}
 
2439
 
 
2440
/*
 
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.
 
2444
 */
 
2445
static void
 
2446
sock_set_intern(gint fd, gint option, gint size, gchar *type, gboolean shrink)
 
2447
{
 
2448
        gint old_len = 0;
 
2449
        gint new_len = 0;
 
2450
        socklen_t len;
 
2451
 
 
2452
        size = (size + 1) & ~0x1;       /* Must be even, round to upper boundary */
 
2453
 
 
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));
 
2458
 
 
2459
/* XXX needs to add metaconfig test */
 
2460
#ifdef LINUX_SYSTEM
 
2461
        old_len >>= 1;          /* Linux returns twice the real amount */
 
2462
#endif
 
2463
 
 
2464
        if (!shrink && old_len >= size) {
 
2465
                if (dbg > 5)
 
2466
                        printf("socket %s buffer on fd #%d NOT shrank to %d bytes (is %d)\n",
 
2467
                                type, fd, size, old_len);
 
2468
                return;
 
2469
        }
 
2470
 
 
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));
 
2474
 
 
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));
 
2479
 
 
2480
#ifdef LINUX_SYSTEM
 
2481
        new_len >>= 1;          /* Linux returns twice the real amount */
 
2482
#endif
 
2483
 
 
2484
        if (dbg > 5)
 
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");
 
2488
}
 
2489
 
 
2490
/**
 
2491
 * Set socket's send buffer to specified size.
 
2492
 * If `shrink' is false, refuse to shrink the buffer if its size is larger.
 
2493
 */
 
2494
void
 
2495
sock_send_buf(struct gnutella_socket *s, gint size, gboolean shrink)
 
2496
{
 
2497
        sock_set_intern(s->file_desc, SO_SNDBUF, size, "send", shrink);
 
2498
}
 
2499
 
 
2500
/**
 
2501
 * Set socket's receive buffer to specified size.
 
2502
 * If `shrink' is false, refuse to shrink the buffer if its size is larger.
 
2503
 */
 
2504
void
 
2505
sock_recv_buf(struct gnutella_socket *s, gint size, gboolean shrink)
 
2506
{
 
2507
        sock_set_intern(s->file_desc, SO_RCVBUF, size, "receive", shrink);
 
2508
}
 
2509
 
 
2510
/**
 
2511
 * Turn TCP_NODELAY on or off on the socket.
 
2512
 */
 
2513
void
 
2514
sock_nodelay(struct gnutella_socket *s, gboolean on)
 
2515
{
 
2516
        gint arg = on ? 1 : 0;
 
2517
 
 
2518
        if (
 
2519
                -1 == setsockopt(s->file_desc, sol_tcp(), TCP_NODELAY, &arg, sizeof arg)
 
2520
        ) {
 
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));
 
2524
        }
 
2525
}
 
2526
 
 
2527
/**
 
2528
 * Shutdown the TX side of the socket.
 
2529
 */
 
2530
void
 
2531
sock_tx_shutdown(struct gnutella_socket *s)
 
2532
{
 
2533
        g_assert(-1 != s->file_desc);
 
2534
        
 
2535
        if (s->was_shutdown)
 
2536
                return;
 
2537
 
 
2538
        /* EINVAL and ENOTCONN may occur if connect() didn't succeed */
 
2539
        if (
 
2540
                -1 == shutdown(s->file_desc, SHUT_WR) &&
 
2541
                EINVAL != errno &&
 
2542
                ENOTCONN != errno
 
2543
        ) {
 
2544
                g_warning("unable to shutdown TX on fd#%d: %s",
 
2545
                        s->file_desc, g_strerror(errno));
 
2546
        }
 
2547
        s->was_shutdown = TRUE;
 
2548
}
 
2549
 
 
2550
static int
 
2551
socket_get_fd(struct wrap_io *wio)
 
2552
{
 
2553
        struct gnutella_socket *s = wio->ctx;
 
2554
        return s->file_desc;
 
2555
}
 
2556
 
 
2557
static ssize_t
 
2558
socket_plain_write(struct wrap_io *wio, gconstpointer buf, size_t size)
 
2559
{
 
2560
        struct gnutella_socket *s = wio->ctx;
 
2561
 
 
2562
#ifdef USE_TLS
 
2563
        g_assert(!SOCKET_USES_TLS(s));
 
2564
#endif
 
2565
 
 
2566
        return write(s->file_desc, buf, size);
 
2567
}
 
2568
 
 
2569
static ssize_t
 
2570
socket_plain_read(struct wrap_io *wio, gpointer buf, size_t size)
 
2571
{
 
2572
        struct gnutella_socket *s = wio->ctx;
 
2573
 
 
2574
#ifdef USE_TLS
 
2575
        g_assert(!SOCKET_USES_TLS(s));
 
2576
#endif
 
2577
 
 
2578
        return read(s->file_desc, buf, size);
 
2579
}
 
2580
 
 
2581
static ssize_t
 
2582
socket_plain_writev(struct wrap_io *wio, const struct iovec *iov, int iovcnt)
 
2583
{
 
2584
        struct gnutella_socket *s = wio->ctx;
 
2585
 
 
2586
#ifdef USE_TLS
 
2587
        g_assert(!SOCKET_USES_TLS(s));
 
2588
#endif
 
2589
 
 
2590
        return writev(s->file_desc, iov, iovcnt);
 
2591
}
 
2592
 
 
2593
static ssize_t
 
2594
socket_plain_readv(struct wrap_io *wio, struct iovec *iov, int iovcnt)
 
2595
{
 
2596
        struct gnutella_socket *s = wio->ctx;
 
2597
 
 
2598
#ifdef USE_TLS
 
2599
        g_assert(!SOCKET_USES_TLS(s));
 
2600
#endif
 
2601
 
 
2602
        return readv(s->file_desc, iov, iovcnt);
 
2603
}
 
2604
 
 
2605
static ssize_t
 
2606
socket_plain_sendto(
 
2607
        struct wrap_io *wio, gnet_host_t *to, gconstpointer buf, size_t size)
 
2608
{
 
2609
        struct gnutella_socket *s = wio->ctx;
 
2610
        socket_addr_t addr;
 
2611
        ssize_t ret;
 
2612
 
 
2613
#ifdef USE_TLS
 
2614
        g_assert(!SOCKET_USES_TLS(s));
 
2615
#endif
 
2616
 
 
2617
        socket_addr_set(&addr, to->ip, to->port);
 
2618
 
 
2619
        ret = sendto(s->file_desc, buf, size, 0,
 
2620
                (const struct sockaddr *) &addr, sizeof addr);
 
2621
        
 
2622
        if ((ssize_t) -1 == ret && udp_debug) {
 
2623
                gint e = errno;
 
2624
 
 
2625
                g_warning("sendto() failed: %s", g_strerror(e));
 
2626
                errno = e;
 
2627
        }
 
2628
        return ret;
 
2629
}
 
2630
 
 
2631
static ssize_t
 
2632
socket_no_sendto(struct wrap_io *unused_wio, gnet_host_t *unused_to,
 
2633
        gconstpointer unused_buf, size_t unused_size)
 
2634
{
 
2635
        (void) unused_wio;
 
2636
        (void) unused_to;
 
2637
        (void) unused_buf;
 
2638
        (void) unused_size;
 
2639
        g_error("no sendto() routine allowed");
 
2640
        return -1;
 
2641
}
 
2642
 
 
2643
static ssize_t
 
2644
socket_no_write(struct wrap_io *unused_wio,
 
2645
                gconstpointer unused_buf, size_t unused_size)
 
2646
{
 
2647
        (void) unused_wio;
 
2648
        (void) unused_buf;
 
2649
        (void) unused_size;
 
2650
        g_error("no write() routine allowed");
 
2651
        return -1;
 
2652
}
 
2653
 
 
2654
static ssize_t
 
2655
socket_no_writev(struct wrap_io *unused_wio,
 
2656
                const struct iovec *unused_iov, int unused_iovcnt)
 
2657
{
 
2658
        (void) unused_wio;
 
2659
        (void) unused_iov;
 
2660
        (void) unused_iovcnt;
 
2661
        g_error("no writev() routine allowed");
 
2662
        return -1;
 
2663
}
 
2664
 
 
2665
#ifdef USE_TLS
 
2666
static ssize_t
 
2667
socket_tls_write(struct wrap_io *wio, gconstpointer buf, size_t size)
 
2668
{
 
2669
        struct gnutella_socket *s = wio->ctx;
 
2670
        const gchar *p;
 
2671
        size_t len;
 
2672
        ssize_t ret;
 
2673
 
 
2674
        g_assert(size <= INT_MAX);
 
2675
        g_assert(s != NULL);
 
2676
        g_assert(buf != NULL);
 
2677
 
 
2678
        g_assert(SOCKET_USES_TLS(s));
 
2679
 
 
2680
        if (0 != s->tls.snarf) {
 
2681
                p = NULL;
 
2682
                len = 0;
 
2683
        } else {
 
2684
                p = buf;
 
2685
                len = size;
 
2686
                g_assert(NULL != p && 0 != len);
 
2687
        }
 
2688
 
 
2689
        ret = gnutls_record_send(s->tls.session, p, len);
 
2690
        if (ret <= 0) {
 
2691
                switch (ret) {
 
2692
                case 0:
 
2693
                        break;
 
2694
                case GNUTLS_E_INTERRUPTED:
 
2695
                case GNUTLS_E_AGAIN:
 
2696
                        if (0 == s->tls.snarf) {
 
2697
                                s->tls.snarf = len;
 
2698
                                ret = len;
 
2699
                        } else {
 
2700
                                errno = EAGAIN;
 
2701
                                ret = -1;
 
2702
                        }
 
2703
                        break;
 
2704
                case GNUTLS_E_PULL_ERROR:
 
2705
                case GNUTLS_E_PUSH_ERROR:
 
2706
                        g_message("%s: errno=\"%s\"", __func__, g_strerror(errno));
 
2707
                        errno = EIO;
 
2708
                        ret = -1;
 
2709
                        break;
 
2710
                default:
 
2711
                        gnutls_perror(ret);
 
2712
                        errno = EIO;
 
2713
                        ret = -1;
 
2714
                }
 
2715
        } else {
 
2716
                if (0 != s->tls.snarf) {
 
2717
                        s->tls.snarf -= ret;
 
2718
                        errno = EAGAIN;
 
2719
                        ret = -1;
 
2720
                }
 
2721
        }
 
2722
 
 
2723
        g_assert(ret == (ssize_t) -1 || (size_t) ret <= size);
 
2724
        return ret;
 
2725
}
 
2726
 
 
2727
static ssize_t
 
2728
socket_tls_read(struct wrap_io *wio, gpointer buf, size_t size)
 
2729
{
 
2730
        struct gnutella_socket *s = wio->ctx;
 
2731
        ssize_t ret;
 
2732
 
 
2733
        g_assert(size <= INT_MAX);
 
2734
        g_assert(s != NULL);
 
2735
        g_assert(buf != NULL);
 
2736
 
 
2737
        g_assert(SOCKET_USES_TLS(s));
 
2738
 
 
2739
        ret = gnutls_record_recv(s->tls.session, buf, size);
 
2740
        if (ret < 0) {
 
2741
                switch (ret) {
 
2742
                case GNUTLS_E_INTERRUPTED:
 
2743
                case GNUTLS_E_AGAIN:
 
2744
                        errno = EAGAIN;
 
2745
                        break;
 
2746
                case GNUTLS_E_PULL_ERROR:
 
2747
                case GNUTLS_E_PUSH_ERROR:
 
2748
                        g_message("%s: errno=\"%s\"", __func__, g_strerror(errno));
 
2749
                        errno = EIO;
 
2750
                        break;
 
2751
                default:
 
2752
                        gnutls_perror(ret);
 
2753
                        errno = EIO;
 
2754
                }
 
2755
                ret = -1;
 
2756
        }
 
2757
 
 
2758
        g_assert(ret == (ssize_t) -1 || (size_t) ret <= size);
 
2759
        return ret;
 
2760
}
 
2761
 
 
2762
static ssize_t
 
2763
socket_tls_writev(struct wrap_io *wio, const struct iovec *iov, int iovcnt)
 
2764
{
 
2765
        struct gnutella_socket *s = wio->ctx;
 
2766
        ssize_t ret, written;
 
2767
        int i;
 
2768
 
 
2769
        g_assert(SOCKET_USES_TLS(s));
 
2770
        g_assert(iovcnt > 0);
 
2771
 
 
2772
        if (0 != s->tls.snarf) {
 
2773
                ret = gnutls_record_send(s->tls.session, NULL, 0);
 
2774
                if (ret > 0) {
 
2775
                        g_assert((ssize_t) s->tls.snarf >= ret);
 
2776
                        s->tls.snarf -= ret;
 
2777
                        if (0 != s->tls.snarf) {
 
2778
                                errno = EAGAIN;
 
2779
                                return -1;
 
2780
                        }
 
2781
                } else {
 
2782
                        switch (ret) {
 
2783
                        case 0:
 
2784
                                return 0;
 
2785
                        case GNUTLS_E_INTERRUPTED:
 
2786
                        case GNUTLS_E_AGAIN:
 
2787
                                errno = EAGAIN;
 
2788
                                break;
 
2789
                        case GNUTLS_E_PULL_ERROR:
 
2790
                        case GNUTLS_E_PUSH_ERROR:
 
2791
                                g_message("%s: errno=\"%s\"", __func__, g_strerror(errno));
 
2792
                                errno = EIO;
 
2793
                                break;
 
2794
                        default:
 
2795
                                gnutls_perror(ret);
 
2796
                                errno = EIO;
 
2797
                        }
 
2798
                        return -1;
 
2799
                }
 
2800
        }
 
2801
 
 
2802
        ret = -2;       /* Shut the compiler: iovcnt could still be 0 */
 
2803
        written = 0;
 
2804
        for (i = 0; i < iovcnt; ++i) {
 
2805
                gchar *p;
 
2806
                size_t len;
 
2807
 
 
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);
 
2812
                if (ret <= 0) {
 
2813
                        switch (ret) {
 
2814
                        case 0:
 
2815
                                ret = written;
 
2816
                                break;
 
2817
                        case GNUTLS_E_INTERRUPTED:
 
2818
                        case GNUTLS_E_AGAIN:
 
2819
                                s->tls.snarf = len;
 
2820
                                ret = written + len;
 
2821
                                break;
 
2822
                        case GNUTLS_E_PULL_ERROR:
 
2823
                        case GNUTLS_E_PUSH_ERROR:
 
2824
                                g_message("%s: errno=\"%s\"", __func__, g_strerror(errno));
 
2825
                                ret = -1;
 
2826
                                break;
 
2827
                        default:
 
2828
                                gnutls_perror(ret);
 
2829
                                errno = EIO;
 
2830
                                ret = -1;
 
2831
                        }
 
2832
 
 
2833
                        break;
 
2834
                }
 
2835
 
 
2836
                written += ret;
 
2837
                ret = written;
 
2838
        }
 
2839
 
 
2840
        g_assert(ret == (ssize_t) -1 || ret >= 0);
 
2841
        return ret;
 
2842
}
 
2843
 
 
2844
static ssize_t
 
2845
socket_tls_readv(struct wrap_io *wio, struct iovec *iov, int iovcnt)
 
2846
{
 
2847
        struct gnutella_socket *s = wio->ctx;
 
2848
        int i;
 
2849
        size_t rcvd = 0;
 
2850
        ssize_t ret;
 
2851
 
 
2852
        g_assert(SOCKET_USES_TLS(s));
 
2853
        g_assert(iovcnt > 0);
 
2854
 
 
2855
        ret = 0;        /* Shut the compiler: iovcnt could still be 0 */
 
2856
        for (i = 0; i < iovcnt; ++i) {
 
2857
                size_t len;
 
2858
                gchar *p;
 
2859
 
 
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);
 
2864
                if (ret > 0) {
 
2865
                        rcvd += ret;
 
2866
                }
 
2867
                if ((size_t) ret != len) {
 
2868
                        break;
 
2869
                }
 
2870
        }
 
2871
 
 
2872
        if (ret >= 0) {
 
2873
                ret = rcvd;
 
2874
        } else {
 
2875
                switch (ret) {
 
2876
                case GNUTLS_E_INTERRUPTED:
 
2877
                case GNUTLS_E_AGAIN:
 
2878
                        if (0 != rcvd) {
 
2879
                                ret = rcvd;
 
2880
                        } else {
 
2881
                                errno = EAGAIN;
 
2882
                                ret = -1;
 
2883
                        }
 
2884
                        break;
 
2885
                case GNUTLS_E_PULL_ERROR:
 
2886
                case GNUTLS_E_PUSH_ERROR:
 
2887
                        g_message("%s: errno=\"%s\"", __func__, g_strerror(errno));
 
2888
                        errno = EIO;
 
2889
                        ret = -1;
 
2890
                        break;
 
2891
                default:
 
2892
                        gnutls_perror(ret);
 
2893
                        errno = EIO;
 
2894
                        ret = -1;
 
2895
                }
 
2896
        }
 
2897
 
 
2898
        g_assert(ret == (ssize_t) -1 || ret >= 0);
 
2899
        return ret;
 
2900
}
 
2901
#endif /* USE_TLS */
 
2902
 
 
2903
static void
 
2904
socket_wio_link(struct gnutella_socket *s)
 
2905
{
 
2906
        g_assert(s->flags & (SOCK_F_TCP | SOCK_F_UDP));
 
2907
 
 
2908
        s->wio.ctx = s;
 
2909
        s->wio.fd = socket_get_fd;
 
2910
 
 
2911
#ifdef USE_TLS
 
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;
 
2918
        } else
 
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;
 
2932
        }
 
2933
}
 
2934
 
 
2935
void
 
2936
socket_init(void)
 
2937
{
 
2938
        get_sol();
 
2939
 
 
2940
#ifdef USE_TLS
 
2941
        if (gnutls_global_init()) {
 
2942
                g_warning("%s: gnutls_global_init() failed", __func__);
 
2943
        }
 
2944
        get_dh_params();
 
2945
#endif /* USE_TLS */
 
2946
}
 
2947
 
 
2948
/* vi: set ts=4 sw=4 cindent: */