core: fix warnings/eliminate unused variables
[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         char c;
861         int ret;
862                 
863                 bytes=-1;
864                 total_bytes=0;
865                 resp=CONN_RELEASE;
866                 req=&con->req;
867
868 again:
869                 if (likely(req->error==TCP_REQ_OK)){
870                         bytes=tcp_read_headers(con, read_flags);
871 #ifdef EXTRA_DEBUG
872                                                 /* if timeout state=0; goto end__req; */
873                         DBG("read= %d bytes, parsed=%d, state=%d, error=%d\n",
874                                         bytes, (int)(req->parsed-req->start), req->state,
875                                         req->error );
876                         DBG("tcp_read_req: last char=0x%02X, parsed msg=\n%.*s\n",
877                                         *(req->parsed-1), (int)(req->parsed-req->start),
878                                         req->start);
879 #endif
880                         if (unlikely(bytes==-1)){
881                                 LOG(cfg_get(core, core_cfg, corelog),
882                                                 "ERROR: tcp_read_req: error reading \n");
883                                 resp=CONN_ERROR;
884                                 goto end_req;
885                         }
886                         total_bytes+=bytes;
887                         /* eof check:
888                          * is EOF if eof on fd and req.  not complete yet,
889                          * if req. is complete we might have a second unparsed
890                          * request after it, so postpone release_with_eof
891                          */
892                         if (unlikely((con->state==S_CONN_EOF) && 
893                                                 (! TCP_REQ_COMPLETE(req)))) {
894                                 DBG( "tcp_read_req: EOF\n");
895                                 resp=CONN_EOF;
896                                 goto end_req;
897                         }
898                 
899                 }
900                 if (unlikely(req->error!=TCP_REQ_OK)){
901                         LOG(L_ERR,"ERROR: tcp_read_req: bad request, state=%d, error=%d "
902                                           "buf:\n%.*s\nparsed:\n%.*s\n", req->state, req->error,
903                                           (int)(req->pos-req->buf), req->buf,
904                                           (int)(req->parsed-req->start), req->start);
905                         DBG("- received from: port %d\n", con->rcv.src_port);
906                         print_ip("- received from: ip ",&con->rcv.src_ip, "\n");
907                         resp=CONN_ERROR;
908                         goto end_req;
909                 }
910                 if (likely(TCP_REQ_COMPLETE(req))){
911 #ifdef EXTRA_DEBUG
912                         DBG("tcp_read_req: end of header part\n");
913                         DBG("- received from: port %d\n", con->rcv.src_port);
914                         print_ip("- received from: ip ", &con->rcv.src_ip, "\n");
915                         DBG("tcp_read_req: headers:\n%.*s.\n",
916                                         (int)(req->body-req->start), req->start);
917 #endif
918                         if (likely(TCP_REQ_HAS_CLEN(req))){
919                                 DBG("tcp_read_req: content-length= %d\n", req->content_len);
920 #ifdef EXTRA_DEBUG
921                                 DBG("tcp_read_req: body:\n%.*s\n", req->content_len,req->body);
922 #endif
923                         }else{
924                                 if (cfg_get(tcp, tcp_cfg, accept_no_cl)==0) {
925                                         req->error=TCP_REQ_BAD_LEN;
926                                         LOG(L_ERR, "ERROR: tcp_read_req: content length not present or"
927                                                 " unparsable\n");
928                                         resp=CONN_ERROR;
929                                         goto end_req;
930                                 }
931                         }
932                         /* if we are here everything is nice and ok*/
933                         resp=CONN_RELEASE;
934 #ifdef EXTRA_DEBUG
935                         DBG("calling receive_msg(%p, %d, )\n",
936                                         req->start, (int)(req->parsed-req->start));
937 #endif
938                         /* rcv.bind_address should always be !=0 */
939                         bind_address=con->rcv.bind_address;
940                         /* just for debugging use sendipv4 as receiving socket  FIXME*/
941                         /*
942                         if (con->rcv.dst_ip.af==AF_INET6){
943                                 bind_address=sendipv6_tcp;
944                         }else{
945                                 bind_address=sendipv4_tcp;
946                         }
947                         */
948                         con->rcv.proto_reserved1=con->id; /* copy the id */
949                         c=*req->parsed; /* ugly hack: zero term the msg & save the
950                                                            previous char, req->parsed should be ok
951                                                            because we always alloc BUF_SIZE+1 */
952                         *req->parsed=0;
953
954                         if (req->state==H_PING_CRLF) {
955                                 init_dst_from_rcv(&dst, &con->rcv);
956
957                                 if (tcp_send(&dst, 0, CRLF, CRLF_LEN) < 0) {
958                                         LOG(L_ERR, "CRLF ping: tcp_send() failed\n");
959                                 }
960                                 ret = 0;
961                         }else
962 #ifdef USE_STUN
963                         if (unlikely(req->state==H_STUN_END)){
964                                 /* stun request */
965                                 ret = stun_process_msg(req->start, req->parsed-req->start,
966                                                                          &con->rcv);
967                         }else
968 #endif
969 #ifdef READ_HTTP11
970                         if (unlikely(req->state==H_HTTP11_CHUNK_FINISH)){
971                                 /* http chunked request */
972                                 req->body[req->content_len] = 0;
973                                 ret = receive_msg(req->start,
974                                                 req->body + req->content_len - req->start,
975                                                 &con->rcv);
976                         }else
977 #endif
978                                 ret = receive_msg(req->start, req->parsed-req->start,
979                                                                         &con->rcv);
980                                 
981                         if (unlikely(ret < 0)) {
982                                 *req->parsed=c;
983                                 resp=CONN_ERROR;
984                                 goto end_req;
985                         }
986                         *req->parsed=c;
987                         
988                         /* prepare for next request */
989                         size=req->pos-req->parsed;
990                         req->start=req->buf;
991                         req->body=0;
992                         req->error=TCP_REQ_OK;
993                         req->state=H_SKIP_EMPTY;
994                         req->flags=0;
995                         req->content_len=0;
996                         req->bytes_to_go=0;
997                         req->pos=req->buf+size;
998                         
999                         if (unlikely(size)){ 
1000                                 memmove(req->buf, req->parsed, size);
1001                                 req->parsed=req->buf; /* fix req->parsed after using it */
1002 #ifdef EXTRA_DEBUG
1003                                 DBG("tcp_read_req: preparing for new request, kept %ld"
1004                                                 " bytes\n", size);
1005 #endif
1006                                 /*if we still have some unparsed bytes, try to parse them too*/
1007                                 goto again;
1008                         } else if (unlikely(con->state==S_CONN_EOF)){
1009                                 DBG( "tcp_read_req: EOF after reading complete request\n");
1010                                 resp=CONN_EOF;
1011                         }
1012                         req->parsed=req->buf; /* fix req->parsed */
1013                 }
1014                 
1015                 
1016         end_req:
1017                 if (likely(bytes_read)) *bytes_read=total_bytes;
1018                 return resp;
1019 }
1020
1021
1022
1023 void release_tcpconn(struct tcp_connection* c, long state, int unix_sock)
1024 {
1025         long response[2];
1026         
1027                 DBG( "releasing con %p, state %ld, fd=%d, id=%d\n",
1028                                 c, state, c->fd, c->id);
1029                 DBG(" extra_data %p\n", c->extra_data);
1030                 /* release req & signal the parent */
1031                 c->reader_pid=0; /* reset it */
1032                 if (c->fd!=-1){
1033                         close(c->fd);
1034                         c->fd=-1;
1035                 }
1036                 /* errno==EINTR, EWOULDBLOCK a.s.o todo */
1037                 response[0]=(long)c;
1038                 response[1]=state;
1039                 
1040                 if (tsend_stream(unix_sock, (char*)response, sizeof(response), -1)<=0)
1041                         LOG(L_ERR, "ERROR: release_tcpconn: tsend_stream failed\n");
1042 }
1043
1044
1045
1046 static ticks_t tcpconn_read_timeout(ticks_t t, struct timer_ln* tl, void* data)
1047 {
1048         struct tcp_connection *c;
1049         
1050         c=(struct tcp_connection*)data; 
1051         /* or (struct tcp...*)(tl-offset(c->timer)) */
1052         
1053         if (likely(!(c->state<0) && TICKS_LT(t, c->timeout))){
1054                 /* timeout extended, exit */
1055                 return (ticks_t)(c->timeout - t);
1056         }
1057         /* if conn->state is ERROR or BAD => force timeout too */
1058         if (unlikely(io_watch_del(&io_w, c->fd, -1, IO_FD_CLOSING)<0)){
1059                 LOG(L_ERR, "ERROR: tcpconn_read_timeout: io_watch_del failed for %p"
1060                                         " id %d fd %d, state %d, flags %x, main fd %d\n",
1061                                         c, c->id, c->fd, c->state, c->flags, c->s);
1062         }
1063         tcpconn_listrm(tcp_conn_lst, c, c_next, c_prev);
1064         release_tcpconn(c, (c->state<0)?CONN_ERROR:CONN_RELEASE, tcpmain_sock);
1065         
1066         return 0;
1067 }
1068
1069
1070
1071 /* handle io routine, based on the fd_map type
1072  * (it will be called from io_wait_loop* )
1073  * params:  fm  - pointer to a fd hash entry
1074  *          idx - index in the fd_array (or -1 if not known)
1075  * return: -1 on error, or when we are not interested any more on reads
1076  *            from this fd (e.g.: we are closing it )
1077  *          0 on EAGAIN or when by some other way it is known that no more 
1078  *            io events are queued on the fd (the receive buffer is empty).
1079  *            Usefull to detect when there are no more io events queued for
1080  *            sigio_rt, epoll_et, kqueue.
1081  *         >0 on successfull read from the fd (when there might be more io
1082  *            queued -- the receive buffer might still be non-empty)
1083  */
1084 inline static int handle_io(struct fd_map* fm, short events, int idx)
1085 {       
1086         int ret;
1087         int n;
1088         int read_flags;
1089         struct tcp_connection* con;
1090         int s;
1091         long resp;
1092         ticks_t t;
1093         
1094         /* update the local config */
1095         cfg_update();
1096         
1097         switch(fm->type){
1098                 case F_TCPMAIN:
1099 again:
1100                         ret=n=receive_fd(fm->fd, &con, sizeof(con), &s, 0);
1101                         DBG("received n=%d con=%p, fd=%d\n", n, con, s);
1102                         if (unlikely(n<0)){
1103                                 if (errno == EWOULDBLOCK || errno == EAGAIN){
1104                                         ret=0;
1105                                         break;
1106                                 }else if (errno == EINTR) goto again;
1107                                 else{
1108                                         LOG(L_CRIT,"BUG: tcp_receive: handle_io: read_fd: %s \n",
1109                                                         strerror(errno));
1110                                                 abort(); /* big error*/
1111                                 }
1112                         }
1113                         if (unlikely(n==0)){
1114                                 LOG(L_ERR, "WARNING: tcp_receive: handle_io: 0 bytes read\n");
1115                                 goto error;
1116                         }
1117                         if (unlikely(con==0)){
1118                                         LOG(L_CRIT, "BUG: tcp_receive: handle_io null pointer\n");
1119                                         goto error;
1120                         }
1121                         con->fd=s;
1122                         if (unlikely(s==-1)) {
1123                                 LOG(L_ERR, "ERROR: tcp_receive: handle_io: read_fd:"
1124                                                                         "no fd read\n");
1125                                 goto con_error;
1126                         }
1127                         con->reader_pid=my_pid();
1128                         if (unlikely(con==tcp_conn_lst)){
1129                                 LOG(L_CRIT, "BUG: tcp_receive: handle_io: duplicate"
1130                                                         " connection received: %p, id %d, fd %d, refcnt %d"
1131                                                         " state %d (n=%d)\n", con, con->id, con->fd,
1132                                                         atomic_get(&con->refcnt), con->state, n);
1133                                 goto con_error;
1134                                 break; /* try to recover */
1135                         }
1136                         if (unlikely(con->state==S_CONN_BAD)){
1137                                 LOG(L_WARN, "WARNING: tcp_receive: handle_io: received an"
1138                                                         " already bad connection: %p id %d refcnt %d\n",
1139                                                         con, con->id, atomic_get(&con->refcnt));
1140                                 goto con_error;
1141                         }
1142                         /* if we received the fd there is most likely data waiting to
1143                          * be read => process it first to avoid extra sys calls */
1144                         read_flags=((con->flags & (F_CONN_EOF_SEEN|F_CONN_FORCE_EOF)) &&
1145                                                 !(con->flags & F_CONN_OOB_DATA))? RD_CONN_FORCE_EOF
1146                                                 :0;
1147 #ifdef USE_TLS
1148 repeat_1st_read:
1149 #endif /* USE_TLS */
1150                         resp=tcp_read_req(con, &n, &read_flags);
1151                         if (unlikely(resp<0)){
1152                                 /* some error occured, but on the new fd, not on the tcp
1153                                  * main fd, so keep the ret value */
1154                                 if (unlikely(resp!=CONN_EOF))
1155                                         con->state=S_CONN_BAD;
1156                                 release_tcpconn(con, resp, tcpmain_sock);
1157                                 break;
1158                         }
1159 #ifdef USE_TLS
1160                         /* repeat read if requested (for now only tls might do this) */
1161                         if (unlikely(read_flags & RD_CONN_REPEAT_READ))
1162                                 goto repeat_1st_read;
1163 #endif /* USE_TLS */
1164                         
1165                         /* must be before io_watch_add, io_watch_add might catch some
1166                          * already existing events => might call handle_io and
1167                          * handle_io might decide to del. the new connection =>
1168                          * must be in the list */
1169                         tcpconn_listadd(tcp_conn_lst, con, c_next, c_prev);
1170                         t=get_ticks_raw();
1171                         con->timeout=t+S_TO_TICKS(TCP_CHILD_TIMEOUT);
1172                         /* re-activate the timer */
1173                         con->timer.f=tcpconn_read_timeout;
1174                         local_timer_reinit(&con->timer);
1175                         local_timer_add(&tcp_reader_ltimer, &con->timer,
1176                                                                 S_TO_TICKS(TCP_CHILD_TIMEOUT), t);
1177                         if (unlikely(io_watch_add(&io_w, s, POLLIN, F_TCPCONN, con)<0)){
1178                                 LOG(L_CRIT, "ERROR: tcpconn_receive: handle_io: io_watch_add "
1179                                                         "failed for %p id %d fd %d, state %d, flags %x,"
1180                                                         " main fd %d, refcnt %d\n",
1181                                                         con, con->id, con->fd, con->state, con->flags,
1182                                                         con->s, atomic_get(&con->refcnt));
1183                                 tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
1184                                 local_timer_del(&tcp_reader_ltimer, &con->timer);
1185                                 goto con_error;
1186                         }
1187                         break;
1188                 case F_TCPCONN:
1189                         con=(struct tcp_connection*)fm->data;
1190                         if (unlikely(con->state==S_CONN_BAD)){
1191                                 resp=CONN_ERROR;
1192                                 if (!(con->send_flags.f & SND_F_CON_CLOSE))
1193                                         LOG(L_WARN, "WARNING: tcp_receive: handle_io: F_TCPCONN"
1194                                                         " connection marked as bad: %p id %d refcnt %d\n",
1195                                                         con, con->id, atomic_get(&con->refcnt));
1196                                 goto read_error;
1197                         }
1198                         read_flags=((
1199 #ifdef POLLRDHUP
1200                                                 (events & POLLRDHUP) |
1201 #endif /* POLLRDHUP */
1202                                                 (events & (POLLHUP|POLLERR)) |
1203                                                         (con->flags & (F_CONN_EOF_SEEN|F_CONN_FORCE_EOF)))
1204                                                 && !(events & POLLPRI))? RD_CONN_FORCE_EOF: 0;
1205 #ifdef USE_TLS
1206 repeat_read:
1207 #endif /* USE_TLS */
1208                         resp=tcp_read_req(con, &ret, &read_flags);
1209                         if (unlikely(resp<0)){
1210 read_error:
1211                                 ret=-1; /* some error occured */
1212                                 if (unlikely(io_watch_del(&io_w, con->fd, idx,
1213                                                                                         IO_FD_CLOSING) < 0)){
1214                                         LOG(L_CRIT, "ERROR: tcpconn_receive: handle_io: "
1215                                                         "io_watch_del failed for %p id %d fd %d,"
1216                                                         " state %d, flags %x, main fd %d, refcnt %d\n",
1217                                                         con, con->id, con->fd, con->state,
1218                                                         con->flags, con->s, atomic_get(&con->refcnt));
1219                                 }
1220                                 tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
1221                                 local_timer_del(&tcp_reader_ltimer, &con->timer);
1222                                 if (unlikely(resp!=CONN_EOF))
1223                                         con->state=S_CONN_BAD;
1224                                 release_tcpconn(con, resp, tcpmain_sock);
1225                         }else{
1226 #ifdef USE_TLS
1227                                 if (unlikely(read_flags & RD_CONN_REPEAT_READ))
1228                                                 goto repeat_read;
1229 #endif /* USE_TLS */
1230                                 /* update timeout */
1231                                 con->timeout=get_ticks_raw()+S_TO_TICKS(TCP_CHILD_TIMEOUT);
1232                                 /* ret= 0 (read the whole socket buffer) if short read & 
1233                                  *  !POLLPRI,  bytes read otherwise */
1234                                 ret&=(((read_flags & RD_CONN_SHORT_READ) &&
1235                                                 !(events & POLLPRI)) - 1);
1236                         }
1237                         break;
1238                 case F_NONE:
1239                         LOG(L_CRIT, "BUG: handle_io: empty fd map %p (%d): "
1240                                                 "{%d, %d, %p}\n", fm, (int)(fm-io_w.fd_hash),
1241                                                 fm->fd, fm->type, fm->data);
1242                         goto error;
1243                 default:
1244                         LOG(L_CRIT, "BUG: handle_io: uknown fd type %d\n", fm->type); 
1245                         goto error;
1246         }
1247         
1248         return ret;
1249 con_error:
1250         con->state=S_CONN_BAD;
1251         release_tcpconn(con, CONN_ERROR, tcpmain_sock);
1252         return ret;
1253 error:
1254         return -1;
1255 }
1256
1257
1258
1259 inline static void tcp_reader_timer_run()
1260 {
1261         ticks_t ticks;
1262         
1263         ticks=get_ticks_raw();
1264         if (unlikely((ticks-tcp_reader_prev_ticks)<TCPCONN_TIMEOUT_MIN_RUN))
1265                 return;
1266         tcp_reader_prev_ticks=ticks;
1267         local_timer_run(&tcp_reader_ltimer, ticks);
1268 }
1269
1270
1271
1272 void tcp_receive_loop(int unix_sock)
1273 {
1274         
1275         /* init */
1276         tcpmain_sock=unix_sock; /* init com. socket */
1277         if (init_io_wait(&io_w, get_max_open_fds(), tcp_poll_method)<0)
1278                 goto error;
1279         tcp_reader_prev_ticks=get_ticks_raw();
1280         if (init_local_timer(&tcp_reader_ltimer, get_ticks_raw())!=0)
1281                 goto error;
1282         /* add the unix socket */
1283         if (io_watch_add(&io_w, tcpmain_sock, POLLIN,  F_TCPMAIN, 0)<0){
1284                 LOG(L_CRIT, "ERROR: tcp_receive_loop: init: failed to add socket "
1285                                                         " to the fd list\n");
1286                 goto error;
1287         }
1288
1289         /* initialize the config framework */
1290         if (cfg_child_init()) goto error;
1291
1292         /* main loop */
1293         switch(io_w.poll_method){
1294                 case POLL_POLL:
1295                                 while(1){
1296                                         io_wait_loop_poll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1297                                         tcp_reader_timer_run();
1298                                 }
1299                                 break;
1300 #ifdef HAVE_SELECT
1301                 case POLL_SELECT:
1302                         while(1){
1303                                 io_wait_loop_select(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1304                                 tcp_reader_timer_run();
1305                         }
1306                         break;
1307 #endif
1308 #ifdef HAVE_SIGIO_RT
1309                 case POLL_SIGIO_RT:
1310                         while(1){
1311                                 io_wait_loop_sigio_rt(&io_w, TCP_CHILD_SELECT_TIMEOUT);
1312                                 tcp_reader_timer_run();
1313                         }
1314                         break;
1315 #endif
1316 #ifdef HAVE_EPOLL
1317                 case POLL_EPOLL_LT:
1318                         while(1){
1319                                 io_wait_loop_epoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1320                                 tcp_reader_timer_run();
1321                         }
1322                         break;
1323                 case POLL_EPOLL_ET:
1324                         while(1){
1325                                 io_wait_loop_epoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 1);
1326                                 tcp_reader_timer_run();
1327                         }
1328                         break;
1329 #endif
1330 #ifdef HAVE_KQUEUE
1331                 case POLL_KQUEUE:
1332                         while(1){
1333                                 io_wait_loop_kqueue(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1334                                 tcp_reader_timer_run();
1335                         }
1336                         break;
1337 #endif
1338 #ifdef HAVE_DEVPOLL
1339                 case POLL_DEVPOLL:
1340                         while(1){
1341                                 io_wait_loop_devpoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1342                                 tcp_reader_timer_run();
1343                         }
1344                         break;
1345 #endif
1346                 default:
1347                         LOG(L_CRIT, "BUG: tcp_receive_loop: no support for poll method "
1348                                         " %s (%d)\n", 
1349                                         poll_method_name(io_w.poll_method), io_w.poll_method);
1350                         goto error;
1351         }
1352 error:
1353         destroy_io_wait(&io_w);
1354         LOG(L_CRIT, "ERROR: tcp_receive_loop: exiting...");
1355         exit(-1);
1356 }
1357
1358
1359
1360 #ifdef USE_STUN
1361 int is_msg_complete(struct tcp_req* r)
1362 {
1363         if (TCP_REQ_HAS_CLEN(r)) {
1364                 r->state = H_STUN_FP;
1365                 return 0;
1366         }
1367         else {
1368                 /* STUN message is complete */
1369                 r->state = H_STUN_END;
1370                 r->flags |= F_TCP_REQ_COMPLETE |
1371                                         F_TCP_REQ_HAS_CLEN; /* hack to avoid error check */
1372                 return 1;
1373         }
1374 }
1375 #endif
1376
1377 #endif /* USE_TCP */