be67f9a21079c49f832da69c1370d1e4af36302c
[sip-router] / tcp_read.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27 /*
28  * History:
29  * --------
30  * 2002-12-??  created by andrei.
31  * 2003-02-10  zero term before calling receive_msg & undo afterward (andrei)
32  * 2003-05-13  l: (short form of Content-Length) is now recognized (andrei)
33  * 2003-07-01  tcp_read & friends take no a single tcp_connection 
34  *              parameter & they set c->state to S_CONN_EOF on eof (andrei)
35  * 2003-07-04  fixed tcp EOF handling (possible infinite loop) (andrei)
36  * 2005-07-05  migrated to the new io_wait code (andrei)
37  * 2006-02-03  use tsend_stream instead of send_all (andrei)
38  * 2006-10-13  added STUN support - state machine for TCP (vlada)
39  * 2007-02-20  fixed timeout calc. bug (andrei)
40  * 2007-11-26  improved tcp timers: switched to local_timer (andrei)
41  * 2008-02-04  optimizations: handle POLLRDHUP (if supported), detect short
42  *              reads (sock. buffer empty) (andrei)
43  * 2009-02-26  direct blacklist support (andrei)
44  * 2009-04-09  tcp ev and tcp stats macros added (andrei)
45  * 2010-05-14  split tcp_read() into tcp_read() and tcp_read_data() (andrei)
46  * 2010-05-17  new RD_CONN_REPEAT_READ flag, used by the tls hooks (andrei)
47  */
48
49 /** tcp readers processes, tcp read and pre-parse msg. functions.
50  * @file tcp_read.c
51  * @ingroup core
52  * Module: @ref core
53  */
54
55 #ifdef USE_TCP
56
57 #include <stdio.h>
58 #include <errno.h>
59 #include <string.h>
60
61
62 #include <sys/time.h>
63 #include <sys/types.h>
64 #include <sys/select.h>
65 #include <sys/socket.h>
66
67 #include <unistd.h>
68 #include <stdlib.h> /* for abort() */
69
70
71 #include "dprint.h"
72 #include "tcp_conn.h"
73 #include "tcp_read.h"
74 #include "tcp_stats.h"
75 #include "tcp_ev.h"
76 #include "pass_fd.h"
77 #include "globals.h"
78 #include "receive.h"
79 #include "timer.h"
80 #include "local_timer.h"
81 #include "ut.h"
82 #include "pt.h"
83 #include "cfg/cfg_struct.h"
84 #ifdef CORE_TLS
85 #include "tls/tls_server.h"
86 #else
87 #include "tls_hooks.h"
88 #endif /* CORE_TLS */
89 #ifdef USE_DST_BLACKLIST
90 #include "dst_blacklist.h"
91 #endif /* USE_DST_BLACKLIST */
92
93 #define HANDLE_IO_INLINE
94 #include "io_wait.h"
95 #include <fcntl.h> /* must be included after io_wait.h if SIGIO_RT is used */
96 #include "tsend.h"
97 #include "forward.h"
98
99 #ifdef USE_STUN
100 #include "ser_stun.h"
101
102 int is_msg_complete(struct tcp_req* r);
103
104 #endif /* USE_STUN */
105
106 #ifdef READ_HTTP11
107 #define HTTP11CONTINUE  "HTTP/1.1 100 Continue\r\nContent-Lenght: 0\r\n\r\n"
108 #define HTTP11CONTINUE_LEN      (sizeof(HTTP11CONTINUE)-1)
109 #endif
110
111 #define TCPCONN_TIMEOUT_MIN_RUN  1 /* run the timers each new tick */
112
113 /* types used in io_wait* */
114 enum fd_types { F_NONE, F_TCPMAIN, F_TCPCONN };
115
116 /* list of tcp connections handled by this process */
117 static struct tcp_connection* tcp_conn_lst=0;
118 static io_wait_h io_w; /* io_wait handler*/
119 static int tcpmain_sock=-1;
120
121 static struct local_timer tcp_reader_ltimer;
122 static ticks_t tcp_reader_prev_ticks;
123
124 #ifdef READ_HTTP11
125 static inline char *strfindcasestrz(str *haystack, char *needlez)
126 {
127         int i,j;
128         str needle;
129
130         needle.s = needlez;
131         needle.len = strlen(needlez);
132         for(i=0;i<haystack->len-needle.len;i++) {
133                 for(j=0;j<needle.len;j++) {
134                         if ( !((haystack->s[i+j]==needle.s[j]) ||
135                                         ( isalpha((int)haystack->s[i+j])
136                                                 && ((haystack->s[i+j])^(needle.s[j]))==0x20 )) )
137                                 break;
138                 }
139                 if (j==needle.len)
140                         return haystack->s+i;
141         }
142         return 0;
143 }
144
145 int tcp_http11_continue(struct tcp_connection *c)
146 {
147         struct dest_info dst;
148         char *p;
149         struct msg_start fline;
150         int ret;
151         str msg;
152
153         ret = 0;
154
155         msg.s = c->req.start;
156         msg.len = c->req.pos - c->req.start;
157         p = parse_first_line(msg.s, msg.len, &fline);
158         if(p==NULL)
159                 return 0;
160
161         if(fline.type!=SIP_REQUEST)
162                 return 0;
163
164         /* check if http request */
165         if(fline.u.request.version.len < HTTP_VERSION_LEN
166                         || strncasecmp(fline.u.request.version.s,
167                                 HTTP_VERSION, HTTP_VERSION_LEN))
168                 return 0;
169
170         /* check for Expect header */
171         if(strfindcasestrz(&msg, "Expect: 100-continue")!=NULL)
172         {
173                 init_dst_from_rcv(&dst, &c->rcv);
174                 if (tcp_send(&dst, 0, HTTP11CONTINUE, HTTP11CONTINUE_LEN) < 0) {
175                         LOG(L_ERR, "HTTP/1.1 continue failed\n");
176                 }
177         }
178         /* check for Transfer-Encoding header */
179         if(strfindcasestrz(&msg, "Transfer-Encoding: chunked")!=NULL)
180         {
181                 c->req.flags |= F_TCP_REQ_BCHUNKED;
182                 ret = 1;
183         }
184         return ret;
185 }
186 #endif /* HTTP11 */
187
188
189 /** reads data from an existing tcp connection.
190  * Side-effects: blacklisting, sets connection state to S_CONN_OK, tcp stats.
191  * @param fd - connection file descriptor
192  * @param c - tcp connection structure. c->state might be changed and
193  *             receive info might be used for blacklisting.
194  * @param buf - buffer where the received data will be stored.
195  * @param b_size - buffer size.
196  * @param flags - value/result - used to signal a seen or "forced" EOF on the
197  *     connection (when it is known that no more data will come after the 
198  *     current socket buffer is emptied )=> return/signal EOF on the first
199  *     short read (=> don't use it on POLLPRI, as OOB data will cause short
200  *     reads even if there are still remaining bytes in the socket buffer)
201  *     input: RD_CONN_FORCE_EOF  - force EOF after the first successful read
202  *                                 (bytes_read >=0 )
203  *     output: RD_CONN_SHORT_READ - if the read exhausted all the bytes
204  *                                  in the socket read buffer.
205  *             RD_CONN_EOF - if EOF detected (0 bytes read) or forced via
206  *                           RD_CONN_FORCE_EOF.
207  *             RD_CONN_REPEAT_READ - the read should be repeated immediately
208  *                                   (used only by the tls code for now).
209  *     Note: RD_CONN_SHORT_READ & RD_CONN_EOF _are_ not cleared internally,
210  *           so one should clear them before calling this function.
211  * @return number of bytes read, 0 on EOF or -1 on error,
212  * on EOF it also sets c->state to S_CONN_EOF.
213  * (to distinguish from reads that would block which could return 0)
214  * RD_CONN_SHORT_READ is also set in *flags for short reads.
215  * EOF checking should be done by checking the RD_CONN_EOF flag.
216  */
217 int tcp_read_data(int fd, struct tcp_connection *c,
218                                         char* buf, int b_size, int* flags)
219 {
220         int bytes_read;
221         
222 again:
223         bytes_read=read(fd, buf, b_size);
224         
225         if (likely(bytes_read!=b_size)){
226                 if(unlikely(bytes_read==-1)){
227                         if (errno == EWOULDBLOCK || errno == EAGAIN){
228                                 bytes_read=0; /* nothing has been read */
229                         }else if (errno == EINTR) goto again;
230                         else{
231                                 if (unlikely(c->state==S_CONN_CONNECT)){
232                                         switch(errno){
233                                                 case ECONNRESET:
234 #ifdef USE_DST_BLACKLIST
235                                                         dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
236                                                                                                 &c->rcv.src_su,
237                                                                                                 &c->send_flags, 0);
238 #endif /* USE_DST_BLACKLIST */
239                                                         TCP_EV_CONNECT_RST(errno, TCP_LADDR(c),
240                                                                         TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
241                                                         break;
242                                                 case ETIMEDOUT:
243 #ifdef USE_DST_BLACKLIST
244                                                         dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
245                                                                                                 &c->rcv.src_su,
246                                                                                                 &c->send_flags, 0);
247 #endif /* USE_DST_BLACKLIST */
248                                                         TCP_EV_CONNECT_TIMEOUT(errno, TCP_LADDR(c),
249                                                                         TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
250                                                         break;
251                                                 default:
252                                                         TCP_EV_CONNECT_ERR(errno, TCP_LADDR(c),
253                                                                         TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
254                                         }
255                                         TCP_STATS_CONNECT_FAILED();
256                                 }else{
257                                                 switch(errno){
258                                                         case ECONNRESET:
259                                                                 TCP_STATS_CON_RESET();
260                                                         case ETIMEDOUT:
261 #ifdef USE_DST_BLACKLIST
262                                                                 dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto,
263                                                                                                         &c->rcv.src_su,
264                                                                                                         &c->send_flags, 0);
265 #endif /* USE_DST_BLACKLIST */
266                                                                 break;
267                                                 }
268                                 }
269                                 LOG(cfg_get(core, core_cfg, corelog),
270                                                 "error reading: %s (%d)\n", strerror(errno), errno);
271                                 return -1;
272                         }
273                 }else if (unlikely((bytes_read==0) || 
274                                         (*flags & RD_CONN_FORCE_EOF))){
275                         c->state=S_CONN_EOF;
276                         *flags|=RD_CONN_EOF;
277                         DBG("EOF on %p, FD %d\n", c, fd);
278                 }else{
279                         if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT)){
280                                 TCP_STATS_ESTABLISHED(c->state);
281                                 c->state=S_CONN_OK;
282                         }
283                 }
284                 /* short read */
285                 *flags|=RD_CONN_SHORT_READ;
286         }else{ /* else normal full read */
287                 if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT)){
288                         TCP_STATS_ESTABLISHED(c->state);
289                         c->state=S_CONN_OK;
290                 }
291         }
292         return bytes_read;
293 }
294
295
296
297 /* reads next available bytes
298  *   c- tcp connection used for reading, tcp_read changes also c->state on
299  *      EOF and c->req.error on read error
300  *   * flags - value/result - used to signal a seen or "forced" EOF on the 
301  *     connection (when it is known that no more data will come after the 
302  *     current socket buffer is emptied )=> return/signal EOF on the first 
303  *     short read (=> don't use it on POLLPRI, as OOB data will cause short
304  *      reads even if there are still remaining bytes in the socket buffer)
305  * return number of bytes read, 0 on EOF or -1 on error,
306  * on EOF it also sets c->state to S_CONN_EOF.
307  * (to distinguish from reads that would block which could return 0)
308  * RD_CONN_SHORT_READ is also set in *flags for short reads.
309  * sets also r->error */
310 int tcp_read(struct tcp_connection *c, int* flags)
311 {
312         int bytes_free, bytes_read;
313         struct tcp_req *r;
314         int fd;
315
316         r=&c->req;
317         fd=c->fd;
318         bytes_free=r->b_size- (int)(r->pos - r->buf);
319         
320         if (unlikely(bytes_free==0)){
321                 LOG(L_ERR, "ERROR: tcp_read: buffer overrun, dropping\n");
322                 r->error=TCP_REQ_OVERRUN;
323                 return -1;
324         }
325         bytes_read = tcp_read_data(fd, c, r->pos, bytes_free, flags);
326         if (unlikely(bytes_read < 0)){
327                 r->error=TCP_READ_ERROR;
328                 return -1;
329         }
330 #ifdef EXTRA_DEBUG
331         DBG("tcp_read: read %d bytes:\n%.*s\n", bytes_read, bytes_read, r->pos);
332 #endif
333         r->pos+=bytes_read;
334         return bytes_read;
335 }
336
337
338
339 /* reads all headers (until double crlf), & parses the content-length header
340  * (WARNING: inefficient, tries to reuse receive_msg but will go through
341  * the headers twice [once here looking for Content-Length and for the end
342  * of the headers and once in receive_msg]; a more speed efficient version will
343  * result in either major code duplication or major changes to the receive code)
344  * returns number of bytes read & sets r->state & r->body
345  * when either r->body!=0 or r->state==H_BODY =>
346  * all headers have been read. It should be called in a while loop.
347  * returns < 0 if error or 0 if EOF */
348 int tcp_read_headers(struct tcp_connection *c, int* read_flags)
349 {
350         int bytes, remaining;
351         char *p;
352         struct tcp_req* r;
353         
354 #ifdef USE_STUN
355         unsigned int mc;   /* magic cookie */
356         unsigned short body_len;
357 #endif
358         
359         #define crlf_default_skip_case \
360                                         case '\n': \
361                                                 r->state=H_LF; \
362                                                 break; \
363                                         default: \
364                                                 r->state=H_SKIP
365         
366         #define content_len_beg_case \
367                                         case ' ': \
368                                         case '\t': \
369                                                 if (!TCP_REQ_HAS_CLEN(r)) r->state=H_STARTWS; \
370                                                 else r->state=H_SKIP; \
371                                                         /* not interested if we already found one */ \
372                                                 break; \
373                                         case 'C': \
374                                         case 'c': \
375                                                 if(!TCP_REQ_HAS_CLEN(r)) r->state=H_CONT_LEN1; \
376                                                 else r->state=H_SKIP; \
377                                                 break; \
378                                         case 'l': \
379                                         case 'L': \
380                                                 /* short form for Content-Length */ \
381                                                 if (!TCP_REQ_HAS_CLEN(r)) r->state=H_L_COLON; \
382                                                 else r->state=H_SKIP; \
383                                                 break
384                                                 
385         #define change_state(upper, lower, newstate)\
386                                         switch(*p){ \
387                                                 case upper: \
388                                                 case lower: \
389                                                         r->state=(newstate); break; \
390                                                 crlf_default_skip_case; \
391                                         }
392         
393         #define change_state_case(state0, upper, lower, newstate)\
394                                         case state0: \
395                                                           change_state(upper, lower, newstate); \
396                                                           p++; \
397                                                           break
398
399
400         r=&c->req;
401         /* if we still have some unparsed part, parse it first, don't do the read*/
402         if (unlikely(r->parsed<r->pos)){
403                 bytes=0;
404         }else{
405 #ifdef USE_TLS
406                 if (unlikely(c->type==PROTO_TLS))
407                         bytes=tls_read(c, read_flags);
408                 else
409 #endif
410                         bytes=tcp_read(c, read_flags);
411                 if (bytes<=0) return bytes;
412         }
413         p=r->parsed;
414         
415         while(p<r->pos && r->error==TCP_REQ_OK){
416                 switch((unsigned char)r->state){
417                         case H_BODY: /* read the body*/
418                                 remaining=r->pos-p;
419                                 if (remaining>r->bytes_to_go) remaining=r->bytes_to_go;
420                                 r->bytes_to_go-=remaining;
421                                 p+=remaining;
422                                 if (r->bytes_to_go==0){
423                                         r->flags|=F_TCP_REQ_COMPLETE;
424                                         goto skip;
425                                 }
426                                 break;
427                                 
428                         case H_SKIP:
429                                 /* find lf, we are in this state if we are not interested
430                                  * in anything till end of line*/
431                                 p=q_memchr(p, '\n', r->pos-p);
432                                 if (p){
433                                         p++;
434                                         r->state=H_LF;
435                                 }else{
436                                         p=r->pos;
437                                 }
438                                 break;
439                                 
440                         case H_LF:
441                                 /* terminate on LF CR LF or LF LF */
442                                 switch (*p){
443                                         case '\r':
444                                                 r->state=H_LFCR;
445                                                 break;
446                                         case '\n':
447                                                 /* found LF LF */
448                                                 r->state=H_BODY;
449                                                 if (TCP_REQ_HAS_CLEN(r)){
450                                                         r->body=p+1;
451                                                         r->bytes_to_go=r->content_len;
452                                                         if (r->bytes_to_go==0){
453                                                                 r->flags|=F_TCP_REQ_COMPLETE;
454                                                                 p++;
455                                                                 goto skip;
456                                                         }
457                                                 }else{
458                                                         DBG("tcp_read_headers: ERROR: no clen, p=%X\n",
459                                                                         *p);
460                                                         r->error=TCP_REQ_BAD_LEN;
461                                                 }
462                                                 break;
463                                         content_len_beg_case;
464                                         default: 
465                                                 r->state=H_SKIP;
466                                 }
467                                 p++;
468                                 break;
469                         case H_LFCR:
470                                 if (*p=='\n'){
471                                         /* found LF CR LF */
472                                         r->state=H_BODY;
473 #ifdef READ_HTTP11
474                                         if (cfg_get(tcp, tcp_cfg, accept_no_cl)!=0)
475                                                 tcp_http11_continue(c);
476 #endif
477                                         if (TCP_REQ_HAS_CLEN(r)){
478                                                 r->body=p+1;
479                                                 r->bytes_to_go=r->content_len;
480                                                 if (r->bytes_to_go==0){
481                                                         r->flags|=F_TCP_REQ_COMPLETE;
482                                                         p++;
483                                                         goto skip;
484                                                 }
485                                         }else{
486                                                 if (cfg_get(tcp, tcp_cfg, accept_no_cl)!=0) {
487 #ifdef READ_HTTP11
488                                                         if(TCP_REQ_BCHUNKED(r)) {
489                                                                 r->body=p+1;
490                                                                 /* at least 3 bytes: 0\r\n */
491                                                                 r->bytes_to_go=3;
492                                                                 p++;
493                                                                 r->content_len = 0;
494                                                                 r->state=H_HTTP11_CHUNK_START;
495                                                                 break;
496                                                         }
497 #endif
498                                                         r->body=p+1;
499                                                         r->bytes_to_go=0;
500                                                         r->flags|=F_TCP_REQ_COMPLETE;
501                                                         p++;
502                                                         goto skip;
503                                                 } else {
504                                                         DBG("tcp_read_headers: ERROR: no clen, p=%X\n",
505                                                                         *p);
506                                                         r->error=TCP_REQ_BAD_LEN;
507                                                 }
508                                         }
509                                 }else r->state=H_SKIP;
510                                 p++;
511                                 break;
512                                 
513                         case H_STARTWS:
514                                 switch (*p){
515                                         content_len_beg_case;
516                                         crlf_default_skip_case;
517                                 }
518                                 p++;
519                                 break;
520                         case H_SKIP_EMPTY:
521                                 switch (*p){
522                                         case '\n':
523                                                 break;
524                                         case '\r':
525                                                 if (cfg_get(tcp, tcp_cfg, crlf_ping)) {
526                                                         r->state=H_SKIP_EMPTY_CR_FOUND;
527                                                         r->start=p;
528                                                 }
529                                                 break;
530                                         case ' ':
531                                         case '\t':
532                                                 /* skip empty lines */
533                                                 break;
534                                         case 'C': 
535                                         case 'c': 
536                                                 r->state=H_CONT_LEN1; 
537                                                 r->start=p;
538                                                 break;
539                                         case 'l':
540                                         case 'L':
541                                                 /* short form for Content-Length */
542                                                 r->state=H_L_COLON;
543                                                 r->start=p;
544                                                 break;
545                                         default:
546 #ifdef USE_STUN
547                                                 /* STUN support can be switched off even if it's compiled */
548                                                 /* stun test */                                         
549                                                 if (stun_allow_stun && (unsigned char)*p == 0x00) {
550                                                         r->state=H_STUN_MSG;
551                                                 /* body will used as pointer to the last used byte */
552                                                         r->body=p;
553                                                         r->content_len = 0;
554                                                         DBG("stun msg detected\n");
555                                                 }else
556 #endif
557                                                 r->state=H_SKIP;
558                                                 r->start=p;
559                                 };
560                                 p++;
561                                 break;
562
563                         case H_SKIP_EMPTY_CR_FOUND:
564                                 if (*p=='\n'){
565                                         r->state=H_SKIP_EMPTY_CRLF_FOUND;
566                                         p++;
567                                 }else{
568                                         r->state=H_SKIP_EMPTY;
569                                 }
570                                 break;
571
572                         case H_SKIP_EMPTY_CRLF_FOUND:
573                                 if (*p=='\r'){
574                                         r->state = H_SKIP_EMPTY_CRLFCR_FOUND;
575                                         p++;
576                                 }else{
577                                         r->state = H_SKIP_EMPTY;
578                                 }
579                                 break;
580
581                         case H_SKIP_EMPTY_CRLFCR_FOUND:
582                                 if (*p=='\n'){
583                                         r->state = H_PING_CRLF;
584                                         r->flags |= F_TCP_REQ_HAS_CLEN |
585                                                         F_TCP_REQ_COMPLETE; /* hack to avoid error check */
586                                         p++;
587                                         goto skip;
588                                 }else{
589                                         r->state = H_SKIP_EMPTY;
590                                 }
591                                 break;
592 #ifdef USE_STUN
593                         case H_STUN_MSG:
594                                 if ((r->pos - r->body) >= sizeof(struct stun_hdr)) {
595                                         /* copy second short from buffer where should be body 
596                                          * length 
597                                          */
598                                         memcpy(&body_len, &r->start[sizeof(unsigned short)], 
599                                                 sizeof(unsigned short));
600                                         
601                                         body_len = ntohs(body_len);
602                                         
603                                         /* check if there is valid magic cookie */
604                                         memcpy(&mc, &r->start[sizeof(unsigned int)], 
605                                                 sizeof(unsigned int));
606                                         mc = ntohl(mc);
607                                         /* using has_content_len as a flag if there should be
608                                          * fingerprint or no
609                                          */
610                                         r->flags |= (mc == MAGIC_COOKIE) ? F_TCP_REQ_HAS_CLEN : 0;
611                                         
612                                         r->body += sizeof(struct stun_hdr);
613                                         p = r->body; 
614                                         
615                                         if (body_len > 0) {
616                                                 r->state = H_STUN_READ_BODY;
617                                         }
618                                         else {
619                                                 if (is_msg_complete(r) != 0) {
620                                                         goto skip;
621                                                 }
622                                                 else {
623                                                         /* set content_len to length of fingerprint */
624                                                         body_len = sizeof(struct stun_attr) + 
625                                                                            SHA_DIGEST_LENGTH;
626                                                 }
627                                         }
628                                         r->content_len=body_len;
629                                 }
630                                 else {
631                                         p = r->pos; 
632                                 }
633                                 break;
634                                 
635                         case H_STUN_READ_BODY:
636                                 /* check if the whole body was read */
637                                 body_len=r->content_len;
638                                 if ((r->pos - r->body) >= body_len) {
639                                         r->body += body_len;
640                                         p = r->body;
641                                         if (is_msg_complete(r) != 0) {
642                                                 r->content_len=0;
643                                                 goto skip;
644                                         }
645                                         else {
646                                                 /* set content_len to length of fingerprint */
647                                                 body_len = sizeof(struct stun_attr)+SHA_DIGEST_LENGTH;
648                                                 r->content_len=body_len;
649                                         }
650                                 }
651                                 else {
652                                         p = r->pos;
653                                 }
654                                 break;
655                                 
656                         case H_STUN_FP:
657                                 /* content_len contains length of fingerprint in this place! */
658                                 body_len=r->content_len;
659                                 if ((r->pos - r->body) >= body_len) {
660                                         r->body += body_len;
661                                         p = r->body;
662                                         r->state = H_STUN_END;
663                                         r->flags |= F_TCP_REQ_COMPLETE |
664                                                 F_TCP_REQ_HAS_CLEN; /* hack to avoid error check */
665                                         r->content_len=0;
666                                         goto skip;
667                                 }
668                                 else {
669                                         p = r->pos;
670                                 }
671                                 break;
672 #endif /* USE_STUN */
673                         change_state_case(H_CONT_LEN1,  'O', 'o', H_CONT_LEN2);
674                         change_state_case(H_CONT_LEN2,  'N', 'n', H_CONT_LEN3);
675                         change_state_case(H_CONT_LEN3,  'T', 't', H_CONT_LEN4);
676                         change_state_case(H_CONT_LEN4,  'E', 'e', H_CONT_LEN5);
677                         change_state_case(H_CONT_LEN5,  'N', 'n', H_CONT_LEN6);
678                         change_state_case(H_CONT_LEN6,  'T', 't', H_CONT_LEN7);
679                         change_state_case(H_CONT_LEN7,  '-', '_', H_CONT_LEN8);
680                         change_state_case(H_CONT_LEN8,  'L', 'l', H_CONT_LEN9);
681                         change_state_case(H_CONT_LEN9,  'E', 'e', H_CONT_LEN10);
682                         change_state_case(H_CONT_LEN10, 'N', 'n', H_CONT_LEN11);
683                         change_state_case(H_CONT_LEN11, 'G', 'g', H_CONT_LEN12);
684                         change_state_case(H_CONT_LEN12, 'T', 't', H_CONT_LEN13);
685                         change_state_case(H_CONT_LEN13, 'H', 'h', H_L_COLON);
686
687                         case H_L_COLON:
688                                 switch(*p){
689                                         case ' ':
690                                         case '\t':
691                                                 break; /* skip space */
692                                         case ':':
693                                                 r->state=H_CONT_LEN_BODY;
694                                                 break;
695                                         crlf_default_skip_case;
696                                 };
697                                 p++;
698                                 break;
699
700                         case  H_CONT_LEN_BODY:
701                                 switch(*p){
702                                         case ' ':
703                                         case '\t':
704                                                 break; /* eat space */
705                                         case '0':
706                                         case '1':
707                                         case '2':
708                                         case '3':
709                                         case '4':
710                                         case '5':
711                                         case '6':
712                                         case '7':
713                                         case '8':
714                                         case '9':
715                                                 r->state=H_CONT_LEN_BODY_PARSE;
716                                                 r->content_len=(*p-'0');
717                                                 break;
718                                         /*FIXME: content length on different lines ! */
719                                         crlf_default_skip_case;
720                                 }
721                                 p++;
722                                 break;
723
724                         case H_CONT_LEN_BODY_PARSE:
725                                 switch(*p){
726                                         case '0':
727                                         case '1':
728                                         case '2':
729                                         case '3':
730                                         case '4':
731                                         case '5':
732                                         case '6':
733                                         case '7':
734                                         case '8':
735                                         case '9':
736                                                 r->content_len=r->content_len*10+(*p-'0');
737                                                 break;
738                                         case '\r':
739                                         case ' ':
740                                         case '\t': /* FIXME: check if line contains only WS */
741                                                 r->state=H_SKIP;
742                                                 r->flags|=F_TCP_REQ_HAS_CLEN;
743                                                 break;
744                                         case '\n':
745                                                 /* end of line, parse successful */
746                                                 r->state=H_LF;
747                                                 r->flags|=F_TCP_REQ_HAS_CLEN;
748                                                 break;
749                                         default:
750                                                 LOG(L_ERR, "ERROR: tcp_read_headers: bad "
751                                                                 "Content-Length header value, unexpected "
752                                                                 "char %c in state %d\n", *p, r->state);
753                                                 r->state=H_SKIP; /* try to find another?*/
754                                 }
755                                 p++;
756                                 break;
757                         
758 #ifdef READ_HTTP11
759                         case H_HTTP11_CHUNK_START: /* start a new body chunk: SIZE\r\nBODY\r\n */
760                                 r->chunk_size = 0;
761                                 r->state = H_HTTP11_CHUNK_SIZE;
762                                 break;
763                         case H_HTTP11_CHUNK_BODY: /* content of chunnk */
764                                 remaining=r->pos-p;
765                                 if (remaining>r->bytes_to_go) remaining=r->bytes_to_go;
766                                 r->bytes_to_go-=remaining;
767                                 p+=remaining;
768                                 if (r->bytes_to_go==0){
769                                         r->state = H_HTTP11_CHUNK_END;
770                                         /* shift back body content */
771                                         if(r->chunk_size>0 && p-r->chunk_size>r->body) {
772                                                 memmove(r->body + r->content_len, p - r->chunk_size,
773                                                                 r->chunk_size);
774                                                 r->content_len += r->chunk_size;
775                                         }
776                                         goto skip;
777                                 }
778                                 break;
779
780                         case H_HTTP11_CHUNK_END:
781                                 switch(*p){
782                                         case '\r':
783                                         case ' ':
784                                         case '\t': /* skip */
785                                                 break;
786                                         case '\n':
787                                                 r->state = H_HTTP11_CHUNK_START;
788                                                 break;
789                                         default:
790                                                 LM_ERR("bad chunk, unexpected "
791                                                                 "char %c in state %d\n", *p, r->state);
792                                                 r->state=H_SKIP; /* try to find another?*/
793                                 }
794                                 p++;
795                                 break;
796
797                         case H_HTTP11_CHUNK_SIZE:
798                                 switch(*p){
799                                         case '0': case '1': case '2': case '3':
800                                         case '4': case '5': case '6': case '7':
801                                         case '8': case '9':
802                                                 r->chunk_size <<= 4;
803                                                 r->chunk_size += *p - '0';
804                                                 break;
805                                         case 'a': case 'b': case 'c': case 'd':
806                                         case 'e': case 'f':
807                                                 r->chunk_size <<= 4;
808                                                 r->chunk_size += *p - 'a' + 10;
809                                                 break;
810                                         case 'A': case 'B': case 'C': case 'D':
811                                         case 'E': case 'F':
812                                                 r->chunk_size <<= 4;
813                                                 r->chunk_size += *p - 'A' + 10;
814                                                 break;
815                                         case '\r':
816                                         case ' ':
817                                         case '\t': /* skip */
818                                                 break;
819                                         case '\n':
820                                                 /* end of line, parse successful */
821                                                 r->state=H_HTTP11_CHUNK_BODY;
822                                                 r->bytes_to_go = r->chunk_size;
823                                                 if (r->bytes_to_go==0){
824                                                         r->state=H_HTTP11_CHUNK_FINISH;
825                                                         r->flags|=F_TCP_REQ_COMPLETE;
826                                                         p++;
827                                                         goto skip;
828                                                 }
829                                                 break;
830                                         default:
831                                                 LM_ERR("bad chunk size value, unexpected "
832                                                                 "char %c in state %d\n", *p, r->state);
833                                                 r->state=H_SKIP; /* try to find another?*/
834                                 }
835                                 p++;
836                                 break;
837 #endif
838
839                         default:
840                                 LOG(L_CRIT, "BUG: tcp_read_headers: unexpected state %d\n",
841                                                 r->state);
842                                 abort();
843                 }
844         }
845 skip:
846         r->parsed=p;
847         return bytes;
848 }
849
850
851
852 int tcp_read_req(struct tcp_connection* con, int* bytes_read, int* read_flags)
853 {
854         int bytes;
855         int total_bytes;
856         int resp;
857         long size;
858         struct tcp_req* req;
859         struct dest_info dst;
860         int s;
861         char c;
862         int ret;
863                 
864                 bytes=-1;
865                 total_bytes=0;
866                 resp=CONN_RELEASE;
867                 s=con->fd;
868                 req=&con->req;
869
870 again:
871                 if (likely(req->error==TCP_REQ_OK)){
872                         bytes=tcp_read_headers(con, read_flags);
873 #ifdef EXTRA_DEBUG
874                                                 /* if timeout state=0; goto end__req; */
875                         DBG("read= %d bytes, parsed=%d, state=%d, error=%d\n",
876                                         bytes, (int)(req->parsed-req->start), req->state,
877                                         req->error );
878                         DBG("tcp_read_req: last char=0x%02X, parsed msg=\n%.*s\n",
879                                         *(req->parsed-1), (int)(req->parsed-req->start),
880                                         req->start);
881 #endif
882                         if (unlikely(bytes==-1)){
883                                 LOG(cfg_get(core, core_cfg, corelog),
884                                                 "ERROR: tcp_read_req: error reading \n");
885                                 resp=CONN_ERROR;
886                                 goto end_req;
887                         }
888                         total_bytes+=bytes;
889                         /* eof check:
890                          * is EOF if eof on fd and req.  not complete yet,
891                          * if req. is complete we might have a second unparsed
892                          * request after it, so postpone release_with_eof
893                          */
894                         if (unlikely((con->state==S_CONN_EOF) && 
895                                                 (! TCP_REQ_COMPLETE(req)))) {
896                                 DBG( "tcp_read_req: EOF\n");
897                                 resp=CONN_EOF;
898                                 goto end_req;
899                         }
900                 
901                 }
902                 if (unlikely(req->error!=TCP_REQ_OK)){
903                         LOG(L_ERR,"ERROR: tcp_read_req: bad request, state=%d, error=%d "
904                                           "buf:\n%.*s\nparsed:\n%.*s\n", req->state, req->error,
905                                           (int)(req->pos-req->buf), req->buf,
906                                           (int)(req->parsed-req->start), req->start);
907                         DBG("- received from: port %d\n", con->rcv.src_port);
908                         print_ip("- received from: ip ",&con->rcv.src_ip, "\n");
909                         resp=CONN_ERROR;
910                         goto end_req;
911                 }
912                 if (likely(TCP_REQ_COMPLETE(req))){
913 #ifdef EXTRA_DEBUG
914                         DBG("tcp_read_req: end of header part\n");
915                         DBG("- received from: port %d\n", con->rcv.src_port);
916                         print_ip("- received from: ip ", &con->rcv.src_ip, "\n");
917                         DBG("tcp_read_req: headers:\n%.*s.\n",
918                                         (int)(req->body-req->start), req->start);
919 #endif
920                         if (likely(TCP_REQ_HAS_CLEN(req))){
921                                 DBG("tcp_read_req: content-length= %d\n", req->content_len);
922 #ifdef EXTRA_DEBUG
923                                 DBG("tcp_read_req: body:\n%.*s\n", req->content_len,req->body);
924 #endif
925                         }else{
926                                 if (cfg_get(tcp, tcp_cfg, accept_no_cl)==0) {
927                                         req->error=TCP_REQ_BAD_LEN;
928                                         LOG(L_ERR, "ERROR: tcp_read_req: content length not present or"
929                                                 " unparsable\n");
930                                         resp=CONN_ERROR;
931                                         goto end_req;
932                                 }
933                         }
934                         /* if we are here everything is nice and ok*/
935                         resp=CONN_RELEASE;
936 #ifdef EXTRA_DEBUG
937                         DBG("calling receive_msg(%p, %d, )\n",
938                                         req->start, (int)(req->parsed-req->start));
939 #endif
940                         /* rcv.bind_address should always be !=0 */
941                         bind_address=con->rcv.bind_address;
942                         /* just for debugging use sendipv4 as receiving socket  FIXME*/
943                         /*
944                         if (con->rcv.dst_ip.af==AF_INET6){
945                                 bind_address=sendipv6_tcp;
946                         }else{
947                                 bind_address=sendipv4_tcp;
948                         }
949                         */
950                         con->rcv.proto_reserved1=con->id; /* copy the id */
951                         c=*req->parsed; /* ugly hack: zero term the msg & save the
952                                                            previous char, req->parsed should be ok
953                                                            because we always alloc BUF_SIZE+1 */
954                         *req->parsed=0;
955
956                         if (req->state==H_PING_CRLF) {
957                                 init_dst_from_rcv(&dst, &con->rcv);
958
959                                 if (tcp_send(&dst, 0, CRLF, CRLF_LEN) < 0) {
960                                         LOG(L_ERR, "CRLF ping: tcp_send() failed\n");
961                                 }
962                                 ret = 0;
963                         }else
964 #ifdef USE_STUN
965                         if (unlikely(req->state==H_STUN_END)){
966                                 /* stun request */
967                                 ret = stun_process_msg(req->start, req->parsed-req->start,
968                                                                          &con->rcv);
969                         }else
970 #endif
971 #ifdef READ_HTTP11
972                         if (unlikely(req->state==H_HTTP11_CHUNK_FINISH)){
973                                 /* http chunked request */
974                                 req->body[req->content_len] = 0;
975                                 ret = receive_msg(req->start,
976                                                 req->body + req->content_len - req->start,
977                                                 &con->rcv);
978                         }else
979 #endif
980                                 ret = receive_msg(req->start, req->parsed-req->start,
981                                                                         &con->rcv);
982                                 
983                         if (unlikely(ret < 0)) {
984                                 *req->parsed=c;
985                                 resp=CONN_ERROR;
986                                 goto end_req;
987                         }
988                         *req->parsed=c;
989                         
990                         /* prepare for next request */
991                         size=req->pos-req->parsed;
992                         req->start=req->buf;
993                         req->body=0;
994                         req->error=TCP_REQ_OK;
995                         req->state=H_SKIP_EMPTY;
996                         req->flags=0;
997                         req->content_len=0;
998                         req->bytes_to_go=0;
999                         req->pos=req->buf+size;
1000                         
1001                         if (unlikely(size)){ 
1002                                 memmove(req->buf, req->parsed, size);
1003                                 req->parsed=req->buf; /* fix req->parsed after using it */
1004 #ifdef EXTRA_DEBUG
1005                                 DBG("tcp_read_req: preparing for new request, kept %ld"
1006                                                 " bytes\n", size);
1007 #endif
1008                                 /*if we still have some unparsed bytes, try to parse them too*/
1009                                 goto again;
1010                         } else if (unlikely(con->state==S_CONN_EOF)){
1011                                 DBG( "tcp_read_req: EOF after reading complete request\n");
1012                                 resp=CONN_EOF;
1013                         }
1014                         req->parsed=req->buf; /* fix req->parsed */
1015                 }
1016                 
1017                 
1018         end_req:
1019                 if (likely(bytes_read)) *bytes_read=total_bytes;
1020                 return resp;
1021 }
1022
1023
1024
1025 void release_tcpconn(struct tcp_connection* c, long state, int unix_sock)
1026 {
1027         long response[2];
1028         
1029                 DBG( "releasing con %p, state %ld, fd=%d, id=%d\n",
1030                                 c, state, c->fd, c->id);
1031                 DBG(" extra_data %p\n", c->extra_data);
1032                 /* release req & signal the parent */
1033                 c->reader_pid=0; /* reset it */
1034                 if (c->fd!=-1){
1035                         close(c->fd);
1036                         c->fd=-1;
1037                 }
1038                 /* errno==EINTR, EWOULDBLOCK a.s.o todo */
1039                 response[0]=(long)c;
1040                 response[1]=state;
1041                 
1042                 if (tsend_stream(unix_sock, (char*)response, sizeof(response), -1)<=0)
1043                         LOG(L_ERR, "ERROR: release_tcpconn: tsend_stream failed\n");
1044 }
1045
1046
1047
1048 static ticks_t tcpconn_read_timeout(ticks_t t, struct timer_ln* tl, void* data)
1049 {
1050         struct tcp_connection *c;
1051         
1052         c=(struct tcp_connection*)data; 
1053         /* or (struct tcp...*)(tl-offset(c->timer)) */
1054         
1055         if (likely(!(c->state<0) && TICKS_LT(t, c->timeout))){
1056                 /* timeout extended, exit */
1057                 return (ticks_t)(c->timeout - t);
1058         }
1059         /* if conn->state is ERROR or BAD => force timeout too */
1060         if (unlikely(io_watch_del(&io_w, c->fd, -1, IO_FD_CLOSING)<0)){
1061                 LOG(L_ERR, "ERROR: tcpconn_read_timeout: io_watch_del failed for %p"
1062                                         " id %d fd %d, state %d, flags %x, main fd %d\n",
1063                                         c, c->id, c->fd, c->state, c->flags, c->s);
1064         }
1065         tcpconn_listrm(tcp_conn_lst, c, c_next, c_prev);
1066         release_tcpconn(c, (c->state<0)?CONN_ERROR:CONN_RELEASE, tcpmain_sock);
1067         
1068         return 0;
1069 }
1070
1071
1072
1073 /* handle io routine, based on the fd_map type
1074  * (it will be called from io_wait_loop* )
1075  * params:  fm  - pointer to a fd hash entry
1076  *          idx - index in the fd_array (or -1 if not known)
1077  * return: -1 on error, or when we are not interested any more on reads
1078  *            from this fd (e.g.: we are closing it )
1079  *          0 on EAGAIN or when by some other way it is known that no more 
1080  *            io events are queued on the fd (the receive buffer is empty).
1081  *            Usefull to detect when there are no more io events queued for
1082  *            sigio_rt, epoll_et, kqueue.
1083  *         >0 on successfull read from the fd (when there might be more io
1084  *            queued -- the receive buffer might still be non-empty)
1085  */
1086 inline static int handle_io(struct fd_map* fm, short events, int idx)
1087 {       
1088         int ret;
1089         int n;
1090         int read_flags;
1091         struct tcp_connection* con;
1092         int s;
1093         long resp;
1094         ticks_t t;
1095         
1096         /* update the local config */
1097         cfg_update();
1098         
1099         switch(fm->type){
1100                 case F_TCPMAIN:
1101 again:
1102                         ret=n=receive_fd(fm->fd, &con, sizeof(con), &s, 0);
1103                         DBG("received n=%d con=%p, fd=%d\n", n, con, s);
1104                         if (unlikely(n<0)){
1105                                 if (errno == EWOULDBLOCK || errno == EAGAIN){
1106                                         ret=0;
1107                                         break;
1108                                 }else if (errno == EINTR) goto again;
1109                                 else{
1110                                         LOG(L_CRIT,"BUG: tcp_receive: handle_io: read_fd: %s \n",
1111                                                         strerror(errno));
1112                                                 abort(); /* big error*/
1113                                 }
1114                         }
1115                         if (unlikely(n==0)){
1116                                 LOG(L_ERR, "WARNING: tcp_receive: handle_io: 0 bytes read\n");
1117                                 goto error;
1118                         }
1119                         if (unlikely(con==0)){
1120                                         LOG(L_CRIT, "BUG: tcp_receive: handle_io null pointer\n");
1121                                         goto error;
1122                         }
1123                         con->fd=s;
1124                         if (unlikely(s==-1)) {
1125                                 LOG(L_ERR, "ERROR: tcp_receive: handle_io: read_fd:"
1126                                                                         "no fd read\n");
1127                                 goto con_error;
1128                         }
1129                         con->reader_pid=my_pid();
1130                         if (unlikely(con==tcp_conn_lst)){
1131                                 LOG(L_CRIT, "BUG: tcp_receive: handle_io: duplicate"
1132                                                         " connection received: %p, id %d, fd %d, refcnt %d"
1133                                                         " state %d (n=%d)\n", con, con->id, con->fd,
1134                                                         atomic_get(&con->refcnt), con->state, n);
1135                                 goto con_error;
1136                                 break; /* try to recover */
1137                         }
1138                         if (unlikely(con->state==S_CONN_BAD)){
1139                                 LOG(L_WARN, "WARNING: tcp_receive: handle_io: received an"
1140                                                         " already bad connection: %p id %d refcnt %d\n",
1141                                                         con, con->id, atomic_get(&con->refcnt));
1142                                 goto con_error;
1143                         }
1144                         /* if we received the fd there is most likely data waiting to
1145                          * be read => process it first to avoid extra sys calls */
1146                         read_flags=((con->flags & (F_CONN_EOF_SEEN|F_CONN_FORCE_EOF)) &&
1147                                                 !(con->flags & F_CONN_OOB_DATA))? RD_CONN_FORCE_EOF
1148                                                 :0;
1149 #ifdef USE_TLS
1150 repeat_1st_read:
1151 #endif /* USE_TLS */
1152                         resp=tcp_read_req(con, &n, &read_flags);
1153                         if (unlikely(resp<0)){
1154                                 /* some error occured, but on the new fd, not on the tcp
1155                                  * main fd, so keep the ret value */
1156                                 if (unlikely(resp!=CONN_EOF))
1157                                         con->state=S_CONN_BAD;
1158                                 release_tcpconn(con, resp, tcpmain_sock);
1159                                 break;
1160                         }
1161 #ifdef USE_TLS
1162                         /* repeat read if requested (for now only tls might do this) */
1163                         if (unlikely(read_flags & RD_CONN_REPEAT_READ))
1164                                 goto repeat_1st_read;
1165 #endif /* USE_TLS */
1166                         
1167                         /* must be before io_watch_add, io_watch_add might catch some
1168                          * already existing events => might call handle_io and
1169                          * handle_io might decide to del. the new connection =>
1170                          * must be in the list */
1171                         tcpconn_listadd(tcp_conn_lst, con, c_next, c_prev);
1172                         t=get_ticks_raw();
1173                         con->timeout=t+S_TO_TICKS(TCP_CHILD_TIMEOUT);
1174                         /* re-activate the timer */
1175                         con->timer.f=tcpconn_read_timeout;
1176                         local_timer_reinit(&con->timer);
1177                         local_timer_add(&tcp_reader_ltimer, &con->timer,
1178                                                                 S_TO_TICKS(TCP_CHILD_TIMEOUT), t);
1179                         if (unlikely(io_watch_add(&io_w, s, POLLIN, F_TCPCONN, con)<0)){
1180                                 LOG(L_CRIT, "ERROR: tcpconn_receive: handle_io: io_watch_add "
1181                                                         "failed for %p id %d fd %d, state %d, flags %x,"
1182                                                         " main fd %d, refcnt %d\n",
1183                                                         con, con->id, con->fd, con->state, con->flags,
1184                                                         con->s, atomic_get(&con->refcnt));
1185                                 tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
1186                                 local_timer_del(&tcp_reader_ltimer, &con->timer);
1187                                 goto con_error;
1188                         }
1189                         break;
1190                 case F_TCPCONN:
1191                         con=(struct tcp_connection*)fm->data;
1192                         if (unlikely(con->state==S_CONN_BAD)){
1193                                 resp=CONN_ERROR;
1194                                 if (!(con->send_flags.f & SND_F_CON_CLOSE))
1195                                         LOG(L_WARN, "WARNING: tcp_receive: handle_io: F_TCPCONN"
1196                                                         " connection marked as bad: %p id %d refcnt %d\n",
1197                                                         con, con->id, atomic_get(&con->refcnt));
1198                                 goto read_error;
1199                         }
1200                         read_flags=((
1201 #ifdef POLLRDHUP
1202                                                 (events & POLLRDHUP) |
1203 #endif /* POLLRDHUP */
1204                                                 (events & (POLLHUP|POLLERR)) |
1205                                                         (con->flags & (F_CONN_EOF_SEEN|F_CONN_FORCE_EOF)))
1206                                                 && !(events & POLLPRI))? RD_CONN_FORCE_EOF: 0;
1207 #ifdef USE_TLS
1208 repeat_read:
1209 #endif /* USE_TLS */
1210                         resp=tcp_read_req(con, &ret, &read_flags);
1211                         if (unlikely(resp<0)){
1212 read_error:
1213                                 ret=-1; /* some error occured */
1214                                 if (unlikely(io_watch_del(&io_w, con->fd, idx,
1215                                                                                         IO_FD_CLOSING) < 0)){
1216                                         LOG(L_CRIT, "ERROR: tcpconn_receive: handle_io: "
1217                                                         "io_watch_del failed for %p id %d fd %d,"
1218                                                         " state %d, flags %x, main fd %d, refcnt %d\n",
1219                                                         con, con->id, con->fd, con->state,
1220                                                         con->flags, con->s, atomic_get(&con->refcnt));
1221                                 }
1222                                 tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
1223                                 local_timer_del(&tcp_reader_ltimer, &con->timer);
1224                                 if (unlikely(resp!=CONN_EOF))
1225                                         con->state=S_CONN_BAD;
1226                                 release_tcpconn(con, resp, tcpmain_sock);
1227                         }else{
1228 #ifdef USE_TLS
1229                                 if (unlikely(read_flags & RD_CONN_REPEAT_READ))
1230                                                 goto repeat_read;
1231 #endif /* USE_TLS */
1232                                 /* update timeout */
1233                                 con->timeout=get_ticks_raw()+S_TO_TICKS(TCP_CHILD_TIMEOUT);
1234                                 /* ret= 0 (read the whole socket buffer) if short read & 
1235                                  *  !POLLPRI,  bytes read otherwise */
1236                                 ret&=(((read_flags & RD_CONN_SHORT_READ) &&
1237                                                 !(events & POLLPRI)) - 1);
1238                         }
1239                         break;
1240                 case F_NONE:
1241                         LOG(L_CRIT, "BUG: handle_io: empty fd map %p (%d): "
1242                                                 "{%d, %d, %p}\n", fm, (int)(fm-io_w.fd_hash),
1243                                                 fm->fd, fm->type, fm->data);
1244                         goto error;
1245                 default:
1246                         LOG(L_CRIT, "BUG: handle_io: uknown fd type %d\n", fm->type); 
1247                         goto error;
1248         }
1249         
1250         return ret;
1251 con_error:
1252         con->state=S_CONN_BAD;
1253         release_tcpconn(con, CONN_ERROR, tcpmain_sock);
1254         return ret;
1255 error:
1256         return -1;
1257 }
1258
1259
1260
1261 inline static void tcp_reader_timer_run()
1262 {
1263         ticks_t ticks;
1264         
1265         ticks=get_ticks_raw();
1266         if (unlikely((ticks-tcp_reader_prev_ticks)<TCPCONN_TIMEOUT_MIN_RUN))
1267                 return;
1268         tcp_reader_prev_ticks=ticks;
1269         local_timer_run(&tcp_reader_ltimer, ticks);
1270 }
1271
1272
1273
1274 void tcp_receive_loop(int unix_sock)
1275 {
1276         
1277         /* init */
1278         tcpmain_sock=unix_sock; /* init com. socket */
1279         if (init_io_wait(&io_w, get_max_open_fds(), tcp_poll_method)<0)
1280                 goto error;
1281         tcp_reader_prev_ticks=get_ticks_raw();
1282         if (init_local_timer(&tcp_reader_ltimer, get_ticks_raw())!=0)
1283                 goto error;
1284         /* add the unix socket */
1285         if (io_watch_add(&io_w, tcpmain_sock, POLLIN,  F_TCPMAIN, 0)<0){
1286                 LOG(L_CRIT, "ERROR: tcp_receive_loop: init: failed to add socket "
1287                                                         " to the fd list\n");
1288                 goto error;
1289         }
1290
1291         /* initialize the config framework */
1292         if (cfg_child_init()) goto error;
1293
1294         /* main loop */
1295         switch(io_w.poll_method){
1296                 case POLL_POLL:
1297                                 while(1){
1298                                         io_wait_loop_poll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1299                                         tcp_reader_timer_run();
1300                                 }
1301                                 break;
1302 #ifdef HAVE_SELECT
1303                 case POLL_SELECT:
1304                         while(1){
1305                                 io_wait_loop_select(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1306                                 tcp_reader_timer_run();
1307                         }
1308                         break;
1309 #endif
1310 #ifdef HAVE_SIGIO_RT
1311                 case POLL_SIGIO_RT:
1312                         while(1){
1313                                 io_wait_loop_sigio_rt(&io_w, TCP_CHILD_SELECT_TIMEOUT);
1314                                 tcp_reader_timer_run();
1315                         }
1316                         break;
1317 #endif
1318 #ifdef HAVE_EPOLL
1319                 case POLL_EPOLL_LT:
1320                         while(1){
1321                                 io_wait_loop_epoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1322                                 tcp_reader_timer_run();
1323                         }
1324                         break;
1325                 case POLL_EPOLL_ET:
1326                         while(1){
1327                                 io_wait_loop_epoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 1);
1328                                 tcp_reader_timer_run();
1329                         }
1330                         break;
1331 #endif
1332 #ifdef HAVE_KQUEUE
1333                 case POLL_KQUEUE:
1334                         while(1){
1335                                 io_wait_loop_kqueue(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1336                                 tcp_reader_timer_run();
1337                         }
1338                         break;
1339 #endif
1340 #ifdef HAVE_DEVPOLL
1341                 case POLL_DEVPOLL:
1342                         while(1){
1343                                 io_wait_loop_devpoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1344                                 tcp_reader_timer_run();
1345                         }
1346                         break;
1347 #endif
1348                 default:
1349                         LOG(L_CRIT, "BUG: tcp_receive_loop: no support for poll method "
1350                                         " %s (%d)\n", 
1351                                         poll_method_name(io_w.poll_method), io_w.poll_method);
1352                         goto error;
1353         }
1354 error:
1355         destroy_io_wait(&io_w);
1356         LOG(L_CRIT, "ERROR: tcp_receive_loop: exiting...");
1357         exit(-1);
1358 }
1359
1360
1361
1362 #ifdef USE_STUN
1363 int is_msg_complete(struct tcp_req* r)
1364 {
1365         if (TCP_REQ_HAS_CLEN(r)) {
1366                 r->state = H_STUN_FP;
1367                 return 0;
1368         }
1369         else {
1370                 /* STUN message is complete */
1371                 r->state = H_STUN_END;
1372                 r->flags |= F_TCP_REQ_COMPLETE |
1373                                         F_TCP_REQ_HAS_CLEN; /* hack to avoid error check */
1374                 return 1;
1375         }
1376 }
1377 #endif
1378
1379 #endif /* USE_TCP */