+Missing <time.h> include
[middleman.git] / src / network.c
1 /*
2     MiddleMan filtering proxy server
3     Copyright (C) 2002  Jason McLaughlin
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20 #include <stdio.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <netdb.h>
26 #include <fcntl.h>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <sys/time.h>
30 #include <netinet/tcp.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #include <time.h>
34 #include "proto.h"
35
36 time_t last_dns_expire = 0;
37 extern HASH_TABLE *dns_cache;
38 extern char username[];
39 SOCKLIST socklist[MAXLISTENPORTS];
40 pthread_mutex_t dns_cache_lock = PTHREAD_MUTEX_INITIALIZER;
41
42 /*
43 initialize the socket list
44 */
45 void net_init()
46 {
47         int i;
48
49         for (i = 0; i < MAXLISTENPORTS; i++) {
50                 socklist[i].status = NET_UNUSED;
51                 socklist[i].ip = NULL;
52                 socklist[i].port = 0;
53         }
54 }
55
56 /*
57 open a listening socket on a specific port and ip
58 */
59 int net_listen(int port, char *ip)
60 {
61         int i, x = -1, on = 1;
62         struct sockaddr_in saddr;
63
64         for (i = 0; i < MAXLISTENPORTS; i++) {
65                 if (socklist[i].status == NET_UNUSED) {
66                         x = i;
67                         break;
68                 }
69         }
70
71         if (x == -1)
72                 return -1;
73
74         socklist[x].fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
75         if (socklist[x].fd == -1)
76                 return -1;
77
78         /* this allows the proxy to successfully bind to the socket again when the server is restarted,
79            otherwise it would have to wait for all connections is TIME_WAIT to be cleaned up */
80         setsockopt(socklist[x].fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
81
82         /* TCP_NODELAY prevents the kernel from buffering the socket, which is only useful for interactive
83            connections such as telnet or ssh */
84         setsockopt(socklist[x].fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
85
86         fcntl(socklist[x].fd, F_SETFL, FD_CLOEXEC);
87
88         memset(&saddr, 0, sizeof(struct sockaddr_in));
89
90         saddr.sin_family = AF_INET;
91         saddr.sin_port = htons(port);
92
93         if (ip == NULL)
94                 saddr.sin_addr.s_addr = INADDR_ANY;
95         else
96                 saddr.sin_addr.s_addr = inet_addr(ip);
97
98         i = bind(socklist[x].fd, (struct sockaddr *) &saddr, sizeof(saddr));
99         if (i == -1) {
100                 close(socklist[x].fd);
101                 return -1;
102         }
103
104         i = listen(socklist[x].fd, 25);
105         if (i == -1) {
106                 close(socklist[x].fd);
107                 return -1;
108         }
109
110         if (ip != NULL)
111                 socklist[x].ip = xstrdup(ip);
112         else
113                 socklist[x].ip = NULL;
114
115         socklist[x].port = port;
116         socklist[x].status = NET_LISTEN;
117
118         return x;
119 }
120
121 /*
122 poll on every open listening socket in socklist until timeout is reached (or forever if 
123 timeout is -1), accept then return a pointer to a CONNECTION struct
124 */
125 CONNECTION *net_accept(int timeout)
126 {
127         int i, x = 0, j, newfd;
128         struct sockaddr_in saddr;
129         unsigned int sl = sizeof(struct sockaddr);
130         CONNECTION *connection;
131         struct pollfd pfd[MAXLISTENPORTS];
132
133         for (i = 0; i < MAXLISTENPORTS; i++) {
134                 if (socklist[i].status == NET_LISTEN) {
135                         pfd[x].fd = socklist[i].fd;
136                         pfd[x].events = POLLIN;
137
138                         x++;
139                 } else break;
140         }
141
142         j = p_poll(pfd, x, (timeout != -1) ? timeout * 1000 : -1);
143
144         if (j > 0) {
145                 for (i = 0; i < MAXLISTENPORTS; i++) {
146                         if (pfd[i].revents & POLLIN) {
147                                 newfd = accept(socklist[i].fd, (struct sockaddr *) &saddr, &sl);
148
149                                 if (newfd == -1)
150                                         return NULL;
151
152                                 connection = xmalloc(sizeof(CONNECTION));
153
154                                 connection->client = sock_new(newfd);
155                                 connection->server = NULL;
156                                 connection->port = socklist[i].port;
157                                 connection->ip = xstrdup(inet_ntoa(saddr.sin_addr));
158                                 connection->buffer = FALSE;
159                                 connection->site_host = NULL;
160                                 connection->site_port = -1;
161                                 connection->bypass = connection->obypass = 0;
162                                 connection->header = NULL;
163                                 connection->rheader = NULL;
164                                 connection->keepalive_client = FALSE;
165                                 connection->keepalive_server = FALSE;
166                                 connection->request = FALSE;
167                                 connection->proxy_host = NULL;
168                                 connection->proxy_type = PROXY_DIRECT;
169                                 connection->proxy_username = NULL;
170                                 connection->proxy_password = NULL;
171                                 connection->proxy_domain = NULL;
172                                 connection->proxy_auth = NULL;
173                                 connection->authenticate = FALSE;
174
175                                 return connection;
176                         }
177                 }
178         }
179
180         return NULL;
181 }
182
183 /*
184 open a connection to somewhere and return file descriptor
185 */
186 int net_connect(char *host, int port)
187 {
188         int fd, ret, on = TRUE;
189         HOSTENT *hostent;
190         struct sockaddr_in saddr;
191
192         if (!host || port <= 0)
193                 return ERROR_UNKNOWN;
194
195         memset(&saddr, 0, sizeof(saddr));
196
197         hostent = net_dns(host);
198         if (hostent == NULL)
199                 return ERROR_DNS;
200
201         saddr.sin_addr = *(struct in_addr *)hostent->addr;
202
203         hostent_free(hostent);
204
205         saddr.sin_family = AF_INET;
206         saddr.sin_port = htons(port);
207
208         fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
209         if (fd == -1)
210                 return ERROR_CONNECT;
211
212         setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
213         fcntl(fd, F_SETFL, FD_CLOEXEC);
214
215         ret = connect(fd, (struct sockaddr *) &saddr, sizeof(saddr));
216         if (ret == -1) {
217                 close(fd);
218
219                 return ERROR_CONNECT;
220         }
221
222         return fd;
223 }
224
225 /*
226 close a connection and free used memory from structure
227 */
228 void net_close(CONNECTION * connection)
229 {
230         if (!connection)
231                 return;
232
233         sock_close(connection->client);
234
235         FREE_AND_NULL(connection->ip);
236         FREE_AND_NULL(connection->proxy_host);
237         FREE_AND_NULL(connection->proxy_username);
238         FREE_AND_NULL(connection->proxy_password);
239         FREE_AND_NULL(connection->proxy_domain);
240         FREE_AND_NULL(connection->proxy_auth);
241         FREE_AND_NULL(connection->site_host);
242
243         xfree(connection);
244 }
245
246 /*
247 close all open listening sockets
248 */
249 void net_listen_closeall()
250 {
251         int i;
252
253         for (i = 0; i < MAXLISTENPORTS; i++) {
254                 if (socklist[i].status == NET_LISTEN) {
255                         close(socklist[i].fd);
256                         if (socklist[i].ip != NULL)
257                                 xfree(socklist[i].ip);
258                         socklist[i].status = NET_UNUSED;
259                 }
260         }
261 }
262
263 /*
264 load <network> section from XML_LIST
265 */
266 NETWORK *network_load(NETWORK * network, XML_LIST * xml_list)
267 {
268         NETWORK *network_tmp = network;
269         struct LISTEN_LIST *listen_list = NULL;
270
271         if (network_tmp == NULL) {
272                 network_tmp = xmalloc(sizeof(NETWORK));
273                 network_tmp->listen_list = NULL;
274                 network_tmp->id = 0;
275
276                 network = network_tmp;
277
278                 pthread_rwlock_init(&network_tmp->lock, NULL);
279         } else
280                 listen_list = network->listen_list;
281
282         while ((xml_list = xml_section(xml_list, "<network>"))) {
283                 XML_LIST_LOOP(xml_list, "<network>") {
284                         XML_LIST_CMP(xml_list, "<listen>") {
285                                 listen_list = listen_list_new(listen_list);
286                                 listen_list->id = network->id++;
287
288                                 if (network_tmp->listen_list == NULL)
289                                         network_tmp->listen_list = listen_list;
290                                 XML_LIST_LOOP(xml_list, "<listen>") {
291                                         XML_LIST_CMP(xml_list, "<ip>") {
292                                                 xml_list = xml_list->next;
293                                                 if (xml_list->type == XML_VALUE)
294                                                         listen_list_insert(listen_list, xml_list->item, NULL);
295                                         }
296                                         XML_LIST_CMP(xml_list, "<port>") {
297                                                 xml_list = xml_list->next;
298                                                 if (xml_list->type == XML_VALUE)
299                                                         listen_list_insert(listen_list, NULL, xml_list->item);
300                                         }
301                                 }
302                         }
303                 }
304         }
305
306         return network;
307 }
308
309 XML_LIST *network_xml(NETWORK * network, XML_LIST * xml_list)
310 {
311         char buf[16], *ptr;
312         struct LISTEN_LIST *ll;
313
314         if (network == NULL)
315                 return xml_list;
316
317         pthread_rwlock_rdlock(&network->lock);
318
319         xml_list = xml_list_add(xml_list, "<network>", XML_TAG);
320
321         ll = network->listen_list;
322
323         for (ll = network->listen_list; ll; ll = ll->next) {
324                 xml_list = xml_list_add(xml_list, "<listen>", XML_TAG);
325
326                 xml_list = xml_list_add(xml_list, "<port>", XML_TAG);
327                 snprintf(buf, sizeof(buf), "%d", ll->port);
328                 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
329                 xml_list = xml_list_add(xml_list, "</port>", XML_TAG);
330
331                 if (ll->ip != NULL) {
332                         xml_list = xml_list_add(xml_list, "<ip>", XML_TAG);
333                         ptr = string_to_xml(ll->ip);
334                         xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
335                         xfree(ptr);
336                         xml_list = xml_list_add(xml_list, "</ip>", XML_TAG);
337                 }
338
339                 xml_list = xml_list_add(xml_list, "</listen>", XML_TAG);
340         }
341
342         xml_list = xml_list_add(xml_list, "</network>", XML_TAG);
343
344         pthread_rwlock_unlock(&network->lock);
345
346         return xml_list;
347 }
348 void listen_list_insert(struct LISTEN_LIST *x, char *a, char *b)
349 {
350         if (a != NULL) {
351                 FREE_AND_NULL(x->ip);
352
353                 if (strcmp(a, ""))
354                         x->ip = xstrdup(a);
355         }
356         if (b != NULL)
357                 x->port = atoi(b);
358 }
359
360 struct LISTEN_LIST *listen_list_delete(struct LISTEN_LIST *x)
361 {
362         struct LISTEN_LIST *start = x;
363
364         while (start->prev != NULL)
365                 start = start->prev;
366
367         if (x->next != NULL)
368                 x->next->prev = x->prev;
369         if (x->prev != NULL)
370                 x->prev->next = x->next;
371         else
372                 start = start->next;
373
374         FREE_AND_NULL(x->ip);
375         FREE_AND_NULL(x->proxy);
376
377         xfree(x);
378
379         return start;
380 }
381
382 struct LISTEN_LIST *listen_list_new(struct LISTEN_LIST *x)
383 {
384         if (x == NULL) {
385                 x = xmalloc(sizeof(struct LISTEN_LIST));
386                 x->prev = NULL;
387         } else {
388                 while (x->next != NULL)
389                         x = x->next;
390                 x->next = xmalloc(sizeof(struct LISTEN_LIST));
391                 x->next->prev = x;
392                 x = x->next;
393         }
394         x->port = -1;
395         x->ip = NULL;
396         x->next = NULL;
397
398         return x;
399 }
400
401 /*
402 free memory allocated by network_load
403 */
404 void network_free(NETWORK * network)
405 {
406         struct LISTEN_LIST *listen_list, *tmp_list;
407
408         if (!network)
409                 return;
410
411         listen_list = network->listen_list;
412
413         while (listen_list != NULL) {
414                 tmp_list = listen_list->next;
415                 if (listen_list->ip != NULL)
416                         xfree(listen_list->ip);
417                 if (listen_list->proxy != NULL)
418                         xfree(listen_list->proxy);
419                 xfree(listen_list);
420                 listen_list = tmp_list;
421         }
422
423         pthread_rwlock_destroy(&network->lock);
424
425         xfree(network);
426 }
427
428 /*
429 look through network->listen_list linked list and bind to listening ports
430 */
431 void network_check(NETWORK * network)
432 {
433         int ret;
434         struct LISTEN_LIST *listen_list;
435
436         if (!network)
437                 return;
438
439         listen_list = network->listen_list;
440
441         pthread_rwlock_rdlock(&network->lock);
442
443         while (listen_list != NULL) {
444                 if (listen_list->port != -1) {
445                         ret = net_listen(listen_list->port, listen_list->ip);
446
447                         if (ret != -1)
448                                 putlog(MMLOG_NETWORK, "listening on %s:%d", (listen_list->ip != NULL) ? listen_list->ip : "0.0.0.0", listen_list->port);
449                         else
450                                 putlog(MMLOG_NETWORK, "failed to bind to %s:%d", (listen_list->ip != NULL) ? listen_list->ip : "0.0.0.0", listen_list->port);
451                 }
452
453                 listen_list = listen_list->next;
454         }
455
456         pthread_rwlock_unlock(&network->lock);
457 }
458
459 /*
460 relay anything from one socket to another, and vice versa
461 */
462 int net_proxy(CONNECTION * connection, int len)
463 {
464         int x, bytes = 0;
465         char buf[BLOCKSIZE];
466         struct pollfd pfd[2];
467         SOCKET *sock1, *sock2;
468
469         sock1 = connection->client;
470         sock2 = connection->server;
471
472         pfd[0].fd = sock1->fd;
473         pfd[0].events = POLLIN;
474         pfd[1].fd = sock2->fd;
475         pfd[1].events = POLLIN;
476
477         while (1) {
478                 x = p_poll(pfd, 2, (sock1->inbuf_len != 0 || sock2->inbuf_len != 0) ? 0 : -1);
479                 if (sock1->inbuf_len != 0 || pfd[0].revents & POLLIN) {
480                         x = sock_read(sock1, buf, (len != -1) ? (len - bytes < sizeof(buf)) ? len - bytes : sizeof(buf) : sizeof(buf));
481                         if (x > 0)
482                                 sock_write(sock2, buf, x);
483                         else
484                                 break;
485
486                         bytes += x;
487                 } else if (pfd[0].revents & (POLLHUP | POLLERR))
488                         break;
489
490                 if (sock1->inbuf_len != 0 || pfd[1].revents & POLLIN) {
491                         x = sock_read(sock2, buf, (len != -1) ? (len - bytes < sizeof(buf)) ? len - bytes : sizeof(buf) : sizeof(buf));
492                         if (x > 0)
493                                 sock_write(sock1, buf, x);
494                         else
495                                 break;
496
497                         bytes += x;
498                 } else if (pfd[1].revents & (POLLHUP | POLLERR))
499                         break;
500
501                 if (len != -1 && bytes == len)
502                         break;
503         }
504
505         return bytes;
506 }
507
508 /*
509 tranfer data one way between two sockets
510 */
511 int net_transfer(CONNECTION * connection, int flags, int bytes)
512 {
513         int x;
514         char buf[BLOCKSIZE];
515         struct pollfd pfd[2];
516         SOCKET *sock1, *sock2;
517
518         sock1 = (flags == SERVER) ? connection->server : connection->client;
519         sock2 = (flags == SERVER) ? connection->client : connection->server;
520
521         pfd[0].fd = sock1->fd;
522         pfd[0].events = POLLIN;
523         pfd[1].fd = sock2->fd;
524         pfd[1].events = POLLIN;
525
526         while (bytes == -1 || bytes > 0) {
527                 x = p_poll(pfd, 2, (sock1->inbuf_len != 0) ? 0 : -1);
528                 if (sock1->inbuf_len != 0 || pfd[0].revents & POLLIN) {
529                         x = sock_read(sock1, buf, (bytes != -1) ? (bytes < sizeof(buf)) ? bytes : sizeof(buf) : sizeof(buf));
530
531                         if (bytes != -1)
532                                 bytes -= x;
533
534                         if (x > 0) {
535                                 x = sock_write(sock2, buf, x);
536                                 if (x == -1)
537                                         break;
538                         } else
539                                 break;
540                 } else if (pfd[0].revents & (POLLHUP | POLLERR))
541                         break;
542
543                 if (pfd[1].revents & POLLIN) {
544                         x = sock_read(sock2, NULL, -1);
545                         if (x <= 0)
546                                 break;
547                 } else if (pfd[1].revents & (POLLHUP | POLLERR))
548                         break;
549         }
550
551         return bytes;
552 }
553
554 int putsock(SOCKET * sock, char *format, ...)
555 {
556         char buf[8096];
557         va_list va;
558
559         va_start(va, format);
560         vsnprintf(buf, sizeof(buf), format, va);
561         va_end(va);
562
563         return sock_write(sock, buf, strlen(buf));
564 }
565
566 void net_filebuf_read(FILEBUF * filebuf, CONNECTION * connection, int flags, int bytes)
567 {
568         int x;
569         char buf[BLOCKSIZE];
570         struct pollfd pfd[2];
571         SOCKET *sock1, *sock2;
572
573         sock1 = (flags == SERVER) ? connection->server : connection->client;
574         sock2 = (flags == SERVER) ? connection->client : connection->server;
575
576         pfd[0].fd = sock1->fd;
577         pfd[0].events = POLLIN;
578
579         if (sock2 != NULL) {
580                 pfd[1].fd = sock2->fd;
581                 pfd[1].events = POLLIN;
582         } else pfd[1].revents = 0;
583
584         while (bytes == -1 || bytes > 0) {
585                 x = p_poll(pfd, (sock2 != NULL) ? 2 : 1, (sock1->inbuf_len != 0) ? 0 : -1);
586                 if (sock1->inbuf_len != 0 || pfd[0].revents & POLLIN) {
587                         x = sock_read(sock1, buf, (bytes != -1) ? (bytes < sizeof(buf)) ? bytes : sizeof(buf) : sizeof(buf));
588                         if (x > 0) {
589                                 if (filebuf != NULL) filebuf_add(filebuf, buf, x);
590
591                                 if (bytes != -1)
592                                         bytes -= x;
593                         } else
594                                 break;
595                 } else if (pfd[0].revents & (POLLHUP | POLLERR))
596                         break;
597
598                 if (pfd[1].revents & POLLIN) {
599                         x = sock_read(sock2, NULL, -1);
600                         if (x <= 0)
601                                 break;
602                 } else if (pfd[1].revents & (POLLHUP | POLLERR))
603                         break;
604         }
605 }
606
607 int net_filebuf_send(FILEBUF * filebuf, CONNECTION * connection, int flags)
608 {
609         SOCKET *sock;
610
611         sock = (flags == SERVER) ? connection->server : connection->client;
612
613         return sock_write(sock, filebuf->data, filebuf->size);
614 }
615
616 /*
617 perform a dns lookup, using cached response from a previous lookup if possible
618 */
619 HOSTENT *net_dns(char *host)
620 {
621         time_t t;
622         char *string, hst[128], buf[24];
623         HOSTENT *hostent;
624
625         pthread_mutex_lock(&dns_cache_lock);
626
627         t = time(NULL);
628
629         s_strncpy(hst, host, 128);
630         string_tolower(hst);
631
632         if (last_dns_expire == 0)
633                 last_dns_expire = t;
634
635         if (t - last_dns_expire >= DNS_EXPIRE) {
636                 putlog(MMLOG_DEBUG, "dns cache expire: entry > %d seconds", DNS_EXPIRE);
637
638                 hash_expire(dns_cache, DNS_EXPIRE);
639                 last_dns_expire = t;
640         }
641
642         if (isip(host)) {
643                 hostent = xmalloc(sizeof(HOSTENT));
644                 hostent->addr = xmalloc(sizeof(struct in_addr));
645                 hostent->len = sizeof(struct in_addr);
646
647                 inet_aton(host, hostent->addr);
648         } else {
649                 string = hash_search(dns_cache, hst);
650                 if (string == NULL) {
651                         pthread_mutex_unlock(&dns_cache_lock);
652
653                         hostent = p_gethostbyname(host);
654                         if (hostent == NULL)
655                                 return NULL;
656
657                         pthread_mutex_lock(&dns_cache_lock);
658
659                         s_strncpy(buf, inet_ntoa(*hostent->addr), sizeof(buf));
660
661                         hash_insert(dns_cache, hst, xstrdup(buf));
662
663                         putlog(MMLOG_DEBUG, "dns cache insert: %s -> %s", hst, buf);
664                 } else {
665                         putlog(MMLOG_DEBUG, "dns cache hit: %s -> %s", hst, string);
666
667                         hostent = xmalloc(sizeof(HOSTENT));
668                         hostent->addr = xmalloc(sizeof(struct in_addr));
669                         hostent->len = sizeof(struct in_addr);
670
671                         inet_aton(string, hostent->addr);
672                 }
673         }
674
675         pthread_mutex_unlock(&dns_cache_lock);
676
677         return hostent;
678 }
679
680 /*
681 connect through socks4 server
682 */
683 int net_socks4(CONNECTION * connection, char *host, int port)
684 {
685         int ret;
686         char buf[64];
687         HOSTENT *hostent;
688
689         hostent = net_dns(host);
690         if (hostent == NULL)
691                 return ERROR_DNS;
692
693         ret = snprintf(buf, sizeof(buf), "\004\001%c%c%c%c%c%c%s", (port >> 8) % 256, port % 256, '0', '0', '0', '0', username);
694         memcpy(&buf[4], hostent->addr, hostent->len);
695
696         hostent_free(hostent);
697
698         sock_write(connection->server, buf, ret + 1);
699
700         /* come on.. what are the changes we won't get the packet in one read() ? :) */
701         sock_read(connection->server, buf, 8);
702
703         switch (buf[1]) {
704         case SOCKS_GRANTED:
705                 ret = TRUE;
706                 break;
707         case SOCKS_FAILED:
708                 ret = ERROR_CONNECT;
709                 break;
710         case SOCKS_BADIDENT:
711         case SOCKS_NOIDENT:
712                 ret = ERROR_AUTH;
713                 break;
714         default:
715                 ret = ERROR_UNKNOWN;
716         }
717
718         return ret;
719 }