core: removed obsolete DYN_BUF define condition
[sip-router] / src / core / tcp_read.c
1 /*
2  * Copyright (C) 2001-2003 FhG Fokus
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * Kamailio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  * Kamailio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20
21 /** Kamailio core :: tcp readers processes, tcp read and pre-parse msg. functions.
22  * @file tcp_read.c
23  * @ingroup core
24  * Module: @ref core
25  */
26
27 #ifdef USE_TCP
28
29 #include <stdio.h>
30 #include <errno.h>
31 #include <string.h>
32
33
34 #include <sys/time.h>
35 #include <sys/types.h>
36 #include <sys/select.h>
37 #include <sys/socket.h>
38
39 #include <unistd.h>
40 #include <stdlib.h> /* for abort() */
41
42 #include "dprint.h"
43 #include "tcp_conn.h"
44 #include "tcp_read.h"
45 #include "tcp_stats.h"
46 #include "tcp_ev.h"
47 #include "pass_fd.h"
48 #include "globals.h"
49 #include "receive.h"
50 #include "timer.h"
51 #include "local_timer.h"
52 #include "ut.h"
53 #include "trim.h"
54 #include "pt.h"
55 #include "cfg/cfg_struct.h"
56 #ifdef CORE_TLS
57 #include "tls/tls_server.h"
58 #else
59 #include "tls_hooks.h"
60 #endif /* CORE_TLS */
61 #ifdef USE_DST_BLACKLIST
62 #include "dst_blacklist.h"
63 #endif /* USE_DST_BLACKLIST */
64
65 #define HANDLE_IO_INLINE
66 #include "io_wait.h"
67 #include <fcntl.h> /* must be included after io_wait.h if SIGIO_RT is used */
68 #include "tsend.h"
69 #include "forward.h"
70 #include "events.h"
71 #include "stun.h"
72 #include "nonsip_hooks.h"
73
74 #ifdef READ_HTTP11
75 #define HTTP11CONTINUE  "HTTP/1.1 100 Continue\r\nContent-Length: 0\r\n\r\n"
76 #define HTTP11CONTINUE_LEN      (sizeof(HTTP11CONTINUE)-1)
77 #endif
78
79 #define TCPCONN_TIMEOUT_MIN_RUN  1 /* run the timers each new tick */
80
81 /* types used in io_wait* */
82 enum fd_types { F_NONE, F_TCPMAIN, F_TCPCONN };
83
84 /* list of tcp connections handled by this process */
85 static struct tcp_connection* tcp_conn_lst=0;
86 static io_wait_h io_w; /* io_wait handler*/
87 static int tcpmain_sock=-1;
88
89 static struct local_timer tcp_reader_ltimer;
90 static ticks_t tcp_reader_prev_ticks;
91
92 int is_msg_complete(struct tcp_req* r);
93
94 int ksr_tcp_accept_hep3=0;
95 int ksr_tcp_accept_haproxy=0;
96 /**
97  * control cloning of TCP receive buffer
98  * - needed for operations working directly inside the buffer
99  *   (like msg_apply_changes())
100  */
101 #define TCP_CLONE_RCVBUF
102 static int tcp_clone_rcvbuf = 0;
103
104 int tcp_set_clone_rcvbuf(int v)
105 {
106         int r;
107         r = tcp_clone_rcvbuf;
108         tcp_clone_rcvbuf = v;
109         return r;
110 }
111
112 #ifdef READ_HTTP11
113 static inline char *strfindcasestrz(str *haystack, char *needlez)
114 {
115         int i,j;
116         str needle;
117
118         needle.s = needlez;
119         needle.len = strlen(needlez);
120         for(i=0;i<haystack->len-needle.len;i++) {
121                 for(j=0;j<needle.len;j++) {
122                         if ( !((haystack->s[i+j]==needle.s[j]) ||
123                                         ( isalpha((int)haystack->s[i+j])
124                                                 && ((haystack->s[i+j])^(needle.s[j]))==0x20 )) )
125                                 break;
126                 }
127                 if (j==needle.len)
128                         return haystack->s+i;
129         }
130         return 0;
131 }
132
133 int tcp_http11_continue(struct tcp_connection *c)
134 {
135         struct dest_info dst;
136         char *p;
137         struct msg_start fline;
138         int ret;
139         str msg;
140
141         ret = 0;
142
143         msg.s = c->req.start;
144         msg.len = c->req.pos - c->req.start;
145 #ifdef READ_MSRP
146         /* skip if MSRP message */
147         if(c->req.flags&F_TCP_REQ_MSRP_FRAME)
148                 return 0;
149 #endif
150         p = parse_first_line(msg.s, msg.len, &fline);
151         if(p==NULL)
152                 return 0;
153
154         if(fline.type!=SIP_REQUEST)
155                 return 0;
156
157         /* check if http request */
158         if(fline.u.request.version.len < HTTP_VERSION_LEN
159                         || strncasecmp(fline.u.request.version.s,
160                                 HTTP_VERSION, HTTP_VERSION_LEN))
161                 return 0;
162
163         /* check for Expect header */
164         if(strfindcasestrz(&msg, "Expect: 100-continue")!=NULL)
165         {
166                 init_dst_from_rcv(&dst, &c->rcv);
167                 if (tcp_send(&dst, 0, HTTP11CONTINUE, HTTP11CONTINUE_LEN) < 0) {
168                         LM_ERR("HTTP/1.1 continue failed\n");
169                 }
170         }
171         /* check for Transfer-Encoding header */
172         if(strfindcasestrz(&msg, "Transfer-Encoding: chunked")!=NULL)
173         {
174                 c->req.flags |= F_TCP_REQ_BCHUNKED;
175                 ret = 1;
176         }
177         /* check for HTTP Via header
178          * - HTTP Via format is different that SIP Via
179          * - workaround: replace with Hia to be ignored by SIP parser
180          */
181         if((p=strfindcasestrz(&msg, "\nVia:"))!=NULL)
182         {
183                 p++;
184                 *p = 'H';
185                 LM_DBG("replaced HTTP Via with Hia [[\n%.*s]]\n", msg.len, msg.s);
186         }
187         return ret;
188 }
189 #endif /* HTTP11 */
190
191 static int tcp_emit_closed_event(struct tcp_connection *con, enum tcp_closed_reason reason)
192 {
193         int ret;
194         tcp_closed_event_info_t tev;
195         sr_event_param_t evp = {0};
196
197         ret = 0;
198         LM_DBG("TCP closed event creation triggered (reason: %d)\n", reason);
199         if(likely(sr_event_enabled(SREV_TCP_CLOSED))) {
200                 memset(&tev, 0, sizeof(tcp_closed_event_info_t));
201                 tev.reason = reason;
202                 tev.con = con;
203                 evp.data = (void*)(&tev);
204                 ret = sr_event_exec(SREV_TCP_CLOSED, &evp);
205         } else {
206                 LM_DBG("no callback registering for handling TCP closed event\n");
207         }
208         return ret;
209 }
210
211
212 /** reads data from an existing tcp connection.
213  * Side-effects: blacklisting, sets connection state to S_CONN_OK, tcp stats.
214  * @param fd - connection file descriptor
215  * @param c - tcp connection structure. c->state might be changed and
216  *             receive info might be used for blacklisting.
217  * @param buf - buffer where the received data will be stored.
218  * @param b_size - buffer size.
219  * @param flags - value/result - used to signal a seen or "forced" EOF on the
220  *     connection (when it is known that no more data will come after the 
221  *     current socket buffer is emptied )=> return/signal EOF on the first
222  *     short read (=> don't use it on POLLPRI, as OOB data will cause short
223  *     reads even if there are still remaining bytes in the socket buffer)
224  *     input: RD_CONN_FORCE_EOF  - force EOF after the first successful read
225  *                                 (bytes_read >=0 )
226  *     output: RD_CONN_SHORT_READ - if the read exhausted all the bytes
227  *                                  in the socket read buffer.
228  *             RD_CONN_EOF - if EOF detected (0 bytes read) or forced via
229  *                           RD_CONN_FORCE_EOF.
230  *             RD_CONN_REPEAT_READ - the read should be repeated immediately
231  *                                   (used only by the tls code for now).
232  *     Note: RD_CONN_SHORT_READ & RD_CONN_EOF _are_ not cleared internally,
233  *           so one should clear them before calling this function.
234  * @return number of bytes read, 0 on EOF or -1 on error,
235  * on EOF it also sets c->state to S_CONN_EOF.
236  * (to distinguish from reads that would block which could return 0)
237  * RD_CONN_SHORT_READ is also set in *flags for short reads.
238  * EOF checking should be done by checking the RD_CONN_EOF flag.
239  */
240 int tcp_read_data(int fd, struct tcp_connection *c,
241                                         char* buf, int b_size, int* flags)
242 {
243         int bytes_read;
244
245 again:
246         bytes_read=read(fd, buf, b_size);
247
248         if (likely(bytes_read!=b_size)){
249                 if(unlikely(bytes_read==-1)){
250                         if (errno == EWOULDBLOCK || errno == EAGAIN){
251                                 bytes_read=0; /* nothing has been read */
252                         }else if (errno == EINTR){
253                                 goto again;
254                         }else{
255                                 if (unlikely(c->state==S_CONN_CONNECT)){
256                                         switch(errno){
257                                                 case ECONNRESET:
258 #ifdef USE_DST_BLACKLIST
259                                                         dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
260                                                                                                 &c->rcv.src_su,
261                                                                                                 &c->send_flags, 0);
262 #endif /* USE_DST_BLACKLIST */
263                                                         TCP_EV_CONNECT_RST(errno, TCP_LADDR(c),
264                                                                         TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
265                                                         break;
266                                                 case ETIMEDOUT:
267 #ifdef USE_DST_BLACKLIST
268                                                         dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
269                                                                                                 &c->rcv.src_su,
270                                                                                                 &c->send_flags, 0);
271 #endif /* USE_DST_BLACKLIST */
272                                                         TCP_EV_CONNECT_TIMEOUT(errno, TCP_LADDR(c),
273                                                                         TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
274                                                         break;
275                                                 default:
276                                                         TCP_EV_CONNECT_ERR(errno, TCP_LADDR(c),
277                                                                         TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
278                                         }
279                                         TCP_STATS_CONNECT_FAILED();
280                                 }else{
281                                                 switch(errno){
282                                                         case ECONNRESET:
283                                                                 TCP_STATS_CON_RESET();
284 #ifdef USE_DST_BLACKLIST
285                                                                 dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto,
286                                                                                                         &c->rcv.src_su,
287                                                                                                         &c->send_flags, 0);
288 #endif /* USE_DST_BLACKLIST */
289                                                                 break;
290                                                         case ETIMEDOUT:
291 #ifdef USE_DST_BLACKLIST
292                                                                 dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto,
293                                                                                                         &c->rcv.src_su,
294                                                                                                         &c->send_flags, 0);
295 #endif /* USE_DST_BLACKLIST */
296                                                                 break;
297                                                 }
298                                 }
299                                 LOG(cfg_get(core, core_cfg, corelog),
300                                                 "error reading: %s (%d) ([%s]:%u ->",
301                                                 strerror(errno), errno,
302                                                 ip_addr2a(&c->rcv.src_ip), c->rcv.src_port);
303                                 LOG(cfg_get(core, core_cfg, corelog),"-> [%s]:%u)\n",
304                                                 ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port);
305                                 if (errno == ETIMEDOUT) {
306                                         tcp_emit_closed_event(c, TCP_CLOSED_TIMEOUT);
307                                 } else if (errno == ECONNRESET) {
308                                         tcp_emit_closed_event(c, TCP_CLOSED_RESET);
309                                 }
310                                 return -1;
311                         }
312                 }else if (unlikely((bytes_read==0) ||
313                                         (*flags & RD_CONN_FORCE_EOF))){
314                         c->state=S_CONN_EOF;
315                         *flags|=RD_CONN_EOF;
316                         tcp_emit_closed_event(c, TCP_CLOSED_EOF);
317                         LM_DBG("EOF on %p, FD %d ([%s]:%u ->", c, fd,
318                                         ip_addr2a(&c->rcv.src_ip), c->rcv.src_port);
319                         LM_DBG("-> [%s]:%u)\n", ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port);
320                 }else{
321                         if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT)){
322                                 TCP_STATS_ESTABLISHED(c->state);
323                                 c->state=S_CONN_OK;
324                         }
325                 }
326                 /* short read */
327                 *flags|=RD_CONN_SHORT_READ;
328         }else{ /* else normal full read */
329                 if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT)){
330                         TCP_STATS_ESTABLISHED(c->state);
331                         c->state=S_CONN_OK;
332                 }
333         }
334         return bytes_read;
335 }
336
337
338
339 /* reads next available bytes
340  *   c- tcp connection used for reading, tcp_read changes also c->state on
341  *      EOF and c->req.error on read error
342  *   * flags - value/result - used to signal a seen or "forced" EOF on the
343  *     connection (when it is known that no more data will come after the
344  *     current socket buffer is emptied )=> return/signal EOF on the first
345  *     short read (=> don't use it on POLLPRI, as OOB data will cause short
346  *      reads even if there are still remaining bytes in the socket buffer)
347  * return number of bytes read, 0 on EOF or -1 on error,
348  * on EOF it also sets c->state to S_CONN_EOF.
349  * (to distinguish from reads that would block which could return 0)
350  * RD_CONN_SHORT_READ is also set in *flags for short reads.
351  * sets also r->error */
352 int tcp_read(struct tcp_connection *c, int* flags)
353 {
354         int bytes_free, bytes_read;
355         struct tcp_req *r;
356         int fd;
357
358         r=&c->req;
359         fd=c->fd;
360         bytes_free=r->b_size - (unsigned int)(r->pos - r->buf);
361
362         if (unlikely(bytes_free<=0)){
363                 LM_ERR("buffer overrun, dropping ([%s]:%u -> [%s]:%u)\n",
364                                 ip_addr2a(&c->rcv.src_ip), c->rcv.src_port,
365                                 ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port);
366                 r->error=TCP_REQ_OVERRUN;
367                 return -1;
368         }
369         bytes_read = tcp_read_data(fd, c, r->pos, bytes_free, flags);
370         if (unlikely(bytes_read < 0)){
371                 r->error=TCP_READ_ERROR;
372                 return -1;
373         }
374 #ifdef EXTRA_DEBUG
375         LM_DBG("read %d bytes:\n%.*s\n", bytes_read, bytes_read, r->pos);
376 #endif
377         r->pos+=bytes_read;
378         return bytes_read;
379 }
380
381
382
383 /* reads all headers (until double crlf), & parses the content-length header
384  * (WARNING: inefficient, tries to reuse receive_msg but will go through
385  * the headers twice [once here looking for Content-Length and for the end
386  * of the headers and once in receive_msg]; a more speed efficient version will
387  * result in either major code duplication or major changes to the receive code)
388  * returns number of bytes read & sets r->state & r->body
389  * when either r->body!=0 or r->state==H_BODY =>
390  * all headers have been read. It should be called in a while loop.
391  * returns < 0 if error or 0 if EOF */
392 int tcp_read_headers(struct tcp_connection *c, int* read_flags)
393 {
394         int bytes, remaining;
395         char *p;
396         struct tcp_req* r;
397         unsigned int mc;   /* magic cookie */
398         unsigned short body_len;
399
400 #ifdef READ_MSRP
401         char *mfline;
402         str mtransid;
403 #endif
404
405         #define crlf_default_skip_case \
406                                         case '\n': \
407                                                 r->state=H_LF; \
408                                                 break; \
409                                         default: \
410                                                 r->state=H_SKIP
411         
412         #define content_len_beg_case \
413                                         case ' ': \
414                                         case '\t': \
415                                                 if (!TCP_REQ_HAS_CLEN(r)) r->state=H_STARTWS; \
416                                                 else r->state=H_SKIP; \
417                                                         /* not interested if we already found one */ \
418                                                 break; \
419                                         case 'C': \
420                                         case 'c': \
421                                                 if(!TCP_REQ_HAS_CLEN(r)) r->state=H_CONT_LEN1; \
422                                                 else r->state=H_SKIP; \
423                                                 break; \
424                                         case 'l': \
425                                         case 'L': \
426                                                 /* short form for Content-Length */ \
427                                                 if (!TCP_REQ_HAS_CLEN(r)) r->state=H_L_COLON; \
428                                                 else r->state=H_SKIP; \
429                                                 break
430                                                 
431         #define change_state(upper, lower, newstate)\
432                                         switch(*p){ \
433                                                 case upper: \
434                                                 case lower: \
435                                                         r->state=(newstate); break; \
436                                                 crlf_default_skip_case; \
437                                         }
438
439         #define change_state_case(state0, upper, lower, newstate)\
440                                         case state0: \
441                                                           change_state(upper, lower, newstate); \
442                                                           p++; \
443                                                           break
444
445
446         r=&c->req;
447         if(r->parsed<r->buf || r->parsed>r->buf+r->b_size) {
448                 if(r->parsed<r->buf && (unsigned char)r->state==H_SKIP_EMPTY) {
449                         /* give it a chance to parse from beginning */
450                         LM_WARN("resetting parsed pointer (buf:%p parsed:%p bsize:%u)\n",
451                                 r->buf, r->parsed, r->b_size);
452                         r->parsed = r->buf;
453                 } else {
454                         LM_ERR("out of bounds parsed pointer (buf:%p parsed:%p bsize:%u)\n",
455                                 r->buf, r->parsed, r->b_size);
456                         r->parsed = r->buf;
457                         r->content_len=0;
458                         r->error=TCP_REQ_BAD_LEN;
459                         r->state=H_SKIP; /* skip state now */
460                         return -1;
461                 }
462         }
463         /* if we still have some unparsed part, parse it first, don't do the read*/
464         if (unlikely(r->parsed<r->pos)){
465                 bytes=0;
466         }else{
467 #ifdef USE_TLS
468                 if (unlikely(c->type==PROTO_TLS))
469                         bytes=tls_read(c, read_flags);
470                 else
471 #endif
472                         bytes=tcp_read(c, read_flags);
473                 if (bytes<=0) return bytes;
474         }
475         p=r->parsed;
476
477         while(p<r->pos && r->error==TCP_REQ_OK){
478                 switch((unsigned char)r->state){
479                         case H_BODY: /* read the body*/
480                                 remaining=r->pos-p;
481                                 if (remaining>r->bytes_to_go) remaining=r->bytes_to_go;
482                                 r->bytes_to_go-=remaining;
483                                 p+=remaining;
484                                 if (r->bytes_to_go==0){
485                                         r->flags|=F_TCP_REQ_COMPLETE;
486                                         goto skip;
487                                 }
488                                 break;
489
490                         case H_SKIP:
491                                 /* find lf, we are in this state if we are not interested
492                                  * in anything till end of line*/
493                                 p=q_memchr(p, '\n', r->pos-p);
494                                 if (p){
495 #ifdef READ_MSRP
496                                         /* catch if it is MSRP or not with first '\n' */
497                                         if(!((r->flags&F_TCP_REQ_MSRP_NO)
498                                                                 || (r->flags&F_TCP_REQ_MSRP_FRAME))) {
499                                                 if((r->pos - r->start)>5
500                                                                         && strncmp(r->start, "MSRP ", 5)==0)
501                                                 {
502                                                         r->flags |= F_TCP_REQ_MSRP_FRAME;
503                                                 } else {
504                                                         r->flags |= F_TCP_REQ_MSRP_NO;
505                                                 }
506                                         }
507 #endif
508                                         p++;
509                                         r->state=H_LF;
510                                 }else{
511                                         p=r->pos;
512                                 }
513                                 break;
514                                 
515                         case H_LF:
516                                 /* terminate on LF CR LF or LF LF */
517                                 switch (*p){
518                                         case '\r':
519                                                 r->state=H_LFCR;
520                                                 break;
521                                         case '\n':
522                                                 /* found LF LF */
523                                                 r->state=H_BODY;
524 #ifdef READ_HTTP11
525                                                 if (cfg_get(tcp, tcp_cfg, accept_no_cl)!=0)
526                                                         tcp_http11_continue(c);
527 #endif
528                                                 if (TCP_REQ_HAS_CLEN(r)){
529                                                         r->body=p+1;
530                                                         r->bytes_to_go=r->content_len;
531                                                         if (r->bytes_to_go==0){
532                                                                 r->flags|=F_TCP_REQ_COMPLETE;
533                                                                 p++;
534                                                                 goto skip;
535                                                         }
536                                                 }else{
537                                                         if(cfg_get(tcp, tcp_cfg, accept_no_cl)!=0) {
538 #ifdef READ_MSRP
539                                                                 /* if MSRP message */
540                                                                 if(c->req.flags&F_TCP_REQ_MSRP_FRAME)
541                                                                 {
542                                                                         r->body=p+1;
543                                                                         /* at least 3 bytes: 0\r\n */
544                                                                         r->bytes_to_go=3;
545                                                                         p++;
546                                                                         r->content_len = 0;
547                                                                         r->state=H_MSRP_BODY;
548                                                                         break;
549                                                                 }
550 #endif
551
552 #ifdef READ_HTTP11
553                                                                 if(TCP_REQ_BCHUNKED(r)) {
554                                                                         r->body=p+1;
555                                                                         /* at least 3 bytes: 0\r\n */
556                                                                         r->bytes_to_go=3;
557                                                                         p++;
558                                                                         r->content_len = 0;
559                                                                         r->state=H_HTTP11_CHUNK_START;
560                                                                         break;
561                                                                 }
562 #endif
563                                                                 r->body=p+1;
564                                                                 r->bytes_to_go=0;
565                                                                 r->flags|=F_TCP_REQ_COMPLETE;
566                                                                 p++;
567                                                                 goto skip;
568                                                         } else {
569                                                                 LM_DBG("no clen, p=%X\n", *p);
570                                                                 r->error=TCP_REQ_BAD_LEN;
571                                                         }
572                                                 }
573                                                 break;
574                                         case '-':
575                                                 r->state=H_SKIP;
576 #ifdef READ_MSRP
577                                                 /* catch end of MSRP frame without body
578                                                  *     '-------sessid$\r\n'
579                                                  * follows headers wihtout extra CRLF */
580                                                 if(r->flags&F_TCP_REQ_MSRP_FRAME) {
581                                                         p--;
582                                                         r->state=H_MSRP_BODY_END;
583                                                 }
584 #endif
585                                                 break;
586                                         content_len_beg_case;
587                                         default: 
588                                                 r->state=H_SKIP;
589                                 }
590                                 p++;
591                                 break;
592                         case H_LFCR:
593                                 if (*p=='\n'){
594                                         /* found LF CR LF */
595                                         r->state=H_BODY;
596 #ifdef READ_HTTP11
597                                         if (cfg_get(tcp, tcp_cfg, accept_no_cl)!=0)
598                                                 tcp_http11_continue(c);
599 #endif
600                                         if (TCP_REQ_HAS_CLEN(r)){
601                                                 r->body=p+1;
602                                                 r->bytes_to_go=r->content_len;
603                                                 if (r->bytes_to_go==0){
604                                                         r->flags|=F_TCP_REQ_COMPLETE;
605                                                         p++;
606                                                         goto skip;
607                                                 }
608                                         }else{
609                                                 if (cfg_get(tcp, tcp_cfg, accept_no_cl)!=0) {
610 #ifdef READ_MSRP
611                                                         /* if MSRP message */
612                                                         if(c->req.flags&F_TCP_REQ_MSRP_FRAME)
613                                                         {
614                                                                 r->body=p+1;
615                                                                 /* at least 3 bytes: 0\r\n */
616                                                                 r->bytes_to_go=3;
617                                                                 p++;
618                                                                 r->content_len = 0;
619                                                                 r->state=H_MSRP_BODY;
620                                                                 break;
621                                                         }
622 #endif
623
624 #ifdef READ_HTTP11
625                                                         if(TCP_REQ_BCHUNKED(r)) {
626                                                                 r->body=p+1;
627                                                                 /* at least 3 bytes: 0\r\n */
628                                                                 r->bytes_to_go=3;
629                                                                 p++;
630                                                                 r->content_len = 0;
631                                                                 r->state=H_HTTP11_CHUNK_START;
632                                                                 break;
633                                                         }
634 #endif
635                                                         r->body=p+1;
636                                                         r->bytes_to_go=0;
637                                                         r->flags|=F_TCP_REQ_COMPLETE;
638                                                         p++;
639                                                         goto skip;
640                                                 } else {
641                                                         LM_DBG("no clen, p=%X\n", *p);
642                                                         r->error=TCP_REQ_BAD_LEN;
643                                                 }
644                                         }
645                                 }else r->state=H_SKIP;
646                                 p++;
647                                 break;
648                                 
649                         case H_STARTWS:
650                                 switch (*p){
651                                         content_len_beg_case;
652                                         crlf_default_skip_case;
653                                 }
654                                 p++;
655                                 break;
656                         case H_SKIP_EMPTY:
657                                 switch (*p){
658                                         case '\n':
659                                                 break;
660                                         case '\r':
661                                                 if (cfg_get(tcp, tcp_cfg, crlf_ping)) {
662                                                         r->state=H_SKIP_EMPTY_CR_FOUND;
663                                                         r->start=p;
664                                                 }
665                                                 break;
666                                         case ' ':
667                                         case '\t':
668                                                 /* skip empty lines */
669                                                 break;
670                                         case 'C': 
671                                         case 'c': 
672                                                 r->state=H_CONT_LEN1; 
673                                                 r->start=p;
674                                                 break;
675                                         case 'l':
676                                         case 'L':
677                                                 /* short form for Content-Length */
678                                                 r->state=H_L_COLON;
679                                                 r->start=p;
680                                                 break;
681                                         default:
682                                                 /* stun test */
683                                                 if (unlikely(sr_event_enabled(SREV_STUN_IN)) && (unsigned char)*p == 0x00) {
684                                                         r->state=H_STUN_MSG;
685                                                         /* body is used as pointer to the last used byte */
686                                                         r->body=p;
687                                                         r->content_len = 0;
688                                                         LM_DBG("stun msg detected\n");
689                                                 } else {
690                                                         r->state=H_SKIP;
691                                                 }
692                                                 r->start=p;
693                                 };
694                                 p++;
695                                 break;
696
697                         case H_SKIP_EMPTY_CR_FOUND:
698                                 if (*p=='\n'){
699                                         r->state=H_SKIP_EMPTY_CRLF_FOUND;
700                                         p++;
701                                 }else{
702                                         r->state=H_SKIP_EMPTY;
703                                 }
704                                 break;
705
706                         case H_SKIP_EMPTY_CRLF_FOUND:
707                                 if (*p=='\r'){
708                                         r->state = H_SKIP_EMPTY_CRLFCR_FOUND;
709                                         p++;
710                                 }else{
711                                         r->state = H_SKIP_EMPTY;
712                                 }
713                                 break;
714
715                         case H_SKIP_EMPTY_CRLFCR_FOUND:
716                                 if (*p=='\n'){
717                                         r->state = H_PING_CRLF;
718                                         r->flags |= F_TCP_REQ_HAS_CLEN |
719                                                         F_TCP_REQ_COMPLETE; /* hack to avoid error check */
720                                         p++;
721                                         goto skip;
722                                 }else{
723                                         r->state = H_SKIP_EMPTY;
724                                 }
725                                 break;
726
727                         case H_STUN_MSG:
728                                 if ((r->pos - r->body) >= sizeof(struct stun_hdr)) {
729                                         /* copy second short from buffer where should be body 
730                                          * length 
731                                          */
732                                         memcpy(&body_len, &r->start[sizeof(unsigned short)], 
733                                                 sizeof(unsigned short));
734                                         
735                                         body_len = ntohs(body_len);
736                                         
737                                         /* check if there is valid magic cookie */
738                                         memcpy(&mc, &r->start[sizeof(unsigned int)], 
739                                                 sizeof(unsigned int));
740                                         mc = ntohl(mc);
741                                         /* using has_content_len as a flag if there should be
742                                          * fingerprint or no
743                                          */
744                                         r->flags |= (mc == MAGIC_COOKIE) ? F_TCP_REQ_HAS_CLEN : 0;
745                                         
746                                         r->body += sizeof(struct stun_hdr);
747                                         p = r->body; 
748                                         
749                                         if (body_len > 0) {
750                                                 r->state = H_STUN_READ_BODY;
751                                         }
752                                         else {
753                                                 if (is_msg_complete(r) != 0) {
754                                                         goto skip;
755                                                 }
756                                                 else {
757                                                         /* set content_len to length of fingerprint */
758                                                         body_len = sizeof(struct stun_attr) + 20;
759                                                         /* 20 is SHA_DIGEST_LENGTH from openssl/sha.h */
760                                                 }
761                                         }
762                                         r->content_len=body_len;
763                                 }
764                                 else {
765                                         p = r->pos; 
766                                 }
767                                 break;
768                                 
769                         case H_STUN_READ_BODY:
770                                 /* check if the whole body was read */
771                                 body_len=r->content_len;
772                                 if ((r->pos - r->body) >= body_len) {
773                                         r->body += body_len;
774                                         p = r->body;
775                                         if (is_msg_complete(r) != 0) {
776                                                 r->content_len=0;
777                                                 goto skip;
778                                         }
779                                         else {
780                                                 /* set content_len to length of fingerprint */
781                                                 body_len = sizeof(struct stun_attr) + 20;
782                                                 /* 20 is SHA_DIGEST_LENGTH from openssl/sha.h */
783                                                 r->content_len=body_len;
784                                         }
785                                 }
786                                 else {
787                                         p = r->pos;
788                                 }
789                                 break;
790                                 
791                         case H_STUN_FP:
792                                 /* content_len contains length of fingerprint in this place! */
793                                 body_len=r->content_len;
794                                 if ((r->pos - r->body) >= body_len) {
795                                         r->body += body_len;
796                                         p = r->body;
797                                         r->state = H_STUN_END;
798                                         r->flags |= F_TCP_REQ_COMPLETE |
799                                                 F_TCP_REQ_HAS_CLEN; /* hack to avoid error check */
800                                         r->content_len=0;
801                                         goto skip;
802                                 }
803                                 else {
804                                         p = r->pos;
805                                 }
806                                 break;
807
808                         change_state_case(H_CONT_LEN1,  'O', 'o', H_CONT_LEN2);
809                         change_state_case(H_CONT_LEN2,  'N', 'n', H_CONT_LEN3);
810                         change_state_case(H_CONT_LEN3,  'T', 't', H_CONT_LEN4);
811                         change_state_case(H_CONT_LEN4,  'E', 'e', H_CONT_LEN5);
812                         change_state_case(H_CONT_LEN5,  'N', 'n', H_CONT_LEN6);
813                         change_state_case(H_CONT_LEN6,  'T', 't', H_CONT_LEN7);
814                         change_state_case(H_CONT_LEN7,  '-', '_', H_CONT_LEN8);
815                         change_state_case(H_CONT_LEN8,  'L', 'l', H_CONT_LEN9);
816                         change_state_case(H_CONT_LEN9,  'E', 'e', H_CONT_LEN10);
817                         change_state_case(H_CONT_LEN10, 'N', 'n', H_CONT_LEN11);
818                         change_state_case(H_CONT_LEN11, 'G', 'g', H_CONT_LEN12);
819                         change_state_case(H_CONT_LEN12, 'T', 't', H_CONT_LEN13);
820                         change_state_case(H_CONT_LEN13, 'H', 'h', H_L_COLON);
821
822                         case H_L_COLON:
823                                 switch(*p){
824                                         case ' ':
825                                         case '\t':
826                                                 break; /* skip space */
827                                         case ':':
828                                                 r->state=H_CONT_LEN_BODY;
829                                                 break;
830                                         crlf_default_skip_case;
831                                 };
832                                 p++;
833                                 break;
834
835                         case  H_CONT_LEN_BODY:
836                                 switch(*p){
837                                         case ' ':
838                                         case '\t':
839                                                 break; /* eat space */
840                                         case '0':
841                                         case '1':
842                                         case '2':
843                                         case '3':
844                                         case '4':
845                                         case '5':
846                                         case '6':
847                                         case '7':
848                                         case '8':
849                                         case '9':
850                                                 r->state=H_CONT_LEN_BODY_PARSE;
851                                                 r->content_len=(*p-'0');
852                                                 break;
853                                         /*FIXME: content length on different lines ! */
854                                         crlf_default_skip_case;
855                                 }
856                                 p++;
857                                 break;
858
859                         case H_CONT_LEN_BODY_PARSE:
860                                 switch(*p){
861                                         case '0':
862                                         case '1':
863                                         case '2':
864                                         case '3':
865                                         case '4':
866                                         case '5':
867                                         case '6':
868                                         case '7':
869                                         case '8':
870                                         case '9':
871                                                 r->content_len=r->content_len*10+(*p-'0');
872                                                 break;
873                                         case '\r':
874                                         case ' ':
875                                         case '\t': /* FIXME: check if line contains only WS */
876                                                 if(r->content_len<0) {
877                                                         LM_ERR("bad Content-Length header value %d in"
878                                                                         " state %d\n", r->content_len, r->state);
879                                                         r->content_len=0;
880                                                         r->error=TCP_REQ_BAD_LEN;
881                                                         r->state=H_SKIP; /* skip now */
882                                                 }
883                                                 r->state=H_SKIP;
884                                                 r->flags|=F_TCP_REQ_HAS_CLEN;
885                                                 break;
886                                         case '\n':
887                                                 /* end of line, parse successful */
888                                                 if(r->content_len<0) {
889                                                         LM_ERR("bad Content-Length header value %d in"
890                                                                         " state %d\n", r->content_len, r->state);
891                                                         r->content_len=0;
892                                                         r->error=TCP_REQ_BAD_LEN;
893                                                         r->state=H_SKIP; /* skip now */
894                                                 }
895                                                 r->state=H_LF;
896                                                 r->flags|=F_TCP_REQ_HAS_CLEN;
897                                                 break;
898                                         default:
899                                                 LM_ERR("bad Content-Length header value, unexpected "
900                                                                 "char %c in state %d\n", *p, r->state);
901                                                 r->state=H_SKIP; /* try to find another?*/
902                                 }
903                                 p++;
904                                 break;
905                         
906 #ifdef READ_HTTP11
907                         case H_HTTP11_CHUNK_START: /* start a new body chunk: SIZE\r\nBODY\r\n */
908                                 r->chunk_size = 0;
909                                 r->state = H_HTTP11_CHUNK_SIZE;
910                                 break;
911                         case H_HTTP11_CHUNK_BODY: /* content of chunnk */
912                                 remaining=r->pos-p;
913                                 if (remaining>r->bytes_to_go) remaining=r->bytes_to_go;
914                                 r->bytes_to_go-=remaining;
915                                 p+=remaining;
916                                 if (r->bytes_to_go==0){
917                                         r->state = H_HTTP11_CHUNK_END;
918                                         /* shift back body content */
919                                         if(r->chunk_size>0 && p-r->chunk_size>r->body) {
920                                                 memmove(r->body + r->content_len, p - r->chunk_size,
921                                                                 r->chunk_size);
922                                                 r->content_len += r->chunk_size;
923                                         }
924                                         goto skip;
925                                 }
926                                 break;
927
928                         case H_HTTP11_CHUNK_END:
929                                 switch(*p){
930                                         case '\r':
931                                         case ' ':
932                                         case '\t': /* skip */
933                                                 break;
934                                         case '\n':
935                                                 r->state = H_HTTP11_CHUNK_START;
936                                                 break;
937                                         default:
938                                                 LM_ERR("bad chunk, unexpected "
939                                                                 "char %c in state %d\n", *p, r->state);
940                                                 r->state=H_SKIP; /* try to find another?*/
941                                 }
942                                 p++;
943                                 break;
944
945                         case H_HTTP11_CHUNK_SIZE:
946                                 switch(*p){
947                                         case '0': case '1': case '2': case '3':
948                                         case '4': case '5': case '6': case '7':
949                                         case '8': case '9':
950                                                 r->chunk_size <<= 4;
951                                                 r->chunk_size += *p - '0';
952                                                 break;
953                                         case 'a': case 'b': case 'c': case 'd':
954                                         case 'e': case 'f':
955                                                 r->chunk_size <<= 4;
956                                                 r->chunk_size += *p - 'a' + 10;
957                                                 break;
958                                         case 'A': case 'B': case 'C': case 'D':
959                                         case 'E': case 'F':
960                                                 r->chunk_size <<= 4;
961                                                 r->chunk_size += *p - 'A' + 10;
962                                                 break;
963                                         case '\r':
964                                         case ' ':
965                                         case '\t': /* skip */
966                                                 break;
967                                         case '\n':
968                                                 /* end of line, parse successful */
969                                                 r->state=H_HTTP11_CHUNK_BODY;
970                                                 r->bytes_to_go = r->chunk_size;
971                                                 if (r->bytes_to_go==0){
972                                                         r->state=H_HTTP11_CHUNK_FINISH;
973                                                         r->flags|=F_TCP_REQ_COMPLETE;
974                                                         p++;
975                                                         goto skip;
976                                                 }
977                                                 break;
978                                         default:
979                                                 LM_ERR("bad chunk size value, unexpected "
980                                                                 "char %c in state %d\n", *p, r->state);
981                                                 r->state=H_SKIP; /* try to find another?*/
982                                 }
983                                 p++;
984                                 break;
985 #endif
986 #ifdef READ_MSRP
987                         case H_MSRP_BODY: /* body of msrp frame */
988                                 /* find lf, we are in this state if we are not interested
989                                  * in anything till end of line*/
990                                 r->flags |= F_TCP_REQ_MSRP_BODY;
991                                 p = q_memchr(p, '\n', r->pos-p);
992                                 if (p) {
993                                         p++;
994                                         r->state=H_MSRP_BODY_LF;
995                                 } else {
996                                         p=r->pos;
997                                 }
998                                 break;
999                         case H_MSRP_BODY_LF: /* LF in body of msrp frame */
1000                                 switch (*p) {
1001                                         case '-':
1002                                                         p--;
1003                                                         r->state=H_MSRP_BODY_END;
1004                                                 break;
1005                                         default:
1006                                                 r->state=H_MSRP_BODY;
1007                                 }
1008                                 p++;
1009                                 break;
1010                         case H_MSRP_BODY_END: /* end of body for msrp frame */
1011                                 /* find LF and check if it is end-line */
1012                                 p = q_memchr(p, '\n', r->pos-p);
1013                                 if (p) {
1014                                         /* check if it is end line '-------sessid$\r\n' */
1015                                         if(r->pos - r->start < 10) {
1016                                                 LM_ERR("weird situation when reading MSRP frame"
1017                                                                 " - continue reading\n");
1018                                                 /* *p=='\n' */
1019                                                 r->state=H_MSRP_BODY_LF;
1020                                                 p++;
1021                                                 break;
1022                                         }
1023                                         if(*(p-1)!='\r') {
1024                                                 /* not ending in '\r\n' - not end-line */
1025                                                 /* *p=='\n' */
1026                                                 r->state=H_MSRP_BODY_LF;
1027                                                 p++;
1028                                                 break;
1029                                         }
1030                                         /* locate transaction id in first line
1031                                          * -- first line exists, that's why we are here */
1032                                         mfline =  q_memchr(r->start, '\n', r->pos-r->start);
1033                                         mtransid.s = q_memchr(r->start + 5 /* 'MSRP ' */, ' ',
1034                                                         mfline - r->start);
1035                                         mtransid.len = mtransid.s - r->start - 5;
1036                                         mtransid.s = r->start + 5;
1037                                         trim(&mtransid);
1038                                         if(memcmp(mtransid.s,
1039                                                         p - 1 /*\r*/ - 1 /* '+'|'#'|'$' */ - mtransid.len,
1040                                                         mtransid.len)!=0) {
1041                                                 /* no match on session id - not end-line */
1042                                                 /* *p=='\n' */
1043                                                 r->state=H_MSRP_BODY_LF;
1044                                                 p++;
1045                                                 break;
1046                                         }
1047                                         if(memcmp(p - 1 /*\r*/ - 1 /* '+'|'#'|'$' */ - mtransid.len
1048                                                                 - 7 /* 7 x '-' */ - 1 /* '\n' */, "\n-------",
1049                                                                 8)!=0) {
1050                                                 /* no match on "\n-------" - not end-line */
1051                                                 /* *p=='\n' */
1052                                                 r->state=H_MSRP_BODY_LF;
1053                                                 p++;
1054                                                 break;
1055                                         }
1056                                         r->state=H_MSRP_FINISH;
1057                                         r->flags|=F_TCP_REQ_COMPLETE;
1058                                         p++;
1059                                         goto skip;
1060
1061                                 } else {
1062                                         p=r->pos;
1063                                 }
1064                                 break;
1065 #endif
1066
1067                         default:
1068                                 LM_CRIT("unexpected state %d\n", r->state);
1069                                 abort();
1070                 }
1071         }
1072 skip:
1073         r->parsed=p;
1074         return bytes;
1075 }
1076
1077
1078 #ifdef READ_MSRP
1079 int msrp_process_msg(char* tcpbuf, unsigned int len,
1080                 struct receive_info* rcv_info, struct tcp_connection* con)
1081 {
1082         int ret;
1083         tcp_event_info_t tev;
1084         sr_event_param_t evp = {0};
1085
1086         ret = 0;
1087         LM_DBG("MSRP Message: [[>>>\n%.*s<<<]]\n", len, tcpbuf);
1088         if(likely(sr_event_enabled(SREV_TCP_MSRP_FRAME))) {
1089                 memset(&tev, 0, sizeof(tcp_event_info_t));
1090                 tev.type = SREV_TCP_MSRP_FRAME;
1091                 tev.buf = tcpbuf;
1092                 tev.len = len;
1093                 tev.rcv = rcv_info;
1094                 tev.con = con;
1095                 evp.data = (void*)(&tev);
1096                 ret = sr_event_exec(SREV_TCP_MSRP_FRAME, &evp);
1097         } else {
1098                 LM_DBG("no callback registering for handling MSRP - dropping!\n");
1099         }
1100         return ret;
1101 }
1102 #endif
1103
1104 #ifdef READ_WS
1105 static int tcp_read_ws(struct tcp_connection *c, int* read_flags)
1106 {
1107         int bytes;
1108         uint32_t size, pos, mask_present, len;
1109         char *p;
1110         struct tcp_req *r;
1111
1112         r=&c->req;
1113 #ifdef USE_TLS
1114         if (unlikely(c->type == PROTO_WSS))
1115                 bytes = tls_read(c, read_flags);
1116         else
1117 #endif
1118                 bytes = tcp_read(c, read_flags);
1119
1120         if (bytes < 0) {
1121                 /* read error */
1122                 return bytes;
1123         }
1124         if (r->parsed == r->pos) {
1125                 /* nothing else to parse */
1126                 return bytes;
1127         }
1128         if (r->parsed > r->pos) {
1129                 LM_ERR("req buf pos (%p) before parsed (%p) [%d]\n", r->pos, r->parsed,
1130                                 bytes);
1131                 return -1;
1132         }
1133         if(r->pos > r->buf + r->b_size) {
1134                 LM_ERR("req pos (%p) over buf (%p / %u) - parsed (%p) [%d]\n", r->pos,
1135                                 r->buf, r->b_size, r->parsed, bytes);
1136                 return -1;
1137         }
1138         if(r->buf > r->parsed) {
1139                 LM_ERR("req parsed (%p) before buf (%p / %u) - pos (%p) [%d]\n",
1140                                 r->parsed, r->buf, r->b_size, r->pos, bytes);
1141                 return -1;
1142         }
1143
1144         size = r->pos - r->parsed;
1145
1146         p = r->parsed;
1147         pos = 0;
1148
1149         /*
1150          0                   1                   2                   3
1151          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1152         +-+-+-+-+-------+-+-------------+-------------------------------+
1153         |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
1154         |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
1155         |N|V|V|V|       |S|             |   (if payload len==126/127)   |
1156         | |1|2|3|       |K|             |                               |
1157         +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
1158         |     Extended payload length continued, if payload len == 127  |
1159         + - - - - - - - - - - - - - - - +-------------------------------+
1160         |                               |Masking-key, if MASK set to 1  |
1161         +-------------------------------+-------------------------------+
1162         | Masking-key (continued)       |          Payload Data         |
1163         +-------------------------------- - - - - - - - - - - - - - - - +
1164         :                     Payload Data continued ...                :
1165         + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
1166         |                     Payload Data continued ...                |
1167         +---------------------------------------------------------------+
1168
1169         Do minimal parse required to make sure the full message has been
1170         received (websocket module will do full parse and validation).
1171         */
1172
1173         /* Process first two bytes */
1174         if (size < pos + 2)
1175                 goto skip;
1176         pos++;
1177         mask_present = p[pos] & 0x80;
1178         len = (p[pos] & 0xff) & ~0x80;
1179         pos++;
1180
1181         /* Work out real length */
1182         if (len == 126) {
1183                 /* 2 bytes store the payload size */
1184                 if (size < pos + 2)
1185                         goto skip;
1186
1187                 len = ((p[pos + 0] & 0xff) <<  8) | ((p[pos + 1] & 0xff) <<  0);
1188                 pos += 2;
1189         } else if (len == 127) {
1190                 /* 8 bytes store the payload size */
1191                 if (size < pos + 8) {
1192                         goto skip;
1193                 }
1194
1195                 /* Only decoding the last four bytes of the length...
1196                    This limits the size of WebSocket messages that can be
1197                    handled to 2^32 - which should be plenty for SIP! */
1198                 if((p[pos] & 0xff)!=0 || (p[pos + 1] & 0xff)!=0
1199                                 || (p[pos + 2] & 0xff)!=0 || (p[pos + 3] & 0xff)!=0) {
1200                         LM_WARN("advertised length is too large (more than 2^32)\n");
1201                         goto skip;
1202                 }
1203                 len = ((p[pos + 4] & 0xff) << 24)
1204                         | ((p[pos + 5] & 0xff) << 16)
1205                         | ((p[pos + 6] & 0xff) <<  8)
1206                         | ((p[pos + 7] & 0xff) <<  0);
1207                 pos += 8;
1208         }
1209
1210         /* Skip mask */
1211         if (mask_present) {
1212                 if (size < pos + 4)
1213                         goto skip;
1214                 pos += 4;
1215         }
1216
1217         /* check if advertised length fits in read buffer */
1218         if(len>=r->b_size) {
1219                 LM_WARN("advertised length (%u) greater than buffer size (%u)\n",
1220                                 len, r->b_size);
1221                 goto skip;
1222         }
1223         /* Now check the whole message has been received */
1224         if (size < pos + len)
1225                 goto skip;
1226
1227         pos += len;
1228         r->flags |= F_TCP_REQ_COMPLETE;
1229         r->parsed = &p[pos];
1230
1231 skip:
1232         return bytes;
1233 }
1234
1235 static int ws_process_msg(char* tcpbuf, unsigned int len,
1236                 struct receive_info* rcv_info, struct tcp_connection* con)
1237 {
1238         int ret;
1239         tcp_event_info_t tev;
1240         sr_event_param_t evp = {0};
1241
1242         ret = 0;
1243         LM_DBG("WebSocket Message: [[>>>\n%.*s<<<]]\n", len, tcpbuf);
1244         if(likely(sr_event_enabled(SREV_TCP_WS_FRAME_IN))) {
1245                 memset(&tev, 0, sizeof(tcp_event_info_t));
1246                 tev.type = SREV_TCP_WS_FRAME_IN;
1247                 tev.buf = tcpbuf;
1248                 tev.len = len;
1249                 tev.rcv = rcv_info;
1250                 tev.con = con;
1251                 evp.data = (void*)(&tev);
1252                 ret = sr_event_exec(SREV_TCP_WS_FRAME_IN, &evp);
1253         } else {
1254                 LM_DBG("no callback registering for handling WebSockets - dropping!\n");
1255         }
1256         return ret;
1257 }
1258 #endif
1259
1260 static int tcp_read_hep3(struct tcp_connection *c, int* read_flags)
1261 {
1262         int bytes;
1263         uint32_t size, len;
1264         char *p;
1265         struct tcp_req *r;
1266
1267         r=&c->req;
1268 #ifdef USE_TLS
1269         if (unlikely(c->type == PROTO_TLS)) {
1270                 bytes = tls_read(c, read_flags);
1271         } else {
1272 #endif
1273                 bytes = tcp_read(c, read_flags);
1274 #ifdef USE_TLS
1275         }
1276 #endif
1277
1278         if (bytes <= 0) {
1279                 if (likely(r->parsed >= r->pos)) {
1280                         LM_DBG("no new bytes to read, but still unparsed content\n");
1281                         return 0;
1282                 }
1283         }
1284
1285         size = r->pos - r->parsed;
1286
1287         p = r->parsed;
1288
1289         /* Process first six bytes (HEP3 + 2 bytes the size)*/
1290         if (size < 6) {
1291                 LM_DBG("not enough bytes to parse (%u)\n", size);
1292                 goto skip;
1293         }
1294
1295         if(p[0]!='H' || p[1]!='E' || p[2]!='P' || p[3]!='3') {
1296                 /* not hep3 */
1297                 LM_DBG("not HEP3 packet header (%u): %c %c %c %c / %x %x %x %x\n",
1298                                 size, p[0], p[1], p[2], p[3], p[0], p[1], p[2], p[3]);
1299                 goto skip;
1300         }
1301         r->flags |= F_TCP_REQ_HEP3;
1302
1303         len = ((uint32_t)(p[4] & 0xff) <<  8) + (p[5] & 0xff);
1304
1305         /* check if advertised length fits in read buffer */
1306         if(len>=r->b_size) {
1307                 LM_WARN("advertised length (%u) greater than buffer size (%u)\n",
1308                                 len, r->b_size);
1309                 goto skip;
1310         }
1311         /* check the whole message has been received */
1312         if (size < len) {
1313                 LM_DBG("incomplete HEP3 packet (%u / %u)\n", len, size);
1314                 goto skip;
1315         }
1316
1317         r->flags |= F_TCP_REQ_COMPLETE;
1318         r->parsed = p + len;
1319         LM_DBG("reading of HEP3 packet is complete (%u / %u)\n", len, size);
1320
1321 skip:
1322         return bytes;
1323 }
1324
1325 static int hep3_process_msg(char* tcpbuf, unsigned int len,
1326                 struct receive_info* rcv_info, struct tcp_connection* con)
1327 {
1328         sip_msg_t msg;
1329         int ret;
1330         sr_event_param_t evp = {0};
1331
1332         memset(&msg, 0, sizeof(sip_msg_t)); /* init everything to 0 */
1333         /* fill in msg */
1334         msg.buf=tcpbuf;
1335         msg.len=len;
1336         /* zero termination (termination of orig message below not that
1337          * useful as most of the work is done with scratch-pad; -jiri  */
1338         /* buf[len]=0; */ /* WARNING: zero term removed! */
1339         msg.rcv=*rcv_info;
1340         msg.id=msg_no;
1341         msg.pid=my_pid();
1342         msg.set_global_address=default_global_address;
1343         msg.set_global_port=default_global_port;
1344
1345         if(likely(sr_msg_time==1)) msg_set_time(&msg);
1346         evp.data = (void*)(&msg);
1347         ret=sr_event_exec(SREV_RCV_NOSIP, &evp);
1348         LM_DBG("running hep3 handling event returned %d\n", ret);
1349         if(ret == NONSIP_MSG_DROP) {
1350                 free_sip_msg(&msg);
1351                 return 0;
1352         }
1353         if(ret < 0) {
1354                 LM_ERR("error running hep3 handling event: %d\n", ret);
1355                 free_sip_msg(&msg);
1356                 return -1;
1357         }
1358
1359         ret = receive_msg(msg.buf, msg.len, &msg.rcv);
1360         LM_DBG("running hep3-enclosed sip request route returned %d\n", ret);
1361         free_sip_msg(&msg);
1362
1363         return ret;
1364 }
1365
1366 /**
1367  * @brief wrapper around receive_msg() to clone the tcpbuf content
1368  *
1369  * When receiving over TCP, tcpbuf points inside the TCP stream buffer, but during
1370  * processing of config, msg->buf content might be changed and may corrupt
1371  * the content of the stream. Safer, make a clone of buf content in a local
1372  * buffer and give that to receive_msg() to link to msg->buf
1373  */
1374 int receive_tcp_msg(char* tcpbuf, unsigned int len,
1375                 struct receive_info* rcv_info, struct tcp_connection* con)
1376 {
1377 #ifdef TCP_CLONE_RCVBUF
1378         static char *buf = NULL;
1379         static unsigned int bsize = 0;
1380         int blen;
1381
1382         /* cloning is disabled via parameter */
1383         if(likely(tcp_clone_rcvbuf==0)) {
1384 #ifdef READ_MSRP
1385                 if(unlikely(con->req.flags&F_TCP_REQ_MSRP_FRAME))
1386                         return msrp_process_msg(tcpbuf, len, rcv_info, con);
1387 #endif
1388 #ifdef READ_WS
1389                 if(unlikely(con->type == PROTO_WS || con->type == PROTO_WSS))
1390                         return ws_process_msg(tcpbuf, len, rcv_info, con);
1391 #endif
1392                 if(unlikely(con->req.flags&F_TCP_REQ_HEP3))
1393                         return hep3_process_msg(tcpbuf, len, rcv_info, con);
1394
1395                 return receive_msg(tcpbuf, len, rcv_info);
1396         }
1397
1398         /* min buffer size is BUF_SIZE */
1399         blen = len;
1400         if(blen < BUF_SIZE)
1401                 blen = BUF_SIZE;
1402
1403         /* allocate buffer when needed
1404          * - no buffer yet
1405          * - existing buffer too small (min size is BUF_SIZE - to accomodate most
1406          *   of SIP messages; expected larger for HTTP/XCAP)
1407          * - existing buffer too large (e.g., we got a too big message in the past,
1408          *   let's free it)
1409          *
1410          * - also, use system memory, not to eat from PKG (same as static buffer
1411          *   from PKG pov)
1412          */
1413         if(buf==NULL || bsize < blen || blen < bsize/2) {
1414                 if(buf!=NULL)
1415                         free(buf);
1416                 buf=malloc(blen+1);
1417                 if (buf==0) {
1418                         SYS_MEM_ERROR;
1419                         return -1;
1420                 }
1421                 bsize = blen;
1422         }
1423
1424         memcpy(buf, tcpbuf, len);
1425         buf[len] = '\0';
1426 #ifdef READ_MSRP
1427         if(unlikely(con->req.flags&F_TCP_REQ_MSRP_FRAME))
1428                 return msrp_process_msg(buf, len, rcv_info, con);
1429 #endif
1430 #ifdef READ_WS
1431         if(unlikely(con->type == PROTO_WS || con->type == PROTO_WSS))
1432                 return ws_process_msg(buf, len, rcv_info, con);
1433 #endif
1434         if(unlikely(con->req.flags&F_TCP_REQ_HEP3))
1435                 return hep3_process_msg(tcpbuf, len, rcv_info, con);
1436         return receive_msg(buf, len, rcv_info);
1437 #else /* TCP_CLONE_RCVBUF */
1438 #ifdef READ_MSRP
1439         if(unlikely(con->req.flags&F_TCP_REQ_MSRP_FRAME))
1440                 return msrp_process_msg(tcpbuf, len, rcv_info, con);
1441 #endif
1442 #ifdef READ_WS
1443         if(unlikely(con->type == PROTO_WS || con->type == PROTO_WSS))
1444                 return ws_process_msg(tcpbuf, len, rcv_info, con);
1445 #endif
1446         if(unlikely(con->req.flags&F_TCP_REQ_HEP3))
1447                 return hep3_process_msg(tcpbuf, len, rcv_info, con);
1448         return receive_msg(tcpbuf, len, rcv_info);
1449 #endif /* TCP_CLONE_RCVBUF */
1450 }
1451
1452 int tcp_read_req(struct tcp_connection* con, int* bytes_read, int* read_flags)
1453 {
1454         int bytes;
1455         int total_bytes;
1456         int resp;
1457         long size;
1458         struct tcp_req* req;
1459         struct dest_info dst;
1460         char c;
1461         int ret;
1462
1463         bytes=-1;
1464         total_bytes=0;
1465         resp=CONN_RELEASE;
1466         req=&con->req;
1467
1468 again:
1469                 if (likely(req->error==TCP_REQ_OK)){
1470 #ifdef READ_WS
1471                         if (unlikely(con->type == PROTO_WS || con->type == PROTO_WSS)) {
1472                                 bytes=tcp_read_ws(con, read_flags);
1473                         } else {
1474 #endif
1475                                 if(unlikely(ksr_tcp_accept_hep3!=0)) {
1476                                         bytes=tcp_read_hep3(con, read_flags);
1477                                         if (bytes>=0) {
1478                                                 if(!(con->req.flags & F_TCP_REQ_HEP3)) {
1479                                                         /* not hep3, try to read headers */
1480                                                         bytes=tcp_read_headers(con, read_flags);
1481                                                 }
1482                                         }
1483                                 } else {
1484                                         bytes=tcp_read_headers(con, read_flags);
1485                                 }
1486 #ifdef READ_WS
1487                         }
1488 #endif
1489
1490                         if (unlikely(bytes<0)){
1491                                 LOG(cfg_get(core, core_cfg, corelog),
1492                                                 "ERROR: tcp_read_req: error reading - c: %p r: %p (%d)\n",
1493                                                 con, req, bytes);
1494                                 resp=CONN_ERROR;
1495                                 goto end_req;
1496                         }
1497
1498 #ifdef EXTRA_DEBUG
1499                                                 /* if timeout state=0; goto end__req; */
1500                         LM_DBG("read= %d bytes, parsed=%d, state=%d, error=%d\n",
1501                                         bytes, (int)(req->parsed-req->start), req->state,
1502                                         req->error );
1503                         LM_DBG("last char=0x%02X, parsed msg=\n%.*s\n",
1504                                         *(req->parsed-1), (int)(req->parsed-req->start),
1505                                         req->start);
1506 #endif
1507                         total_bytes+=bytes;
1508                         /* eof check:
1509                          * is EOF if eof on fd and req.  not complete yet,
1510                          * if req. is complete we might have a second unparsed
1511                          * request after it, so postpone release_with_eof
1512                          */
1513                         if (unlikely((con->state==S_CONN_EOF) &&
1514                                                 (! TCP_REQ_COMPLETE(req)))) {
1515                                 LM_DBG("EOF\n");
1516                                 resp=CONN_EOF;
1517                                 goto end_req;
1518                         }
1519                 }
1520                 if (unlikely(req->error!=TCP_REQ_OK)){
1521                         if(req->buf!=NULL && req->start!=NULL && req->pos!=NULL
1522                                         && req->pos>=req->buf && req->parsed>=req->start) {
1523                                 LM_ERR("bad request, state=%d, error=%d buf:\n%.*s\nparsed:\n%.*s\n",
1524                                         req->state, req->error,
1525                                         (int)(req->pos-req->buf), req->buf,
1526                                         (int)(req->parsed-req->start), req->start);
1527                         } else {
1528                                 LM_ERR("bad request, state=%d, error=%d buf:%d - %p,"
1529                                                 " parsed:%d - %p\n",
1530                                         req->state, req->error,
1531                                         (int)(req->pos-req->buf), req->buf,
1532                                         (int)(req->parsed-req->start), req->start);
1533                         }
1534                         LM_DBG("received from: port %d\n", con->rcv.src_port);
1535                         print_ip("received from: ip", &con->rcv.src_ip, "\n");
1536                         resp=CONN_ERROR;
1537                         goto end_req;
1538                 }
1539                 if (likely(TCP_REQ_COMPLETE(req))){
1540 #ifdef EXTRA_DEBUG
1541                         LM_DBG("end of header part\n");
1542                         LM_DBG("received from: port %d\n", con->rcv.src_port);
1543                         print_ip("received from: ip", &con->rcv.src_ip, "\n");
1544                         LM_DBG("headers:\n%.*s.\n",
1545                                         (int)(req->body-req->start), req->start);
1546 #endif
1547                         if (likely(TCP_REQ_HAS_CLEN(req))){
1548                                 LM_DBG("content-length=%d\n", req->content_len);
1549 #ifdef EXTRA_DEBUG
1550                                 LM_DBG("body:\n%.*s\n", req->content_len,req->body);
1551 #endif
1552                         }else{
1553                                 if (cfg_get(tcp, tcp_cfg, accept_no_cl)==0) {
1554                                         req->error=TCP_REQ_BAD_LEN;
1555                                         LM_ERR("content length not present or unparsable\n");
1556                                         resp=CONN_ERROR;
1557                                         goto end_req;
1558                                 }
1559                         }
1560                         /* if we are here everything is nice and ok*/
1561                         resp=CONN_RELEASE;
1562 #ifdef EXTRA_DEBUG
1563                         LM_DBG("receiving msg(%p, %d)\n",
1564                                         req->start, (int)(req->parsed-req->start));
1565 #endif
1566                         /* rcv.bind_address should always be !=0 */
1567                         bind_address=con->rcv.bind_address;
1568                         /* just for debugging use sendipv4 as receiving socket  FIXME*/
1569                         /*
1570                         if (con->rcv.dst_ip.af==AF_INET6){
1571                                 bind_address=sendipv6_tcp;
1572                         }else{
1573                                 bind_address=sendipv4_tcp;
1574                         }
1575                         */
1576                         con->rcv.proto_reserved1=con->id; /* copy the id */
1577                         c=*req->parsed; /* ugly hack: zero term the msg & save the
1578                                                            previous char, req->parsed should be ok
1579                                                            because we always alloc BUF_SIZE+1 */
1580                         *req->parsed=0;
1581
1582                         if (req->state==H_PING_CRLF) {
1583                                 init_dst_from_rcv(&dst, &con->rcv);
1584
1585                                 if (tcp_send(&dst, 0, CRLF, CRLF_LEN) < 0) {
1586                                         LM_ERR("CRLF ping: tcp_send() failed ([%s]:%u -> [%s]:%u)\n",
1587                                                         ip_addr2a(&con->rcv.src_ip), con->rcv.src_port,
1588                                                         ip_addr2a(&con->rcv.dst_ip), con->rcv.dst_port);
1589                                 }
1590                                 ret = 0;
1591                         } else if (unlikely(req->state==H_STUN_END)) {
1592                                 /* stun request */
1593                                 ret = stun_process_msg(req->start, req->parsed-req->start,
1594                                                                          &con->rcv);
1595                         } else
1596 #ifdef READ_MSRP
1597                         // if (unlikely(req->flags&F_TCP_REQ_MSRP_FRAME)){
1598                         if (unlikely(req->state==H_MSRP_FINISH)){
1599                                 /* msrp frame */
1600                                 ret = receive_tcp_msg(req->start, req->parsed-req->start,
1601                                                                         &con->rcv, con);
1602                         }else
1603 #endif
1604 #ifdef READ_HTTP11
1605                         if (unlikely(req->state==H_HTTP11_CHUNK_FINISH)){
1606                                 /* http chunked request */
1607                                 req->body[req->content_len] = 0;
1608                                 ret = receive_tcp_msg(req->start,
1609                                                 req->body + req->content_len - req->start,
1610                                                 &con->rcv, con);
1611                         }else
1612 #endif
1613 #ifdef READ_WS
1614                         if (unlikely(con->type == PROTO_WS || con->type == PROTO_WSS)){
1615                                 ret = receive_tcp_msg(req->start, req->parsed-req->start,
1616                                                                         &con->rcv, con);
1617                         }else
1618 #endif
1619                                 ret = receive_tcp_msg(req->start, req->parsed-req->start,
1620                                                                         &con->rcv, con);
1621
1622                         if (unlikely(ret < 0)) {
1623                                 *req->parsed=c;
1624                                 resp=CONN_ERROR;
1625                                 goto end_req;
1626                         }
1627                         *req->parsed=c;
1628
1629                         /* prepare for next request */
1630                         size=req->pos-req->parsed;
1631                         req->start=req->buf;
1632                         req->body=0;
1633                         req->error=TCP_REQ_OK;
1634                         req->state=H_SKIP_EMPTY;
1635                         req->flags=0;
1636                         req->content_len=0;
1637                         req->bytes_to_go=0;
1638                         req->pos=req->buf+size;
1639
1640                         if (unlikely(size)){
1641                                 memmove(req->buf, req->parsed, size);
1642                                 req->parsed=req->buf; /* fix req->parsed after using it */
1643 #ifdef EXTRA_DEBUG
1644                                 LM_DBG("preparing for new request, kept %ld bytes\n", size);
1645 #endif
1646                                 /*if we still have some unparsed bytes, try to parse them too*/
1647                                 goto again;
1648                         } else if (unlikely(con->state==S_CONN_EOF)){
1649                                 LM_DBG("EOF after reading complete request ([%s]:%u -> [%s]:%u)\n",
1650                                                 ip_addr2a(&con->rcv.src_ip), con->rcv.src_port,
1651                                                 ip_addr2a(&con->rcv.dst_ip), con->rcv.dst_port);
1652                                 resp=CONN_EOF;
1653                         }
1654                         req->parsed=req->buf; /* fix req->parsed */
1655                 }
1656
1657         end_req:
1658                 if (likely(bytes_read)) *bytes_read=total_bytes;
1659                 return resp;
1660 }
1661
1662
1663
1664 void release_tcpconn(struct tcp_connection* c, long state, int unix_sock)
1665 {
1666         long response[2];
1667         
1668                 LM_DBG("releasing con %p, state %ld, fd=%d, id=%d ([%s]:%u -> [%s]:%u)\n",
1669                                 c, state, c->fd, c->id,
1670                                 ip_addr2a(&c->rcv.src_ip), c->rcv.src_port,
1671                                 ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port);
1672                 LM_DBG("extra_data %p\n", c->extra_data);
1673                 /* release req & signal the parent */
1674                 c->reader_pid=0; /* reset it */
1675                 if (c->fd!=-1){
1676                         close(c->fd);
1677                         c->fd=-1;
1678                 }
1679                 /* errno==EINTR, EWOULDBLOCK a.s.o todo */
1680                 response[0]=(long)c;
1681                 response[1]=state;
1682                 
1683                 if (tsend_stream(unix_sock, (char*)response, sizeof(response), -1)<=0)
1684                         LM_ERR("tsend_stream failed\n");
1685 }
1686
1687
1688
1689 static ticks_t tcpconn_read_timeout(ticks_t t, struct timer_ln* tl, void* data)
1690 {
1691         struct tcp_connection *c;
1692         
1693         c=(struct tcp_connection*)data; 
1694         /* or (struct tcp...*)(tl-offset(c->timer)) */
1695         
1696         if (likely(!(c->state<0) && TICKS_LT(t, c->timeout))){
1697                 /* timeout extended, exit */
1698                 return (ticks_t)(c->timeout - t);
1699         }
1700         /* if conn->state is ERROR or BAD => force timeout too */
1701         if (unlikely(io_watch_del(&io_w, c->fd, -1, IO_FD_CLOSING)<0)){
1702                 LM_ERR("io_watch_del failed for %p"
1703                                         " id %d fd %d, state %d, flags %x, main fd %d"
1704                                         " ([%s]:%u -> [%s]:%u)\n",
1705                                         c, c->id, c->fd, c->state, c->flags, c->s,
1706                                         ip_addr2a(&c->rcv.src_ip), c->rcv.src_port,
1707                                         ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port);
1708         }
1709         tcpconn_listrm(tcp_conn_lst, c, c_next, c_prev);
1710         release_tcpconn(c, (c->state<0)?CONN_ERROR:CONN_RELEASE, tcpmain_sock);
1711         
1712         return 0;
1713 }
1714
1715
1716
1717 /* handle io routine, based on the fd_map type
1718  * (it will be called from io_wait_loop* )
1719  * params:  fm  - pointer to a fd hash entry
1720  *          idx - index in the fd_array (or -1 if not known)
1721  * return: -1 on error, or when we are not interested any more on reads
1722  *            from this fd (e.g.: we are closing it )
1723  *          0 on EAGAIN or when by some other way it is known that no more 
1724  *            io events are queued on the fd (the receive buffer is empty).
1725  *            Usefull to detect when there are no more io events queued for
1726  *            sigio_rt, epoll_et, kqueue.
1727  *         >0 on successfull read from the fd (when there might be more io
1728  *            queued -- the receive buffer might still be non-empty)
1729  */
1730 inline static int handle_io(struct fd_map* fm, short events, int idx)
1731 {       
1732         int ret;
1733         int n;
1734         int read_flags;
1735         struct tcp_connection* con;
1736         int s;
1737         long resp;
1738         ticks_t t;
1739         
1740         /* update the local config */
1741         cfg_update();
1742         
1743         switch(fm->type){
1744                 case F_TCPMAIN:
1745 again:
1746                         ret=n=receive_fd(fm->fd, &con, sizeof(con), &s, 0);
1747                         LM_DBG("received n=%d con=%p, fd=%d\n", n, con, s);
1748                         if (unlikely(n<0)){
1749                                 if (errno == EWOULDBLOCK || errno == EAGAIN){
1750                                         ret=0;
1751                                         break;
1752                                 }else if (errno == EINTR) goto again;
1753                                 else{
1754                                         LM_CRIT("read_fd: %s \n", strerror(errno));
1755                                                 abort(); /* big error*/
1756                                 }
1757                         }
1758                         if (unlikely(n==0)){
1759                                 LM_ERR("0 bytes read\n");
1760                                 goto error;
1761                         }
1762                         if (unlikely(con==0)){
1763                                         LM_CRIT("null pointer\n");
1764                                         goto error;
1765                         }
1766                         con->fd=s;
1767                         if (unlikely(s==-1)) {
1768                                 LM_ERR("read_fd: no fd read\n");
1769                                 goto con_error;
1770                         }
1771                         con->reader_pid=my_pid();
1772                         if (unlikely(con==tcp_conn_lst)){
1773                                 LM_CRIT("duplicate connection received: %p, id %d, fd %d, refcnt %d"
1774                                                         " state %d (n=%d)\n", con, con->id, con->fd,
1775                                                         atomic_get(&con->refcnt), con->state, n);
1776                                 goto con_error;
1777                                 break; /* try to recover */
1778                         }
1779                         if (unlikely(con->state==S_CONN_BAD)){
1780                                 LM_WARN("received an already bad connection: %p id %d refcnt %d\n",
1781                                                         con, con->id, atomic_get(&con->refcnt));
1782                                 goto con_error;
1783                         }
1784                         /* if we received the fd there is most likely data waiting to
1785                          * be read => process it first to avoid extra sys calls */
1786                         read_flags=((con->flags & (F_CONN_EOF_SEEN|F_CONN_FORCE_EOF)) &&
1787                                                 !(con->flags & F_CONN_OOB_DATA))? RD_CONN_FORCE_EOF
1788                                                 :0;
1789 #ifdef USE_TLS
1790 repeat_1st_read:
1791 #endif /* USE_TLS */
1792                         resp=tcp_read_req(con, &n, &read_flags);
1793                         if (unlikely(resp<0)){
1794                                 /* some error occurred, but on the new fd, not on the tcp
1795                                  * main fd, so keep the ret value */
1796                                 if (unlikely(resp!=CONN_EOF))
1797                                         con->state=S_CONN_BAD;
1798                                 release_tcpconn(con, resp, tcpmain_sock);
1799                                 break;
1800                         }
1801 #ifdef USE_TLS
1802                         /* repeat read if requested (for now only tls might do this) */
1803                         if (unlikely(read_flags & RD_CONN_REPEAT_READ))
1804                                 goto repeat_1st_read;
1805 #endif /* USE_TLS */
1806                         
1807                         /* must be before io_watch_add, io_watch_add might catch some
1808                          * already existing events => might call handle_io and
1809                          * handle_io might decide to del. the new connection =>
1810                          * must be in the list */
1811                         tcpconn_listadd(tcp_conn_lst, con, c_next, c_prev);
1812                         t=get_ticks_raw();
1813                         con->timeout=t+S_TO_TICKS(TCP_CHILD_TIMEOUT);
1814                         /* re-activate the timer */
1815                         con->timer.f=tcpconn_read_timeout;
1816                         local_timer_reinit(&con->timer);
1817                         local_timer_add(&tcp_reader_ltimer, &con->timer,
1818                                                                 S_TO_TICKS(TCP_CHILD_TIMEOUT), t);
1819                         if (unlikely(io_watch_add(&io_w, s, POLLIN, F_TCPCONN, con)<0)){
1820                                 LM_CRIT("io_watch_add failed for %p id %d fd %d, state %d, flags %x,"
1821                                                         " main fd %d, refcnt %d ([%s]:%u -> [%s]:%u)\n",
1822                                                         con, con->id, con->fd, con->state, con->flags,
1823                                                         con->s, atomic_get(&con->refcnt),
1824                                                         ip_addr2a(&con->rcv.src_ip), con->rcv.src_port,
1825                                                         ip_addr2a(&con->rcv.dst_ip), con->rcv.dst_port);
1826                                 tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
1827                                 local_timer_del(&tcp_reader_ltimer, &con->timer);
1828                                 goto con_error;
1829                         }
1830                         break;
1831                 case F_TCPCONN:
1832                         con=(struct tcp_connection*)fm->data;
1833                         if (unlikely(con->state==S_CONN_BAD)){
1834                                 resp=CONN_ERROR;
1835                                 if (!(con->send_flags.f & SND_F_CON_CLOSE))
1836                                         LM_WARN("F_TCPCONN connection marked as bad: %p id %d refcnt %d\n",
1837                                                         con, con->id, atomic_get(&con->refcnt));
1838                                 goto read_error;
1839                         }
1840                         read_flags=((
1841 #ifdef POLLRDHUP
1842                                                 (events & POLLRDHUP) |
1843 #endif /* POLLRDHUP */
1844                                                 (events & (POLLHUP|POLLERR)) |
1845                                                         (con->flags & (F_CONN_EOF_SEEN|F_CONN_FORCE_EOF)))
1846                                                 && !(events & POLLPRI))? RD_CONN_FORCE_EOF: 0;
1847 #ifdef USE_TLS
1848 repeat_read:
1849 #endif /* USE_TLS */
1850                         resp=tcp_read_req(con, &ret, &read_flags);
1851                         if (unlikely(resp<0)){
1852 read_error:
1853                                 ret=-1; /* some error occurred */
1854                                 if (unlikely(io_watch_del(&io_w, con->fd, idx,
1855                                                                                         IO_FD_CLOSING) < 0)){
1856                                         LM_CRIT("io_watch_del failed for %p id %d fd %d,"
1857                                                         " state %d, flags %x, main fd %d, refcnt %d"
1858                                                         " ([%s]:%u -> [%s]:%u)\n",
1859                                                         con, con->id, con->fd, con->state,
1860                                                         con->flags, con->s, atomic_get(&con->refcnt),
1861                                                         ip_addr2a(&con->rcv.src_ip), con->rcv.src_port,
1862                                                         ip_addr2a(&con->rcv.dst_ip), con->rcv.dst_port);
1863                                 }
1864                                 tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
1865                                 local_timer_del(&tcp_reader_ltimer, &con->timer);
1866                                 if (unlikely(resp!=CONN_EOF))
1867                                         con->state=S_CONN_BAD;
1868                                 release_tcpconn(con, resp, tcpmain_sock);
1869                         }else{
1870 #ifdef USE_TLS
1871                                 if (unlikely(read_flags & RD_CONN_REPEAT_READ))
1872                                                 goto repeat_read;
1873 #endif /* USE_TLS */
1874                                 /* update timeout */
1875                                 con->timeout=get_ticks_raw()+S_TO_TICKS(TCP_CHILD_TIMEOUT);
1876                                 /* ret= 0 (read the whole socket buffer) if short read & 
1877                                  *  !POLLPRI,  bytes read otherwise */
1878                                 ret&=(((read_flags & RD_CONN_SHORT_READ) &&
1879                                                 !(events & POLLPRI)) - 1);
1880                         }
1881                         break;
1882                 case F_NONE:
1883                         LM_CRIT("empty fd map %p (%d): {%d, %d, %p}\n",
1884                                                 fm, (int)(fm-io_w.fd_hash),
1885                                                 fm->fd, fm->type, fm->data);
1886                         goto error;
1887                 default:
1888                         LM_CRIT("unknown fd type %d\n", fm->type);
1889                         goto error;
1890         }
1891         
1892         return ret;
1893 con_error:
1894         con->state=S_CONN_BAD;
1895         release_tcpconn(con, CONN_ERROR, tcpmain_sock);
1896         return ret;
1897 error:
1898         return -1;
1899 }
1900
1901
1902
1903 inline static void tcp_reader_timer_run(void)
1904 {
1905         ticks_t ticks;
1906         
1907         ticks=get_ticks_raw();
1908         if (unlikely((ticks-tcp_reader_prev_ticks)<TCPCONN_TIMEOUT_MIN_RUN))
1909                 return;
1910         tcp_reader_prev_ticks=ticks;
1911         local_timer_run(&tcp_reader_ltimer, ticks);
1912 }
1913
1914
1915
1916 void tcp_receive_loop(int unix_sock)
1917 {
1918         
1919         /* init */
1920         tcpmain_sock=unix_sock; /* init com. socket */
1921         if (init_io_wait(&io_w, get_max_open_fds(), tcp_poll_method)<0)
1922                 goto error;
1923         tcp_reader_prev_ticks=get_ticks_raw();
1924         if (init_local_timer(&tcp_reader_ltimer, get_ticks_raw())!=0)
1925                 goto error;
1926         /* add the unix socket */
1927         if (io_watch_add(&io_w, tcpmain_sock, POLLIN,  F_TCPMAIN, 0)<0){
1928                 LM_CRIT("failed to add tcp main socket to the fd list\n");
1929                 goto error;
1930         }
1931
1932         /* initialize the config framework */
1933         if (cfg_child_init()) goto error;
1934
1935         /* main loop */
1936         switch(io_w.poll_method){
1937                 case POLL_POLL:
1938                                 while(1){
1939                                         io_wait_loop_poll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1940                                         tcp_reader_timer_run();
1941                                 }
1942                                 break;
1943 #ifdef HAVE_SELECT
1944                 case POLL_SELECT:
1945                         while(1){
1946                                 io_wait_loop_select(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1947                                 tcp_reader_timer_run();
1948                         }
1949                         break;
1950 #endif
1951 #ifdef HAVE_SIGIO_RT
1952                 case POLL_SIGIO_RT:
1953                         while(1){
1954                                 io_wait_loop_sigio_rt(&io_w, TCP_CHILD_SELECT_TIMEOUT);
1955                                 tcp_reader_timer_run();
1956                         }
1957                         break;
1958 #endif
1959 #ifdef HAVE_EPOLL
1960                 case POLL_EPOLL_LT:
1961                         while(1){
1962                                 io_wait_loop_epoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1963                                 tcp_reader_timer_run();
1964                         }
1965                         break;
1966                 case POLL_EPOLL_ET:
1967                         while(1){
1968                                 io_wait_loop_epoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 1);
1969                                 tcp_reader_timer_run();
1970                         }
1971                         break;
1972 #endif
1973 #ifdef HAVE_KQUEUE
1974                 case POLL_KQUEUE:
1975                         while(1){
1976                                 io_wait_loop_kqueue(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1977                                 tcp_reader_timer_run();
1978                         }
1979                         break;
1980 #endif
1981 #ifdef HAVE_DEVPOLL
1982                 case POLL_DEVPOLL:
1983                         while(1){
1984                                 io_wait_loop_devpoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
1985                                 tcp_reader_timer_run();
1986                         }
1987                         break;
1988 #endif
1989                 default:
1990                         LM_CRIT("no support for poll method %s (%d)\n", 
1991                                         poll_method_name(io_w.poll_method), io_w.poll_method);
1992                         goto error;
1993         }
1994 error:
1995         destroy_io_wait(&io_w);
1996         LM_CRIT("exiting...");
1997         exit(-1);
1998 }
1999
2000
2001 int is_msg_complete(struct tcp_req* r)
2002 {
2003         if (TCP_REQ_HAS_CLEN(r)) {
2004                 r->state = H_STUN_FP;
2005                 return 0;
2006         }
2007         else {
2008                 /* STUN message is complete */
2009                 r->state = H_STUN_END;
2010                 r->flags |= F_TCP_REQ_COMPLETE |
2011                                         F_TCP_REQ_HAS_CLEN; /* hack to avoid error check */
2012                 return 1;
2013         }
2014 }
2015
2016 #endif /* USE_TCP */