Modifying the return value of cfg_set* functions, in order to make
[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  */
42
43 #ifdef USE_TCP
44
45 #include <stdio.h>
46 #include <errno.h>
47 #include <string.h>
48
49
50 #include <sys/time.h>
51 #include <sys/types.h>
52 #include <sys/select.h>
53 #include <sys/socket.h>
54
55 #include <unistd.h>
56 #include <stdlib.h> /* for abort() */
57
58
59 #include "dprint.h"
60 #include "tcp_conn.h"
61 #include "pass_fd.h"
62 #include "globals.h"
63 #include "receive.h"
64 #include "timer.h"
65 #include "local_timer.h"
66 #include "ut.h"
67 #include "pt.h"
68 #include "cfg/cfg_struct.h"
69 #ifdef CORE_TLS
70 #include "tls/tls_server.h"
71 #else
72 #include "tls_hooks.h"
73 #endif
74
75 #define HANDLE_IO_INLINE
76 #include "io_wait.h"
77 #include <fcntl.h> /* must be included after io_wait.h if SIGIO_RT is used */
78 #include "tsend.h"
79
80 #ifdef USE_STUN
81 #include "ser_stun.h"
82
83 int is_msg_complete(struct tcp_req* r);
84
85 #endif /* USE_STUN */
86
87 #define TCPCONN_TIMEOUT_MIN_RUN  1 /* run the timers each new tick */
88
89 /* types used in io_wait* */
90 enum fd_types { F_NONE, F_TCPMAIN, F_TCPCONN };
91
92 /* list of tcp connections handled by this process */
93 static struct tcp_connection* tcp_conn_lst=0;
94 static io_wait_h io_w; /* io_wait handler*/
95 static int tcpmain_sock=-1;
96
97 static struct local_timer tcp_reader_ltimer;
98
99
100 /* reads next available bytes
101  * return number of bytes read, 0 on EOF or -1 on error,
102  * on EOF it also sets c->state to S_CONN_EOF
103  * (to distinguish from reads that would block which could return 0)
104  * sets also r->error */
105 int tcp_read(struct tcp_connection *c)
106 {
107         int bytes_free, bytes_read;
108         struct tcp_req *r;
109         int fd;
110
111         r=&c->req;
112         fd=c->fd;
113         bytes_free=TCP_BUF_SIZE- (int)(r->pos - r->buf);
114         
115         if (bytes_free==0){
116                 LOG(L_ERR, "ERROR: tcp_read: buffer overrun, dropping\n");
117                 r->error=TCP_REQ_OVERRUN;
118                 return -1;
119         }
120 again:
121         bytes_read=read(fd, r->pos, bytes_free);
122
123         if(bytes_read==-1){
124                 if (errno == EWOULDBLOCK || errno == EAGAIN){
125                         return 0; /* nothing has been read */
126                 }else if (errno == EINTR) goto again;
127                 else{
128                         LOG(L_ERR, "ERROR: tcp_read: error reading: %s\n",strerror(errno));
129                         r->error=TCP_READ_ERROR;
130                         return -1;
131                 }
132         }else if (bytes_read==0){
133                 c->state=S_CONN_EOF;
134                 DBG("tcp_read: EOF on %p, FD %d\n", c, fd);
135         }
136 #ifdef EXTRA_DEBUG
137         DBG("tcp_read: read %d bytes:\n%.*s\n", bytes_read, bytes_read, r->pos);
138 #endif
139         r->pos+=bytes_read;
140         return bytes_read;
141 }
142
143
144
145 /* reads all headers (until double crlf), & parses the content-length header
146  * (WARNING: inefficient, tries to reuse receive_msg but will go through
147  * the headers twice [once here looking for Content-Length and for the end
148  * of the headers and once in receive_msg]; a more speed efficient version will
149  * result in either major code duplication or major changes to the receive code)
150  * returns number of bytes read & sets r->state & r->body
151  * when either r->body!=0 or r->state==H_BODY =>
152  * all headers have been read. It should be called in a while loop.
153  * returns < 0 if error or 0 if EOF */
154 int tcp_read_headers(struct tcp_connection *c)
155 {
156         int bytes, remaining;
157         char *p;
158         struct tcp_req* r;
159         
160 #ifdef USE_STUN
161         unsigned int mc;   /* magic cookie */
162         unsigned short body_len;
163 #endif
164         
165         #define crlf_default_skip_case \
166                                         case '\n': \
167                                                 r->state=H_LF; \
168                                                 break; \
169                                         default: \
170                                                 r->state=H_SKIP
171         
172         #define content_len_beg_case \
173                                         case ' ': \
174                                         case '\t': \
175                                                 if (!r->has_content_len) r->state=H_STARTWS; \
176                                                 else r->state=H_SKIP; \
177                                                         /* not interested if we already found one */ \
178                                                 break; \
179                                         case 'C': \
180                                         case 'c': \
181                                                 if(!r->has_content_len) r->state=H_CONT_LEN1; \
182                                                 else r->state=H_SKIP; \
183                                                 break; \
184                                         case 'l': \
185                                         case 'L': \
186                                                 /* short form for Content-Length */ \
187                                                 if (!r->has_content_len) r->state=H_L_COLON; \
188                                                 else r->state=H_SKIP; \
189                                                 break
190                                                 
191         #define change_state(upper, lower, newstate)\
192                                         switch(*p){ \
193                                                 case upper: \
194                                                 case lower: \
195                                                         r->state=(newstate); break; \
196                                                 crlf_default_skip_case; \
197                                         }
198         
199         #define change_state_case(state0, upper, lower, newstate)\
200                                         case state0: \
201                                                           change_state(upper, lower, newstate); \
202                                                           p++; \
203                                                           break
204
205
206         r=&c->req;
207         /* if we still have some unparsed part, parse it first, don't do the read*/
208         if (r->parsed<r->pos){
209                 bytes=0;
210         }else{
211 #ifdef USE_TLS
212                 if (c->type==PROTO_TLS)
213                         bytes=tls_read(c);
214                 else
215 #endif
216                         bytes=tcp_read(c);
217                 if (bytes<=0) return bytes;
218         }
219         p=r->parsed;
220         
221         while(p<r->pos && r->error==TCP_REQ_OK){
222                 switch((unsigned char)r->state){
223                         case H_BODY: /* read the body*/
224                                 remaining=r->pos-p;
225                                 if (remaining>r->bytes_to_go) remaining=r->bytes_to_go;
226                                 r->bytes_to_go-=remaining;
227                                 p+=remaining;
228                                 if (r->bytes_to_go==0){
229                                         r->complete=1;
230                                         goto skip;
231                                 }
232                                 break;
233                                 
234                         case H_SKIP:
235                                 /* find lf, we are in this state if we are not interested
236                                  * in anything till end of line*/
237                                 p=q_memchr(p, '\n', r->pos-p);
238                                 if (p){
239                                         p++;
240                                         r->state=H_LF;
241                                 }else{
242                                         p=r->pos;
243                                 }
244                                 break;
245                                 
246                         case H_LF:
247                                 /* terminate on LF CR LF or LF LF */
248                                 switch (*p){
249                                         case '\r':
250                                                 r->state=H_LFCR;
251                                                 break;
252                                         case '\n':
253                                                 /* found LF LF */
254                                                 r->state=H_BODY;
255                                                 if (r->has_content_len){
256                                                         r->body=p+1;
257                                                         r->bytes_to_go=r->content_len;
258                                                         if (r->bytes_to_go==0){
259                                                                 r->complete=1;
260                                                                 p++;
261                                                                 goto skip;
262                                                         }
263                                                 }else{
264                                                         DBG("tcp_read_headers: ERROR: no clen, p=%X\n",
265                                                                         *p);
266                                                         r->error=TCP_REQ_BAD_LEN;
267                                                 }
268                                                 break;
269                                         content_len_beg_case;
270                                         default: 
271                                                 r->state=H_SKIP;
272                                 }
273                                 p++;
274                                 break;
275                         case H_LFCR:
276                                 if (*p=='\n'){
277                                         /* found LF CR LF */
278                                         r->state=H_BODY;
279                                         if (r->has_content_len){
280                                                 r->body=p+1;
281                                                 r->bytes_to_go=r->content_len;
282                                                 if (r->bytes_to_go==0){
283                                                         r->complete=1;
284                                                         p++;
285                                                         goto skip;
286                                                 }
287                                         }else{
288                                                 DBG("tcp_read_headers: ERROR: no clen, p=%X\n",
289                                                                         *p);
290                                                 r->error=TCP_REQ_BAD_LEN;
291                                         }
292                                 }else r->state=H_SKIP;
293                                 p++;
294                                 break;
295                                 
296                         case H_STARTWS:
297                                 switch (*p){
298                                         content_len_beg_case;
299                                         crlf_default_skip_case;
300                                 }
301                                 p++;
302                                 break;
303                         case H_SKIP_EMPTY:
304                                 switch (*p){
305                                         case '\n':
306                                         case '\r':
307                                         case ' ':
308                                         case '\t':
309                                                 /* skip empty lines */
310                                                 break;
311                                         case 'C': 
312                                         case 'c': 
313                                                 r->state=H_CONT_LEN1; 
314                                                 r->start=p;
315                                                 break;
316                                         case 'l':
317                                         case 'L':
318                                                 /* short form for Content-Length */
319                                                 r->state=H_L_COLON;
320                                                 r->start=p;
321                                                 break;
322                                         default:
323 #ifdef USE_STUN
324                                                 /* STUN support can be switched off even if it's compiled */
325                                                 /* stun test */                                         
326                                                 if (stun_allow_stun && (unsigned char)*p == 0x00) {
327                                                         r->state=H_STUN_MSG;
328                                                 /* body will used as pointer to the last used byte */
329                                                         r->body=p;
330                                                         body_len = 0;
331                                                         DBG("stun msg detected\n");
332                                                 }else
333 #endif
334                                                 r->state=H_SKIP;
335                                                 r->start=p;
336                                 };
337                                 p++;
338                                 break;
339 #ifdef USE_STUN
340                         case H_STUN_MSG:
341                                 if ((r->pos - r->body) >= sizeof(struct stun_hdr)) {
342                                         r->content_len = 0;
343                                         /* copy second short from buffer where should be body 
344                                          * length 
345                                          */
346                                         memcpy(&body_len, &r->start[sizeof(unsigned short)], 
347                                                 sizeof(unsigned short));
348                                         
349                                         body_len = ntohs(r->content_len);
350                                         
351                                         /* check if there is valid magic cookie */
352                                         memcpy(&mc, &r->start[sizeof(unsigned int)], 
353                                                 sizeof(unsigned int));
354                                         mc = ntohl(mc);
355                                         /* using has_content_len as a flag if there should be
356                                          * fingerprint or no
357                                          */
358                                         r->has_content_len = (mc == MAGIC_COOKIE) ? 1 : 0;
359                                         
360                                         r->body += sizeof(struct stun_hdr);
361                                         p = r->body; 
362                                         
363                                         if (body_len > 0) {
364                                                 r->state = H_STUN_READ_BODY;
365                                         }
366                                         else {
367                                                 if (is_msg_complete(r) != 0) {
368                                                         goto skip;
369                                                 }
370                                                 else {
371                                                         /* set content_len to length of fingerprint */
372                                                         body_len = sizeof(struct stun_attr) + 
373                                                                            SHA_DIGEST_LENGTH;
374                                                 }
375                                         }
376                                 }
377                                 else {
378                                         p = r->pos; 
379                                 }
380                                 break;
381                                 
382                         case H_STUN_READ_BODY:
383                                 /* check if the whole body was read */
384                                 if ((r->pos - r->body) >= body_len) {
385                                         r->body += body_len;
386                                         p = r->body;
387                                         if (is_msg_complete(r) != 0) {
388                                                 goto skip;
389                                         }
390                                         else {
391                                                 /* set content_len to length of fingerprint */
392                                                 body_len = sizeof(struct stun_attr)+SHA_DIGEST_LENGTH;
393                                         }
394                                 }
395                                 else {
396                                         p = r->pos;
397                                 }
398                                 break;
399                                 
400                         case H_STUN_FP:
401                                 /* content_len contains length of fingerprint in this place! */
402                                 if ((r->pos - r->body) >= body_len) {
403                                         r->body += body_len;
404                                         p = r->body;
405                                         r->state = H_STUN_END;
406                                         r->complete = 1;
407                                         r->has_content_len = 1; /* hack to avoid error check */
408                                         goto skip;
409                                 }
410                                 else {
411                                         p = r->pos;
412                                 }
413                                 break;
414 #endif /* USE_STUN */
415                         change_state_case(H_CONT_LEN1,  'O', 'o', H_CONT_LEN2);
416                         change_state_case(H_CONT_LEN2,  'N', 'n', H_CONT_LEN3);
417                         change_state_case(H_CONT_LEN3,  'T', 't', H_CONT_LEN4);
418                         change_state_case(H_CONT_LEN4,  'E', 'e', H_CONT_LEN5);
419                         change_state_case(H_CONT_LEN5,  'N', 'n', H_CONT_LEN6);
420                         change_state_case(H_CONT_LEN6,  'T', 't', H_CONT_LEN7);
421                         change_state_case(H_CONT_LEN7,  '-', '_', H_CONT_LEN8);
422                         change_state_case(H_CONT_LEN8,  'L', 'l', H_CONT_LEN9);
423                         change_state_case(H_CONT_LEN9,  'E', 'e', H_CONT_LEN10);
424                         change_state_case(H_CONT_LEN10, 'N', 'n', H_CONT_LEN11);
425                         change_state_case(H_CONT_LEN11, 'G', 'g', H_CONT_LEN12);
426                         change_state_case(H_CONT_LEN12, 'T', 't', H_CONT_LEN13);
427                         change_state_case(H_CONT_LEN13, 'H', 'h', H_L_COLON);
428                         
429                         case H_L_COLON:
430                                 switch(*p){
431                                         case ' ':
432                                         case '\t':
433                                                 break; /* skip space */
434                                         case ':':
435                                                 r->state=H_CONT_LEN_BODY;
436                                                 break;
437                                         crlf_default_skip_case;
438                                 };
439                                 p++;
440                                 break;
441                         
442                         case  H_CONT_LEN_BODY:
443                                 switch(*p){
444                                         case ' ':
445                                         case '\t':
446                                                 break; /* eat space */
447                                         case '0':
448                                         case '1':
449                                         case '2':
450                                         case '3':
451                                         case '4':
452                                         case '5':
453                                         case '6':
454                                         case '7':
455                                         case '8':
456                                         case '9':
457                                                 r->state=H_CONT_LEN_BODY_PARSE;
458                                                 r->content_len=(*p-'0');
459                                                 break;
460                                         /*FIXME: content length on different lines ! */
461                                         crlf_default_skip_case;
462                                 }
463                                 p++;
464                                 break;
465                                 
466                         case H_CONT_LEN_BODY_PARSE:
467                                 switch(*p){
468                                         case '0':
469                                         case '1':
470                                         case '2':
471                                         case '3':
472                                         case '4':
473                                         case '5':
474                                         case '6':
475                                         case '7':
476                                         case '8':
477                                         case '9':
478                                                 r->content_len=r->content_len*10+(*p-'0');
479                                                 break;
480                                         case '\r':
481                                         case ' ':
482                                         case '\t': /* FIXME: check if line contains only WS */
483                                                 r->state=H_SKIP;
484                                                 r->has_content_len=1;
485                                                 break;
486                                         case '\n':
487                                                 /* end of line, parse successful */
488                                                 r->state=H_LF;
489                                                 r->has_content_len=1;
490                                                 break;
491                                         default:
492                                                 LOG(L_ERR, "ERROR: tcp_read_headers: bad "
493                                                                 "Content-Length header value, unexpected "
494                                                                 "char %c in state %d\n", *p, r->state);
495                                                 r->state=H_SKIP; /* try to find another?*/
496                                 }
497                                 p++;
498                                 break;
499                         
500                         default:
501                                 LOG(L_CRIT, "BUG: tcp_read_headers: unexpected state %d\n",
502                                                 r->state);
503                                 abort();
504                 }
505         }
506 skip:
507         r->parsed=p;
508         return bytes;
509 }
510
511
512
513 int tcp_read_req(struct tcp_connection* con, int* bytes_read)
514 {
515         int bytes;
516         int total_bytes;
517         int resp;
518         long size;
519         struct tcp_req* req;
520         int s;
521         char c;
522         int ret;
523                 
524                 bytes=-1;
525                 total_bytes=0;
526                 resp=CONN_RELEASE;
527                 s=con->fd;
528                 req=&con->req;
529 #ifdef USE_TLS
530                 if (con->type==PROTO_TLS){
531                         if (tls_fix_read_conn(con)!=0){
532                                 resp=CONN_ERROR;
533                                 goto end_req;
534                         }
535                         if(con->state!=S_CONN_OK) goto end_req; /* not enough data */
536                 }
537 #endif
538
539 again:
540                 if(req->error==TCP_REQ_OK){
541                         bytes=tcp_read_headers(con);
542 #ifdef EXTRA_DEBUG
543                                                 /* if timeout state=0; goto end__req; */
544                         DBG("read= %d bytes, parsed=%d, state=%d, error=%d\n",
545                                         bytes, (int)(req->parsed-req->start), req->state,
546                                         req->error );
547                         DBG("tcp_read_req: last char=0x%02X, parsed msg=\n%.*s\n",
548                                         *(req->parsed-1), (int)(req->parsed-req->start),
549                                         req->start);
550 #endif
551                         if (bytes==-1){
552                                 LOG(L_ERR, "ERROR: tcp_read_req: error reading \n");
553                                 resp=CONN_ERROR;
554                                 goto end_req;
555                         }
556                         total_bytes+=bytes;
557                         /* eof check:
558                          * is EOF if eof on fd and req.  not complete yet,
559                          * if req. is complete we might have a second unparsed
560                          * request after it, so postpone release_with_eof
561                          */
562                         if ((con->state==S_CONN_EOF) && (req->complete==0)) {
563                                 DBG( "tcp_read_req: EOF\n");
564                                 resp=CONN_EOF;
565                                 goto end_req;
566                         }
567                 
568                 }
569                 if (req->error!=TCP_REQ_OK){
570                         LOG(L_ERR,"ERROR: tcp_read_req: bad request, state=%d, error=%d "
571                                           "buf:\n%.*s\nparsed:\n%.*s\n", req->state, req->error,
572                                           (int)(req->pos-req->buf), req->buf,
573                                           (int)(req->parsed-req->start), req->start);
574                         DBG("- received from: port %d\n", con->rcv.src_port);
575                         print_ip("- received from: ip ",&con->rcv.src_ip, "\n");
576                         resp=CONN_ERROR;
577                         goto end_req;
578                 }
579                 if (req->complete){
580 #ifdef EXTRA_DEBUG
581                         DBG("tcp_read_req: end of header part\n");
582                         DBG("- received from: port %d\n", con->rcv.src_port);
583                         print_ip("- received from: ip ", &con->rcv.src_ip, "\n");
584                         DBG("tcp_read_req: headers:\n%.*s.\n",
585                                         (int)(req->body-req->start), req->start);
586 #endif
587                         if (req->has_content_len){
588                                 DBG("tcp_read_req: content-length= %d\n", req->content_len);
589 #ifdef EXTRA_DEBUG
590                                 DBG("tcp_read_req: body:\n%.*s\n", req->content_len,req->body);
591 #endif
592                         }else{
593                                 req->error=TCP_REQ_BAD_LEN;
594                                 LOG(L_ERR, "ERROR: tcp_read_req: content length not present or"
595                                                 " unparsable\n");
596                                 resp=CONN_ERROR;
597                                 goto end_req;
598                         }
599                         /* if we are here everything is nice and ok*/
600                         resp=CONN_RELEASE;
601 #ifdef EXTRA_DEBUG
602                         DBG("calling receive_msg(%p, %d, )\n",
603                                         req->start, (int)(req->parsed-req->start));
604 #endif
605                         /* rcv.bind_address should always be !=0 */
606                         bind_address=con->rcv.bind_address;
607                         /* just for debugging use sendipv4 as receiving socket  FIXME*/
608                         /*
609                         if (con->rcv.dst_ip.af==AF_INET6){
610                                 bind_address=sendipv6_tcp;
611                         }else{
612                                 bind_address=sendipv4_tcp;
613                         }
614                         */
615                         con->rcv.proto_reserved1=con->id; /* copy the id */
616                         c=*req->parsed; /* ugly hack: zero term the msg & save the
617                                                            previous char, req->parsed should be ok
618                                                            because we always alloc BUF_SIZE+1 */
619                         *req->parsed=0;
620 #ifdef USE_STUN
621                         if (req->state==H_STUN_END){
622                                 /* stun request */
623                                 ret = stun_process_msg(req->start, req->parsed-req->start,
624                                                                          &con->rcv);
625                         }else
626 #endif
627                                 ret = receive_msg(req->start, req->parsed-req->start, &con->rcv);
628                                 
629                         if (ret < 0) {
630                                 *req->parsed=c;
631                                 resp=CONN_ERROR;
632                                 goto end_req;
633                         }
634                         *req->parsed=c;
635                         
636                         /* prepare for next request */
637                         size=req->pos-req->parsed;
638                         if (size) memmove(req->buf, req->parsed, size);
639 #ifdef EXTRA_DEBUG
640                         DBG("tcp_read_req: preparing for new request, kept %ld bytes\n",
641                                         size);
642 #endif
643                         req->pos=req->buf+size;
644                         req->parsed=req->buf;
645                         req->start=req->buf;
646                         req->body=0;
647                         req->error=TCP_REQ_OK;
648                         req->state=H_SKIP_EMPTY;
649                         req->complete=req->content_len=req->has_content_len=0;
650                         req->bytes_to_go=0;
651                         /* if we still have some unparsed bytes, try to  parse them too*/
652                         if (size) goto again;
653                         else if (con->state==S_CONN_EOF){
654                                 DBG( "tcp_read_req: EOF after reading complete request\n");
655                                 resp=CONN_EOF;
656                         }
657                         
658                 }
659                 
660                 
661         end_req:
662                 if (bytes_read) *bytes_read=total_bytes;
663                 return resp;
664 }
665
666
667
668 void release_tcpconn(struct tcp_connection* c, long state, int unix_sock)
669 {
670         long response[2];
671         
672                 DBG( "releasing con %p, state %ld, fd=%d, id=%d\n",
673                                 c, state, c->fd, c->id);
674                 DBG(" extra_data %p\n", c->extra_data);
675                 /* release req & signal the parent */
676                 c->reader_pid=0; /* reset it */
677                 if (c->fd!=-1) close(c->fd);
678                 /* errno==EINTR, EWOULDBLOCK a.s.o todo */
679                 response[0]=(long)c;
680                 response[1]=state;
681                 
682                 if (tsend_stream(unix_sock, (char*)response, sizeof(response), -1)<=0)
683                         LOG(L_ERR, "ERROR: release_tcpconn: tsend_stream failed\n");
684 }
685
686
687
688 static ticks_t tcpconn_read_timeout(ticks_t t, struct timer_ln* tl, void* data)
689 {
690         struct tcp_connection *c;
691         
692         c=(struct tcp_connection*)data; 
693         /* or (struct tcp...*)(tl-offset(c->timer)) */
694         
695         if (likely(!(c->state<0) && TICKS_LT(t, c->timeout))){
696                 /* timeout extended, exit */
697                 return (ticks_t)(c->timeout - t);
698         }
699         /* if conn->state is ERROR or BAD => force timeout too */
700         io_watch_del(&io_w, c->fd, -1, IO_FD_CLOSING);
701         tcpconn_listrm(tcp_conn_lst, c, c_next, c_prev);
702         release_tcpconn(c, (c->state<0)?CONN_ERROR:CONN_RELEASE, tcpmain_sock);
703         
704         return 0;
705 }
706
707
708
709 /* handle io routine, based on the fd_map type
710  * (it will be called from io_wait_loop* )
711  * params:  fm  - pointer to a fd hash entry
712  *          idx - index in the fd_array (or -1 if not known)
713  * return: -1 on error, or when we are not interested any more on reads
714  *            from this fd (e.g.: we are closing it )
715  *          0 on EAGAIN or when by some other way it is known that no more 
716  *            io events are queued on the fd (the receive buffer is empty).
717  *            Usefull to detect when there are no more io events queued for
718  *            sigio_rt, epoll_et, kqueue.
719  *         >0 on successfull read from the fd (when there might be more io
720  *            queued -- the receive buffer might still be non-empty)
721  */
722 inline static int handle_io(struct fd_map* fm, short events, int idx)
723 {       
724         int ret;
725         int n;
726         struct tcp_connection* con;
727         int s;
728         long resp;
729         ticks_t t;
730         
731         /* update the local config */
732         cfg_update();
733         
734         switch(fm->type){
735                 case F_TCPMAIN:
736 again:
737                         ret=n=receive_fd(fm->fd, &con, sizeof(con), &s, 0);
738                         DBG("received n=%d con=%p, fd=%d\n", n, con, s);
739                         if (unlikely(n<0)){
740                                 if (errno == EWOULDBLOCK || errno == EAGAIN){
741                                         ret=0;
742                                         break;
743                                 }else if (errno == EINTR) goto again;
744                                 else{
745                                         LOG(L_CRIT,"BUG: tcp_receive: handle_io: read_fd: %s \n",
746                                                         strerror(errno));
747                                                 abort(); /* big error*/
748                                 }
749                         }
750                         if (unlikely(n==0)){
751                                 LOG(L_ERR, "WARNING: tcp_receive: handle_io: 0 bytes read\n");
752                                 goto error;
753                         }
754                         if (unlikely(con==0)){
755                                         LOG(L_CRIT, "BUG: tcp_receive: handle_io null pointer\n");
756                                         goto error;
757                         }
758                         con->fd=s;
759                         if (unlikely(s==-1)) {
760                                 LOG(L_ERR, "ERROR: tcp_receive: handle_io: read_fd:"
761                                                                         "no fd read\n");
762                                 goto con_error;
763                         }
764                         con->reader_pid=my_pid();
765                         if (unlikely(con==tcp_conn_lst)){
766                                 LOG(L_CRIT, "BUG: tcp_receive: handle_io: duplicate"
767                                                         " connection received: %p, id %d, fd %d, refcnt %d"
768                                                         " state %d (n=%d)\n", con, con->id, con->fd,
769                                                         atomic_get(&con->refcnt), con->state, n);
770                                 release_tcpconn(con, CONN_ERROR, tcpmain_sock);
771                                 break; /* try to recover */
772                         }
773                         /* must be before io_watch_add, io_watch_add might catch some
774                          * already existing events => might call handle_io and
775                          * handle_io might decide to del. the new connection =>
776                          * must be in the list */
777                         tcpconn_listadd(tcp_conn_lst, con, c_next, c_prev);
778                         t=get_ticks_raw();
779                         con->timeout=t+S_TO_TICKS(TCP_CHILD_TIMEOUT);
780                         /* re-activate the timer */
781                         con->timer.f=tcpconn_read_timeout;
782                         timer_reinit(&con->timer);
783                         local_timer_add(&tcp_reader_ltimer, &con->timer,
784                                                                 S_TO_TICKS(TCP_CHILD_TIMEOUT), t);
785                         if (unlikely(io_watch_add(&io_w, s, POLLIN, F_TCPCONN, con))<0){
786                                 LOG(L_CRIT, "ERROR: tcp_receive: handle_io: failed to add"
787                                                 " new socket to the fd list\n");
788                                 tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
789                                 local_timer_del(&tcp_reader_ltimer, &con->timer);
790                                 goto con_error;
791                         }
792                         break;
793                 case F_TCPCONN:
794                         con=(struct tcp_connection*)fm->data;
795                         resp=tcp_read_req(con, &ret);
796                         if (unlikely(resp<0)){
797                                 ret=-1; /* some error occured */
798                                 io_watch_del(&io_w, con->fd, idx, IO_FD_CLOSING);
799                                 tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
800                                 local_timer_del(&tcp_reader_ltimer, &con->timer);
801                                 con->state=S_CONN_BAD;
802                                 release_tcpconn(con, resp, tcpmain_sock);
803                         }else{
804                                 /* update timeout */
805                                 con->timeout=get_ticks_raw()+S_TO_TICKS(TCP_CHILD_TIMEOUT);
806                         }
807                         break;
808                 case F_NONE:
809                         LOG(L_CRIT, "BUG: handle_io: empty fd map %p (%d): "
810                                                 "{%d, %d, %p}\n", fm, (int)(fm-io_w.fd_hash),
811                                                 fm->fd, fm->type, fm->data);
812                         goto error;
813                 default:
814                         LOG(L_CRIT, "BUG: handle_io: uknown fd type %d\n", fm->type); 
815                         goto error;
816         }
817         
818         return ret;
819 con_error:
820         con->state=S_CONN_BAD;
821         release_tcpconn(con, CONN_ERROR, fm->fd);
822         return ret;
823 error:
824         return -1;
825 }
826
827
828
829 inline static void tcp_reader_timer_run()
830 {
831         ticks_t ticks;
832         static ticks_t prev_ticks=0;
833         
834         ticks=get_ticks_raw();
835         if (unlikely((ticks-prev_ticks)<TCPCONN_TIMEOUT_MIN_RUN)) return;
836         prev_ticks=ticks;
837         local_timer_run(&tcp_reader_ltimer, ticks);
838 }
839
840
841
842 void tcp_receive_loop(int unix_sock)
843 {
844         
845         /* init */
846         tcpmain_sock=unix_sock; /* init com. socket */
847         if (init_io_wait(&io_w, get_max_open_fds(), tcp_poll_method)<0)
848                 goto error;
849         if (init_local_timer(&tcp_reader_ltimer, get_ticks_raw())!=0)
850                 goto error;
851         /* add the unix socket */
852         if (io_watch_add(&io_w, tcpmain_sock, POLLIN,  F_TCPMAIN, 0)<0){
853                 LOG(L_CRIT, "ERROR: tcp_receive_loop: init: failed to add socket "
854                                                         " to the fd list\n");
855                 goto error;
856         }
857
858         /* initialize the config framework */
859         if (cfg_child_init()) goto error;
860
861         /* main loop */
862         switch(io_w.poll_method){
863                 case POLL_POLL:
864                                 while(1){
865                                         io_wait_loop_poll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
866                                         tcp_reader_timer_run();
867                                 }
868                                 break;
869 #ifdef HAVE_SELECT
870                 case POLL_SELECT:
871                         while(1){
872                                 io_wait_loop_select(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
873                                 tcp_reader_timer_run();
874                         }
875                         break;
876 #endif
877 #ifdef HAVE_SIGIO_RT
878                 case POLL_SIGIO_RT:
879                         while(1){
880                                 io_wait_loop_sigio_rt(&io_w, TCP_CHILD_SELECT_TIMEOUT);
881                                 tcp_reader_timer_run();
882                         }
883                         break;
884 #endif
885 #ifdef HAVE_EPOLL
886                 case POLL_EPOLL_LT:
887                         while(1){
888                                 io_wait_loop_epoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
889                                 tcp_reader_timer_run();
890                         }
891                         break;
892                 case POLL_EPOLL_ET:
893                         while(1){
894                                 io_wait_loop_epoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 1);
895                                 tcp_reader_timer_run();
896                         }
897                         break;
898 #endif
899 #ifdef HAVE_KQUEUE
900                 case POLL_KQUEUE:
901                         while(1){
902                                 io_wait_loop_kqueue(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
903                                 tcp_reader_timer_run();
904                         }
905                         break;
906 #endif
907 #ifdef HAVE_DEVPOLL
908                 case POLL_DEVPOLL:
909                         while(1){
910                                 io_wait_loop_devpoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
911                                 tcp_reader_timer_run();
912                         }
913                         break;
914 #endif
915                 default:
916                         LOG(L_CRIT, "BUG: tcp_receive_loop: no support for poll method "
917                                         " %s (%d)\n", 
918                                         poll_method_name(io_w.poll_method), io_w.poll_method);
919                         goto error;
920         }
921 error:
922         destroy_io_wait(&io_w);
923         LOG(L_CRIT, "ERROR: tcp_receive_loop: exiting...");
924         exit(-1);
925 }
926
927
928
929 #ifdef USE_STUN
930 int is_msg_complete(struct tcp_req* r)
931 {
932         if (r->has_content_len == 1) {
933                 r->state = H_STUN_FP;
934                 return 0;
935         }
936         else {
937                 /* STUN message is complete */
938                 r->state = H_STUN_END;
939                 r->complete = 1;
940                 r->has_content_len = 1; /* hack to avoid error check */
941                 return 1;
942         }
943 }
944 #endif
945
946 #endif /* USE_TCP */