00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00055 #ifdef USE_TCP
00056
00057 #include <stdio.h>
00058 #include <errno.h>
00059 #include <string.h>
00060
00061
00062 #include <sys/time.h>
00063 #include <sys/types.h>
00064 #include <sys/select.h>
00065 #include <sys/socket.h>
00066
00067 #include <unistd.h>
00068 #include <stdlib.h>
00069
00070
00071 #include "dprint.h"
00072 #include "tcp_conn.h"
00073 #include "tcp_read.h"
00074 #include "tcp_stats.h"
00075 #include "tcp_ev.h"
00076 #include "pass_fd.h"
00077 #include "globals.h"
00078 #include "receive.h"
00079 #include "timer.h"
00080 #include "local_timer.h"
00081 #include "ut.h"
00082 #include "trim.h"
00083 #include "pt.h"
00084 #include "cfg/cfg_struct.h"
00085 #ifdef CORE_TLS
00086 #include "tls/tls_server.h"
00087 #else
00088 #include "tls_hooks.h"
00089 #endif
00090 #ifdef USE_DST_BLACKLIST
00091 #include "dst_blacklist.h"
00092 #endif
00093
00094 #define HANDLE_IO_INLINE
00095 #include "io_wait.h"
00096 #include <fcntl.h>
00097 #include "tsend.h"
00098 #include "forward.h"
00099 #include "events.h"
00100
00101 #ifdef USE_STUN
00102 #include "ser_stun.h"
00103
00104 int is_msg_complete(struct tcp_req* r);
00105
00106 #endif
00107
00108 #ifdef READ_HTTP11
00109 #define HTTP11CONTINUE "HTTP/1.1 100 Continue\r\nContent-Lenght: 0\r\n\r\n"
00110 #define HTTP11CONTINUE_LEN (sizeof(HTTP11CONTINUE)-1)
00111 #endif
00112
00113 #define TCPCONN_TIMEOUT_MIN_RUN 1
00114
00115
00116 enum fd_types { F_NONE, F_TCPMAIN, F_TCPCONN };
00117
00118
00119 static struct tcp_connection* tcp_conn_lst=0;
00120 static io_wait_h io_w;
00121 static int tcpmain_sock=-1;
00122
00123 static struct local_timer tcp_reader_ltimer;
00124 static ticks_t tcp_reader_prev_ticks;
00125
00131 #define TCP_CLONE_RCVBUF
00132 static int tcp_clone_rcvbuf = 0;
00133
00134 int tcp_set_clone_rcvbuf(int v)
00135 {
00136 int r;
00137 r = tcp_clone_rcvbuf;
00138 tcp_clone_rcvbuf = v;
00139 return r;
00140 }
00141
00142 #ifdef READ_HTTP11
00143 static inline char *strfindcasestrz(str *haystack, char *needlez)
00144 {
00145 int i,j;
00146 str needle;
00147
00148 needle.s = needlez;
00149 needle.len = strlen(needlez);
00150 for(i=0;i<haystack->len-needle.len;i++) {
00151 for(j=0;j<needle.len;j++) {
00152 if ( !((haystack->s[i+j]==needle.s[j]) ||
00153 ( isalpha((int)haystack->s[i+j])
00154 && ((haystack->s[i+j])^(needle.s[j]))==0x20 )) )
00155 break;
00156 }
00157 if (j==needle.len)
00158 return haystack->s+i;
00159 }
00160 return 0;
00161 }
00162
00163 int tcp_http11_continue(struct tcp_connection *c)
00164 {
00165 struct dest_info dst;
00166 char *p;
00167 struct msg_start fline;
00168 int ret;
00169 str msg;
00170
00171 ret = 0;
00172
00173 msg.s = c->req.start;
00174 msg.len = c->req.pos - c->req.start;
00175 #ifdef READ_MSRP
00176
00177 if(c->req.flags&F_TCP_REQ_MSRP_FRAME)
00178 return 0;
00179 #endif
00180 p = parse_first_line(msg.s, msg.len, &fline);
00181 if(p==NULL)
00182 return 0;
00183
00184 if(fline.type!=SIP_REQUEST)
00185 return 0;
00186
00187
00188 if(fline.u.request.version.len < HTTP_VERSION_LEN
00189 || strncasecmp(fline.u.request.version.s,
00190 HTTP_VERSION, HTTP_VERSION_LEN))
00191 return 0;
00192
00193
00194 if(strfindcasestrz(&msg, "Expect: 100-continue")!=NULL)
00195 {
00196 init_dst_from_rcv(&dst, &c->rcv);
00197 if (tcp_send(&dst, 0, HTTP11CONTINUE, HTTP11CONTINUE_LEN) < 0) {
00198 LOG(L_ERR, "HTTP/1.1 continue failed\n");
00199 }
00200 }
00201
00202 if(strfindcasestrz(&msg, "Transfer-Encoding: chunked")!=NULL)
00203 {
00204 c->req.flags |= F_TCP_REQ_BCHUNKED;
00205 ret = 1;
00206 }
00207 return ret;
00208 }
00209 #endif
00210
00211
00240 int tcp_read_data(int fd, struct tcp_connection *c,
00241 char* buf, int b_size, int* flags)
00242 {
00243 int bytes_read;
00244
00245 again:
00246 bytes_read=read(fd, buf, b_size);
00247
00248 if (likely(bytes_read!=b_size)){
00249 if(unlikely(bytes_read==-1)){
00250 if (errno == EWOULDBLOCK || errno == EAGAIN){
00251 bytes_read=0;
00252 }else if (errno == EINTR) goto again;
00253 else{
00254 if (unlikely(c->state==S_CONN_CONNECT)){
00255 switch(errno){
00256 case ECONNRESET:
00257 #ifdef USE_DST_BLACKLIST
00258 dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
00259 &c->rcv.src_su,
00260 &c->send_flags, 0);
00261 #endif
00262 TCP_EV_CONNECT_RST(errno, TCP_LADDR(c),
00263 TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
00264 break;
00265 case ETIMEDOUT:
00266 #ifdef USE_DST_BLACKLIST
00267 dst_blacklist_su(BLST_ERR_CONNECT, c->rcv.proto,
00268 &c->rcv.src_su,
00269 &c->send_flags, 0);
00270 #endif
00271 TCP_EV_CONNECT_TIMEOUT(errno, TCP_LADDR(c),
00272 TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
00273 break;
00274 default:
00275 TCP_EV_CONNECT_ERR(errno, TCP_LADDR(c),
00276 TCP_LPORT(c), TCP_PSU(c), TCP_PROTO(c));
00277 }
00278 TCP_STATS_CONNECT_FAILED();
00279 }else{
00280 switch(errno){
00281 case ECONNRESET:
00282 TCP_STATS_CON_RESET();
00283 case ETIMEDOUT:
00284 #ifdef USE_DST_BLACKLIST
00285 dst_blacklist_su(BLST_ERR_SEND, c->rcv.proto,
00286 &c->rcv.src_su,
00287 &c->send_flags, 0);
00288 #endif
00289 break;
00290 }
00291 }
00292 LOG(cfg_get(core, core_cfg, corelog),
00293 "error reading: %s (%d)\n", strerror(errno), errno);
00294 return -1;
00295 }
00296 }else if (unlikely((bytes_read==0) ||
00297 (*flags & RD_CONN_FORCE_EOF))){
00298 c->state=S_CONN_EOF;
00299 *flags|=RD_CONN_EOF;
00300 DBG("EOF on %p, FD %d\n", c, fd);
00301 }else{
00302 if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT)){
00303 TCP_STATS_ESTABLISHED(c->state);
00304 c->state=S_CONN_OK;
00305 }
00306 }
00307
00308 *flags|=RD_CONN_SHORT_READ;
00309 }else{
00310 if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT)){
00311 TCP_STATS_ESTABLISHED(c->state);
00312 c->state=S_CONN_OK;
00313 }
00314 }
00315 return bytes_read;
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 int tcp_read(struct tcp_connection *c, int* flags)
00334 {
00335 int bytes_free, bytes_read;
00336 struct tcp_req *r;
00337 int fd;
00338
00339 r=&c->req;
00340 fd=c->fd;
00341 bytes_free=r->b_size- (int)(r->pos - r->buf);
00342
00343 if (unlikely(bytes_free==0)){
00344 LOG(L_ERR, "ERROR: tcp_read: buffer overrun, dropping\n");
00345 r->error=TCP_REQ_OVERRUN;
00346 return -1;
00347 }
00348 bytes_read = tcp_read_data(fd, c, r->pos, bytes_free, flags);
00349 if (unlikely(bytes_read < 0)){
00350 r->error=TCP_READ_ERROR;
00351 return -1;
00352 }
00353 #ifdef EXTRA_DEBUG
00354 DBG("tcp_read: read %d bytes:\n%.*s\n", bytes_read, bytes_read, r->pos);
00355 #endif
00356 r->pos+=bytes_read;
00357 return bytes_read;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 int tcp_read_headers(struct tcp_connection *c, int* read_flags)
00372 {
00373 int bytes, remaining;
00374 char *p;
00375 struct tcp_req* r;
00376
00377 #ifdef USE_STUN
00378 unsigned int mc;
00379 unsigned short body_len;
00380 #endif
00381
00382 #ifdef READ_MSRP
00383 char *mfline;
00384 str mtransid;
00385 #endif
00386
00387 #define crlf_default_skip_case \
00388 case '\n': \
00389 r->state=H_LF; \
00390 break; \
00391 default: \
00392 r->state=H_SKIP
00393
00394 #define content_len_beg_case \
00395 case ' ': \
00396 case '\t': \
00397 if (!TCP_REQ_HAS_CLEN(r)) r->state=H_STARTWS; \
00398 else r->state=H_SKIP; \
00399 \
00400 break; \
00401 case 'C': \
00402 case 'c': \
00403 if(!TCP_REQ_HAS_CLEN(r)) r->state=H_CONT_LEN1; \
00404 else r->state=H_SKIP; \
00405 break; \
00406 case 'l': \
00407 case 'L': \
00408 \
00409 if (!TCP_REQ_HAS_CLEN(r)) r->state=H_L_COLON; \
00410 else r->state=H_SKIP; \
00411 break
00412
00413 #define change_state(upper, lower, newstate)\
00414 switch(*p){ \
00415 case upper: \
00416 case lower: \
00417 r->state=(newstate); break; \
00418 crlf_default_skip_case; \
00419 }
00420
00421 #define change_state_case(state0, upper, lower, newstate)\
00422 case state0: \
00423 change_state(upper, lower, newstate); \
00424 p++; \
00425 break
00426
00427
00428 r=&c->req;
00429
00430 if (unlikely(r->parsed<r->pos)){
00431 bytes=0;
00432 }else{
00433 #ifdef USE_TLS
00434 if (unlikely(c->type==PROTO_TLS))
00435 bytes=tls_read(c, read_flags);
00436 else
00437 #endif
00438 bytes=tcp_read(c, read_flags);
00439 if (bytes<=0) return bytes;
00440 }
00441 p=r->parsed;
00442
00443 while(p<r->pos && r->error==TCP_REQ_OK){
00444 switch((unsigned char)r->state){
00445 case H_BODY:
00446 remaining=r->pos-p;
00447 if (remaining>r->bytes_to_go) remaining=r->bytes_to_go;
00448 r->bytes_to_go-=remaining;
00449 p+=remaining;
00450 if (r->bytes_to_go==0){
00451 r->flags|=F_TCP_REQ_COMPLETE;
00452 goto skip;
00453 }
00454 break;
00455
00456 case H_SKIP:
00457
00458
00459 p=q_memchr(p, '\n', r->pos-p);
00460 if (p){
00461 #ifdef READ_MSRP
00462
00463 if(!((r->flags&F_TCP_REQ_MSRP_NO)
00464 || (r->flags&F_TCP_REQ_MSRP_FRAME))) {
00465 if((r->pos - r->start)>5
00466 && strncmp(r->start, "MSRP ", 5)==0)
00467 {
00468 r->flags |= F_TCP_REQ_MSRP_FRAME;
00469 } else {
00470 r->flags |= F_TCP_REQ_MSRP_NO;
00471 }
00472 }
00473 #endif
00474 p++;
00475 r->state=H_LF;
00476 }else{
00477 p=r->pos;
00478 }
00479 break;
00480
00481 case H_LF:
00482
00483 switch (*p){
00484 case '\r':
00485 r->state=H_LFCR;
00486 break;
00487 case '\n':
00488
00489 r->state=H_BODY;
00490 if (TCP_REQ_HAS_CLEN(r)){
00491 r->body=p+1;
00492 r->bytes_to_go=r->content_len;
00493 if (r->bytes_to_go==0){
00494 r->flags|=F_TCP_REQ_COMPLETE;
00495 p++;
00496 goto skip;
00497 }
00498 }else{
00499 DBG("tcp_read_headers: ERROR: no clen, p=%X\n",
00500 *p);
00501 r->error=TCP_REQ_BAD_LEN;
00502 }
00503 break;
00504 case '-':
00505 r->state=H_SKIP;
00506 #ifdef READ_MSRP
00507
00508
00509
00510 if(r->flags&F_TCP_REQ_MSRP_FRAME) {
00511 p--;
00512 r->state=H_MSRP_BODY_END;
00513 }
00514 #endif
00515 break;
00516 content_len_beg_case;
00517 default:
00518 r->state=H_SKIP;
00519 }
00520 p++;
00521 break;
00522 case H_LFCR:
00523 if (*p=='\n'){
00524
00525 r->state=H_BODY;
00526 #ifdef READ_HTTP11
00527 if (cfg_get(tcp, tcp_cfg, accept_no_cl)!=0)
00528 tcp_http11_continue(c);
00529 #endif
00530 if (TCP_REQ_HAS_CLEN(r)){
00531 r->body=p+1;
00532 r->bytes_to_go=r->content_len;
00533 if (r->bytes_to_go==0){
00534 r->flags|=F_TCP_REQ_COMPLETE;
00535 p++;
00536 goto skip;
00537 }
00538 }else{
00539 if (cfg_get(tcp, tcp_cfg, accept_no_cl)!=0) {
00540 #ifdef READ_MSRP
00541
00542 if(c->req.flags&F_TCP_REQ_MSRP_FRAME)
00543 {
00544 r->body=p+1;
00545
00546 r->bytes_to_go=3;
00547 p++;
00548 r->content_len = 0;
00549 r->state=H_MSRP_BODY;
00550 break;
00551 }
00552 #endif
00553
00554 #ifdef READ_HTTP11
00555 if(TCP_REQ_BCHUNKED(r)) {
00556 r->body=p+1;
00557
00558 r->bytes_to_go=3;
00559 p++;
00560 r->content_len = 0;
00561 r->state=H_HTTP11_CHUNK_START;
00562 break;
00563 }
00564 #endif
00565 r->body=p+1;
00566 r->bytes_to_go=0;
00567 r->flags|=F_TCP_REQ_COMPLETE;
00568 p++;
00569 goto skip;
00570 } else {
00571 DBG("tcp_read_headers: ERROR: no clen, p=%X\n",
00572 *p);
00573 r->error=TCP_REQ_BAD_LEN;
00574 }
00575 }
00576 }else r->state=H_SKIP;
00577 p++;
00578 break;
00579
00580 case H_STARTWS:
00581 switch (*p){
00582 content_len_beg_case;
00583 crlf_default_skip_case;
00584 }
00585 p++;
00586 break;
00587 case H_SKIP_EMPTY:
00588 switch (*p){
00589 case '\n':
00590 break;
00591 case '\r':
00592 if (cfg_get(tcp, tcp_cfg, crlf_ping)) {
00593 r->state=H_SKIP_EMPTY_CR_FOUND;
00594 r->start=p;
00595 }
00596 break;
00597 case ' ':
00598 case '\t':
00599
00600 break;
00601 case 'C':
00602 case 'c':
00603 r->state=H_CONT_LEN1;
00604 r->start=p;
00605 break;
00606 case 'l':
00607 case 'L':
00608
00609 r->state=H_L_COLON;
00610 r->start=p;
00611 break;
00612 default:
00613 #ifdef USE_STUN
00614
00615
00616 if (stun_allow_stun && (unsigned char)*p == 0x00) {
00617 r->state=H_STUN_MSG;
00618
00619 r->body=p;
00620 r->content_len = 0;
00621 DBG("stun msg detected\n");
00622 }else
00623 #endif
00624 r->state=H_SKIP;
00625 r->start=p;
00626 };
00627 p++;
00628 break;
00629
00630 case H_SKIP_EMPTY_CR_FOUND:
00631 if (*p=='\n'){
00632 r->state=H_SKIP_EMPTY_CRLF_FOUND;
00633 p++;
00634 }else{
00635 r->state=H_SKIP_EMPTY;
00636 }
00637 break;
00638
00639 case H_SKIP_EMPTY_CRLF_FOUND:
00640 if (*p=='\r'){
00641 r->state = H_SKIP_EMPTY_CRLFCR_FOUND;
00642 p++;
00643 }else{
00644 r->state = H_SKIP_EMPTY;
00645 }
00646 break;
00647
00648 case H_SKIP_EMPTY_CRLFCR_FOUND:
00649 if (*p=='\n'){
00650 r->state = H_PING_CRLF;
00651 r->flags |= F_TCP_REQ_HAS_CLEN |
00652 F_TCP_REQ_COMPLETE;
00653 p++;
00654 goto skip;
00655 }else{
00656 r->state = H_SKIP_EMPTY;
00657 }
00658 break;
00659 #ifdef USE_STUN
00660 case H_STUN_MSG:
00661 if ((r->pos - r->body) >= sizeof(struct stun_hdr)) {
00662
00663
00664
00665 memcpy(&body_len, &r->start[sizeof(unsigned short)],
00666 sizeof(unsigned short));
00667
00668 body_len = ntohs(body_len);
00669
00670
00671 memcpy(&mc, &r->start[sizeof(unsigned int)],
00672 sizeof(unsigned int));
00673 mc = ntohl(mc);
00674
00675
00676
00677 r->flags |= (mc == MAGIC_COOKIE) ? F_TCP_REQ_HAS_CLEN : 0;
00678
00679 r->body += sizeof(struct stun_hdr);
00680 p = r->body;
00681
00682 if (body_len > 0) {
00683 r->state = H_STUN_READ_BODY;
00684 }
00685 else {
00686 if (is_msg_complete(r) != 0) {
00687 goto skip;
00688 }
00689 else {
00690
00691 body_len = sizeof(struct stun_attr) +
00692 SHA_DIGEST_LENGTH;
00693 }
00694 }
00695 r->content_len=body_len;
00696 }
00697 else {
00698 p = r->pos;
00699 }
00700 break;
00701
00702 case H_STUN_READ_BODY:
00703
00704 body_len=r->content_len;
00705 if ((r->pos - r->body) >= body_len) {
00706 r->body += body_len;
00707 p = r->body;
00708 if (is_msg_complete(r) != 0) {
00709 r->content_len=0;
00710 goto skip;
00711 }
00712 else {
00713
00714 body_len = sizeof(struct stun_attr)+SHA_DIGEST_LENGTH;
00715 r->content_len=body_len;
00716 }
00717 }
00718 else {
00719 p = r->pos;
00720 }
00721 break;
00722
00723 case H_STUN_FP:
00724
00725 body_len=r->content_len;
00726 if ((r->pos - r->body) >= body_len) {
00727 r->body += body_len;
00728 p = r->body;
00729 r->state = H_STUN_END;
00730 r->flags |= F_TCP_REQ_COMPLETE |
00731 F_TCP_REQ_HAS_CLEN;
00732 r->content_len=0;
00733 goto skip;
00734 }
00735 else {
00736 p = r->pos;
00737 }
00738 break;
00739 #endif
00740 change_state_case(H_CONT_LEN1, 'O', 'o', H_CONT_LEN2);
00741 change_state_case(H_CONT_LEN2, 'N', 'n', H_CONT_LEN3);
00742 change_state_case(H_CONT_LEN3, 'T', 't', H_CONT_LEN4);
00743 change_state_case(H_CONT_LEN4, 'E', 'e', H_CONT_LEN5);
00744 change_state_case(H_CONT_LEN5, 'N', 'n', H_CONT_LEN6);
00745 change_state_case(H_CONT_LEN6, 'T', 't', H_CONT_LEN7);
00746 change_state_case(H_CONT_LEN7, '-', '_', H_CONT_LEN8);
00747 change_state_case(H_CONT_LEN8, 'L', 'l', H_CONT_LEN9);
00748 change_state_case(H_CONT_LEN9, 'E', 'e', H_CONT_LEN10);
00749 change_state_case(H_CONT_LEN10, 'N', 'n', H_CONT_LEN11);
00750 change_state_case(H_CONT_LEN11, 'G', 'g', H_CONT_LEN12);
00751 change_state_case(H_CONT_LEN12, 'T', 't', H_CONT_LEN13);
00752 change_state_case(H_CONT_LEN13, 'H', 'h', H_L_COLON);
00753
00754 case H_L_COLON:
00755 switch(*p){
00756 case ' ':
00757 case '\t':
00758 break;
00759 case ':':
00760 r->state=H_CONT_LEN_BODY;
00761 break;
00762 crlf_default_skip_case;
00763 };
00764 p++;
00765 break;
00766
00767 case H_CONT_LEN_BODY:
00768 switch(*p){
00769 case ' ':
00770 case '\t':
00771 break;
00772 case '0':
00773 case '1':
00774 case '2':
00775 case '3':
00776 case '4':
00777 case '5':
00778 case '6':
00779 case '7':
00780 case '8':
00781 case '9':
00782 r->state=H_CONT_LEN_BODY_PARSE;
00783 r->content_len=(*p-'0');
00784 break;
00785
00786 crlf_default_skip_case;
00787 }
00788 p++;
00789 break;
00790
00791 case H_CONT_LEN_BODY_PARSE:
00792 switch(*p){
00793 case '0':
00794 case '1':
00795 case '2':
00796 case '3':
00797 case '4':
00798 case '5':
00799 case '6':
00800 case '7':
00801 case '8':
00802 case '9':
00803 r->content_len=r->content_len*10+(*p-'0');
00804 break;
00805 case '\r':
00806 case ' ':
00807 case '\t':
00808 r->state=H_SKIP;
00809 r->flags|=F_TCP_REQ_HAS_CLEN;
00810 break;
00811 case '\n':
00812
00813 r->state=H_LF;
00814 r->flags|=F_TCP_REQ_HAS_CLEN;
00815 break;
00816 default:
00817 LOG(L_ERR, "ERROR: tcp_read_headers: bad "
00818 "Content-Length header value, unexpected "
00819 "char %c in state %d\n", *p, r->state);
00820 r->state=H_SKIP;
00821 }
00822 p++;
00823 break;
00824
00825 #ifdef READ_HTTP11
00826 case H_HTTP11_CHUNK_START:
00827 r->chunk_size = 0;
00828 r->state = H_HTTP11_CHUNK_SIZE;
00829 break;
00830 case H_HTTP11_CHUNK_BODY:
00831 remaining=r->pos-p;
00832 if (remaining>r->bytes_to_go) remaining=r->bytes_to_go;
00833 r->bytes_to_go-=remaining;
00834 p+=remaining;
00835 if (r->bytes_to_go==0){
00836 r->state = H_HTTP11_CHUNK_END;
00837
00838 if(r->chunk_size>0 && p-r->chunk_size>r->body) {
00839 memmove(r->body + r->content_len, p - r->chunk_size,
00840 r->chunk_size);
00841 r->content_len += r->chunk_size;
00842 }
00843 goto skip;
00844 }
00845 break;
00846
00847 case H_HTTP11_CHUNK_END:
00848 switch(*p){
00849 case '\r':
00850 case ' ':
00851 case '\t':
00852 break;
00853 case '\n':
00854 r->state = H_HTTP11_CHUNK_START;
00855 break;
00856 default:
00857 LM_ERR("bad chunk, unexpected "
00858 "char %c in state %d\n", *p, r->state);
00859 r->state=H_SKIP;
00860 }
00861 p++;
00862 break;
00863
00864 case H_HTTP11_CHUNK_SIZE:
00865 switch(*p){
00866 case '0': case '1': case '2': case '3':
00867 case '4': case '5': case '6': case '7':
00868 case '8': case '9':
00869 r->chunk_size <<= 4;
00870 r->chunk_size += *p - '0';
00871 break;
00872 case 'a': case 'b': case 'c': case 'd':
00873 case 'e': case 'f':
00874 r->chunk_size <<= 4;
00875 r->chunk_size += *p - 'a' + 10;
00876 break;
00877 case 'A': case 'B': case 'C': case 'D':
00878 case 'E': case 'F':
00879 r->chunk_size <<= 4;
00880 r->chunk_size += *p - 'A' + 10;
00881 break;
00882 case '\r':
00883 case ' ':
00884 case '\t':
00885 break;
00886 case '\n':
00887
00888 r->state=H_HTTP11_CHUNK_BODY;
00889 r->bytes_to_go = r->chunk_size;
00890 if (r->bytes_to_go==0){
00891 r->state=H_HTTP11_CHUNK_FINISH;
00892 r->flags|=F_TCP_REQ_COMPLETE;
00893 p++;
00894 goto skip;
00895 }
00896 break;
00897 default:
00898 LM_ERR("bad chunk size value, unexpected "
00899 "char %c in state %d\n", *p, r->state);
00900 r->state=H_SKIP;
00901 }
00902 p++;
00903 break;
00904 #endif
00905 #ifdef READ_MSRP
00906 case H_MSRP_BODY:
00907
00908
00909 r->flags |= F_TCP_REQ_MSRP_BODY;
00910 p = q_memchr(p, '\n', r->pos-p);
00911 if (p) {
00912 p++;
00913 r->state=H_MSRP_BODY_LF;
00914 } else {
00915 p=r->pos;
00916 }
00917 break;
00918 case H_MSRP_BODY_LF:
00919 switch (*p) {
00920 case '-':
00921 p--;
00922 r->state=H_MSRP_BODY_END;
00923 break;
00924 default:
00925 r->state=H_MSRP_BODY;
00926 }
00927 p++;
00928 break;
00929 case H_MSRP_BODY_END:
00930
00931 p = q_memchr(p, '\n', r->pos-p);
00932 if (p) {
00933
00934 if(r->pos - r->start < 10) {
00935 LM_ERR("weird situation when reading MSRP frame"
00936 " - continue reading\n");
00937 p++;
00938 r->state=H_MSRP_BODY;
00939 break;
00940 }
00941 if(*(p-1)!='\r') {
00942
00943 p++;
00944 r->state=H_MSRP_BODY;
00945 break;
00946 }
00947
00948
00949 mfline = q_memchr(r->start, '\n', r->pos-r->start);
00950 mtransid.s = q_memchr(r->start + 5 , ' ',
00951 mfline - r->start);
00952 mtransid.len = mtransid.s - r->start - 5;
00953 mtransid.s = r->start + 5;
00954 trim(&mtransid);
00955 if(memcmp(mtransid.s,
00956 p - 1 - 1 - mtransid.len,
00957 mtransid.len)!=0) {
00958
00959 p++;
00960 r->state=H_MSRP_BODY;
00961 break;
00962 }
00963 if(memcmp(p - 1 - 1 - mtransid.len
00964 - 7 - 1 , "\n-------",
00965 8)!=0) {
00966
00967 p++;
00968 r->state=H_MSRP_BODY;
00969 break;
00970 }
00971 r->state=H_MSRP_FINISH;
00972 r->flags|=F_TCP_REQ_COMPLETE;
00973 p++;
00974 goto skip;
00975
00976 } else {
00977 p=r->pos;
00978 }
00979 break;
00980 #endif
00981
00982 default:
00983 LOG(L_CRIT, "BUG: tcp_read_headers: unexpected state %d\n",
00984 r->state);
00985 abort();
00986 }
00987 }
00988 skip:
00989 r->parsed=p;
00990 return bytes;
00991 }
00992
00993
00994 #ifdef READ_MSRP
00995 int msrp_process_msg(char* tcpbuf, unsigned int len,
00996 struct receive_info* rcv_info, struct tcp_connection* con)
00997 {
00998 int ret;
00999 tcp_event_info_t tev;
01000
01001 ret = 0;
01002 LM_DBG("MSRP Message: [[>>>\n%.*s<<<]]\n", len, tcpbuf);
01003 if(likely(sr_event_enabled(SREV_TCP_MSRP_FRAME))) {
01004 memset(&tev, 0, sizeof(tcp_event_info_t));
01005 tev.type = SREV_TCP_MSRP_FRAME;
01006 tev.buf = tcpbuf;
01007 tev.len = len;
01008 tev.rcv = rcv_info;
01009 tev.con = con;
01010 ret = sr_event_exec(SREV_TCP_MSRP_FRAME, (void*)(&tev));
01011 } else {
01012 LM_DBG("no callback registering for handling MSRP - dropping!\n");
01013 }
01014 return ret;
01015 }
01016 #endif
01017
01026 int receive_tcp_msg(char* tcpbuf, unsigned int len,
01027 struct receive_info* rcv_info, struct tcp_connection* con)
01028 {
01029 #ifdef TCP_CLONE_RCVBUF
01030 #ifdef DYN_BUF
01031 char *buf = NULL;
01032 #else
01033 static char *buf = NULL;
01034 static unsigned int bsize = 0;
01035 #endif
01036 int blen;
01037
01038
01039 if(likely(tcp_clone_rcvbuf==0)) {
01040 #ifdef READ_MSRP
01041 if(unlikely(con->req.flags&F_TCP_REQ_MSRP_FRAME))
01042 return msrp_process_msg(tcpbuf, len, rcv_info, con);
01043 #endif
01044 return receive_msg(tcpbuf, len, rcv_info);
01045 }
01046
01047
01048 blen = len;
01049 if(blen < BUF_SIZE)
01050 blen = BUF_SIZE;
01051
01052 #ifdef DYN_BUF
01053 buf=pkg_malloc(blen+1);
01054 if (buf==0) {
01055 LM_ERR("could not allocate receive buffer\n");
01056 return -1;
01057 }
01058 #else
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069 if(buf==NULL || bsize < blen || blen < bsize/2) {
01070 if(buf!=NULL)
01071 free(buf);
01072 buf=malloc(blen+1);
01073 if (buf==0) {
01074 LM_ERR("could not allocate receive buffer\n");
01075 return -1;
01076 }
01077 bsize = blen;
01078 }
01079 #endif
01080
01081 memcpy(buf, tcpbuf, len);
01082 buf[len] = '\0';
01083 #ifdef READ_MSRP
01084 if(unlikely(con->req.flags&F_TCP_REQ_MSRP_FRAME))
01085 return msrp_process_msg(buf, len, rcv_info, con);
01086 #endif
01087 return receive_msg(buf, len, rcv_info);
01088 #else
01089 #ifdef READ_MSRP
01090 if(unlikely(con->req.flags&F_TCP_REQ_MSRP_FRAME))
01091 return msrp_process_msg(tcpbuf, len, rcv_info, con);
01092 #endif
01093 return receive_msg(tcpbuf, len, rcv_info);
01094 #endif
01095 }
01096
01097 int tcp_read_req(struct tcp_connection* con, int* bytes_read, int* read_flags)
01098 {
01099 int bytes;
01100 int total_bytes;
01101 int resp;
01102 long size;
01103 struct tcp_req* req;
01104 struct dest_info dst;
01105 char c;
01106 int ret;
01107
01108 bytes=-1;
01109 total_bytes=0;
01110 resp=CONN_RELEASE;
01111 req=&con->req;
01112
01113 again:
01114 if (likely(req->error==TCP_REQ_OK)){
01115 bytes=tcp_read_headers(con, read_flags);
01116 #ifdef EXTRA_DEBUG
01117
01118 DBG("read= %d bytes, parsed=%d, state=%d, error=%d\n",
01119 bytes, (int)(req->parsed-req->start), req->state,
01120 req->error );
01121 DBG("tcp_read_req: last char=0x%02X, parsed msg=\n%.*s\n",
01122 *(req->parsed-1), (int)(req->parsed-req->start),
01123 req->start);
01124 #endif
01125 if (unlikely(bytes==-1)){
01126 LOG(cfg_get(core, core_cfg, corelog),
01127 "ERROR: tcp_read_req: error reading \n");
01128 resp=CONN_ERROR;
01129 goto end_req;
01130 }
01131 total_bytes+=bytes;
01132
01133
01134
01135
01136
01137 if (unlikely((con->state==S_CONN_EOF) &&
01138 (! TCP_REQ_COMPLETE(req)))) {
01139 DBG( "tcp_read_req: EOF\n");
01140 resp=CONN_EOF;
01141 goto end_req;
01142 }
01143
01144 }
01145 if (unlikely(req->error!=TCP_REQ_OK)){
01146 LOG(L_ERR,"ERROR: tcp_read_req: bad request, state=%d, error=%d "
01147 "buf:\n%.*s\nparsed:\n%.*s\n", req->state, req->error,
01148 (int)(req->pos-req->buf), req->buf,
01149 (int)(req->parsed-req->start), req->start);
01150 DBG("- received from: port %d\n", con->rcv.src_port);
01151 print_ip("- received from: ip ",&con->rcv.src_ip, "\n");
01152 resp=CONN_ERROR;
01153 goto end_req;
01154 }
01155 if (likely(TCP_REQ_COMPLETE(req))){
01156 #ifdef EXTRA_DEBUG
01157 DBG("tcp_read_req: end of header part\n");
01158 DBG("- received from: port %d\n", con->rcv.src_port);
01159 print_ip("- received from: ip ", &con->rcv.src_ip, "\n");
01160 DBG("tcp_read_req: headers:\n%.*s.\n",
01161 (int)(req->body-req->start), req->start);
01162 #endif
01163 if (likely(TCP_REQ_HAS_CLEN(req))){
01164 DBG("tcp_read_req: content-length= %d\n", req->content_len);
01165 #ifdef EXTRA_DEBUG
01166 DBG("tcp_read_req: body:\n%.*s\n", req->content_len,req->body);
01167 #endif
01168 }else{
01169 if (cfg_get(tcp, tcp_cfg, accept_no_cl)==0) {
01170 req->error=TCP_REQ_BAD_LEN;
01171 LOG(L_ERR, "ERROR: tcp_read_req: content length not present or"
01172 " unparsable\n");
01173 resp=CONN_ERROR;
01174 goto end_req;
01175 }
01176 }
01177
01178 resp=CONN_RELEASE;
01179 #ifdef EXTRA_DEBUG
01180 DBG("receiving msg(%p, %d, )\n",
01181 req->start, (int)(req->parsed-req->start));
01182 #endif
01183
01184 bind_address=con->rcv.bind_address;
01185
01186
01187
01188
01189
01190
01191
01192
01193 con->rcv.proto_reserved1=con->id;
01194 c=*req->parsed;
01195
01196
01197 *req->parsed=0;
01198
01199 if (req->state==H_PING_CRLF) {
01200 init_dst_from_rcv(&dst, &con->rcv);
01201
01202 if (tcp_send(&dst, 0, CRLF, CRLF_LEN) < 0) {
01203 LOG(L_ERR, "CRLF ping: tcp_send() failed\n");
01204 }
01205 ret = 0;
01206 }else
01207 #ifdef USE_STUN
01208 if (unlikely(req->state==H_STUN_END)){
01209
01210 ret = stun_process_msg(req->start, req->parsed-req->start,
01211 &con->rcv);
01212 }else
01213 #endif
01214 #ifdef READ_MSRP
01215
01216 if (unlikely(req->state==H_MSRP_FINISH)){
01217
01218 ret = receive_tcp_msg(req->start, req->parsed-req->start,
01219 &con->rcv, con);
01220 }else
01221 #endif
01222 #ifdef READ_HTTP11
01223 if (unlikely(req->state==H_HTTP11_CHUNK_FINISH)){
01224
01225 req->body[req->content_len] = 0;
01226 ret = receive_tcp_msg(req->start,
01227 req->body + req->content_len - req->start,
01228 &con->rcv, con);
01229 }else
01230 #endif
01231 ret = receive_tcp_msg(req->start, req->parsed-req->start,
01232 &con->rcv, con);
01233
01234 if (unlikely(ret < 0)) {
01235 *req->parsed=c;
01236 resp=CONN_ERROR;
01237 goto end_req;
01238 }
01239 *req->parsed=c;
01240
01241
01242 size=req->pos-req->parsed;
01243 req->start=req->buf;
01244 req->body=0;
01245 req->error=TCP_REQ_OK;
01246 req->state=H_SKIP_EMPTY;
01247 req->flags=0;
01248 req->content_len=0;
01249 req->bytes_to_go=0;
01250 req->pos=req->buf+size;
01251
01252 if (unlikely(size)){
01253 memmove(req->buf, req->parsed, size);
01254 req->parsed=req->buf;
01255 #ifdef EXTRA_DEBUG
01256 DBG("tcp_read_req: preparing for new request, kept %ld"
01257 " bytes\n", size);
01258 #endif
01259
01260 goto again;
01261 } else if (unlikely(con->state==S_CONN_EOF)){
01262 DBG( "tcp_read_req: EOF after reading complete request\n");
01263 resp=CONN_EOF;
01264 }
01265 req->parsed=req->buf;
01266 }
01267
01268
01269 end_req:
01270 if (likely(bytes_read)) *bytes_read=total_bytes;
01271 return resp;
01272 }
01273
01274
01275
01276 void release_tcpconn(struct tcp_connection* c, long state, int unix_sock)
01277 {
01278 long response[2];
01279
01280 DBG( "releasing con %p, state %ld, fd=%d, id=%d\n",
01281 c, state, c->fd, c->id);
01282 DBG(" extra_data %p\n", c->extra_data);
01283
01284 c->reader_pid=0;
01285 if (c->fd!=-1){
01286 close(c->fd);
01287 c->fd=-1;
01288 }
01289
01290 response[0]=(long)c;
01291 response[1]=state;
01292
01293 if (tsend_stream(unix_sock, (char*)response, sizeof(response), -1)<=0)
01294 LOG(L_ERR, "ERROR: release_tcpconn: tsend_stream failed\n");
01295 }
01296
01297
01298
01299 static ticks_t tcpconn_read_timeout(ticks_t t, struct timer_ln* tl, void* data)
01300 {
01301 struct tcp_connection *c;
01302
01303 c=(struct tcp_connection*)data;
01304
01305
01306 if (likely(!(c->state<0) && TICKS_LT(t, c->timeout))){
01307
01308 return (ticks_t)(c->timeout - t);
01309 }
01310
01311 if (unlikely(io_watch_del(&io_w, c->fd, -1, IO_FD_CLOSING)<0)){
01312 LOG(L_ERR, "ERROR: tcpconn_read_timeout: io_watch_del failed for %p"
01313 " id %d fd %d, state %d, flags %x, main fd %d\n",
01314 c, c->id, c->fd, c->state, c->flags, c->s);
01315 }
01316 tcpconn_listrm(tcp_conn_lst, c, c_next, c_prev);
01317 release_tcpconn(c, (c->state<0)?CONN_ERROR:CONN_RELEASE, tcpmain_sock);
01318
01319 return 0;
01320 }
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337 inline static int handle_io(struct fd_map* fm, short events, int idx)
01338 {
01339 int ret;
01340 int n;
01341 int read_flags;
01342 struct tcp_connection* con;
01343 int s;
01344 long resp;
01345 ticks_t t;
01346
01347
01348 cfg_update();
01349
01350 switch(fm->type){
01351 case F_TCPMAIN:
01352 again:
01353 ret=n=receive_fd(fm->fd, &con, sizeof(con), &s, 0);
01354 DBG("received n=%d con=%p, fd=%d\n", n, con, s);
01355 if (unlikely(n<0)){
01356 if (errno == EWOULDBLOCK || errno == EAGAIN){
01357 ret=0;
01358 break;
01359 }else if (errno == EINTR) goto again;
01360 else{
01361 LOG(L_CRIT,"BUG: tcp_receive: handle_io: read_fd: %s \n",
01362 strerror(errno));
01363 abort();
01364 }
01365 }
01366 if (unlikely(n==0)){
01367 LOG(L_ERR, "WARNING: tcp_receive: handle_io: 0 bytes read\n");
01368 goto error;
01369 }
01370 if (unlikely(con==0)){
01371 LOG(L_CRIT, "BUG: tcp_receive: handle_io null pointer\n");
01372 goto error;
01373 }
01374 con->fd=s;
01375 if (unlikely(s==-1)) {
01376 LOG(L_ERR, "ERROR: tcp_receive: handle_io: read_fd:"
01377 "no fd read\n");
01378 goto con_error;
01379 }
01380 con->reader_pid=my_pid();
01381 if (unlikely(con==tcp_conn_lst)){
01382 LOG(L_CRIT, "BUG: tcp_receive: handle_io: duplicate"
01383 " connection received: %p, id %d, fd %d, refcnt %d"
01384 " state %d (n=%d)\n", con, con->id, con->fd,
01385 atomic_get(&con->refcnt), con->state, n);
01386 goto con_error;
01387 break;
01388 }
01389 if (unlikely(con->state==S_CONN_BAD)){
01390 LOG(L_WARN, "WARNING: tcp_receive: handle_io: received an"
01391 " already bad connection: %p id %d refcnt %d\n",
01392 con, con->id, atomic_get(&con->refcnt));
01393 goto con_error;
01394 }
01395
01396
01397 read_flags=((con->flags & (F_CONN_EOF_SEEN|F_CONN_FORCE_EOF)) &&
01398 !(con->flags & F_CONN_OOB_DATA))? RD_CONN_FORCE_EOF
01399 :0;
01400 #ifdef USE_TLS
01401 repeat_1st_read:
01402 #endif
01403 resp=tcp_read_req(con, &n, &read_flags);
01404 if (unlikely(resp<0)){
01405
01406
01407 if (unlikely(resp!=CONN_EOF))
01408 con->state=S_CONN_BAD;
01409 release_tcpconn(con, resp, tcpmain_sock);
01410 break;
01411 }
01412 #ifdef USE_TLS
01413
01414 if (unlikely(read_flags & RD_CONN_REPEAT_READ))
01415 goto repeat_1st_read;
01416 #endif
01417
01418
01419
01420
01421
01422 tcpconn_listadd(tcp_conn_lst, con, c_next, c_prev);
01423 t=get_ticks_raw();
01424 con->timeout=t+S_TO_TICKS(TCP_CHILD_TIMEOUT);
01425
01426 con->timer.f=tcpconn_read_timeout;
01427 local_timer_reinit(&con->timer);
01428 local_timer_add(&tcp_reader_ltimer, &con->timer,
01429 S_TO_TICKS(TCP_CHILD_TIMEOUT), t);
01430 if (unlikely(io_watch_add(&io_w, s, POLLIN, F_TCPCONN, con)<0)){
01431 LOG(L_CRIT, "ERROR: tcpconn_receive: handle_io: io_watch_add "
01432 "failed for %p id %d fd %d, state %d, flags %x,"
01433 " main fd %d, refcnt %d\n",
01434 con, con->id, con->fd, con->state, con->flags,
01435 con->s, atomic_get(&con->refcnt));
01436 tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
01437 local_timer_del(&tcp_reader_ltimer, &con->timer);
01438 goto con_error;
01439 }
01440 break;
01441 case F_TCPCONN:
01442 con=(struct tcp_connection*)fm->data;
01443 if (unlikely(con->state==S_CONN_BAD)){
01444 resp=CONN_ERROR;
01445 if (!(con->send_flags.f & SND_F_CON_CLOSE))
01446 LOG(L_WARN, "WARNING: tcp_receive: handle_io: F_TCPCONN"
01447 " connection marked as bad: %p id %d refcnt %d\n",
01448 con, con->id, atomic_get(&con->refcnt));
01449 goto read_error;
01450 }
01451 read_flags=((
01452 #ifdef POLLRDHUP
01453 (events & POLLRDHUP) |
01454 #endif
01455 (events & (POLLHUP|POLLERR)) |
01456 (con->flags & (F_CONN_EOF_SEEN|F_CONN_FORCE_EOF)))
01457 && !(events & POLLPRI))? RD_CONN_FORCE_EOF: 0;
01458 #ifdef USE_TLS
01459 repeat_read:
01460 #endif
01461 resp=tcp_read_req(con, &ret, &read_flags);
01462 if (unlikely(resp<0)){
01463 read_error:
01464 ret=-1;
01465 if (unlikely(io_watch_del(&io_w, con->fd, idx,
01466 IO_FD_CLOSING) < 0)){
01467 LOG(L_CRIT, "ERROR: tcpconn_receive: handle_io: "
01468 "io_watch_del failed for %p id %d fd %d,"
01469 " state %d, flags %x, main fd %d, refcnt %d\n",
01470 con, con->id, con->fd, con->state,
01471 con->flags, con->s, atomic_get(&con->refcnt));
01472 }
01473 tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
01474 local_timer_del(&tcp_reader_ltimer, &con->timer);
01475 if (unlikely(resp!=CONN_EOF))
01476 con->state=S_CONN_BAD;
01477 release_tcpconn(con, resp, tcpmain_sock);
01478 }else{
01479 #ifdef USE_TLS
01480 if (unlikely(read_flags & RD_CONN_REPEAT_READ))
01481 goto repeat_read;
01482 #endif
01483
01484 con->timeout=get_ticks_raw()+S_TO_TICKS(TCP_CHILD_TIMEOUT);
01485
01486
01487 ret&=(((read_flags & RD_CONN_SHORT_READ) &&
01488 !(events & POLLPRI)) - 1);
01489 }
01490 break;
01491 case F_NONE:
01492 LOG(L_CRIT, "BUG: handle_io: empty fd map %p (%d): "
01493 "{%d, %d, %p}\n", fm, (int)(fm-io_w.fd_hash),
01494 fm->fd, fm->type, fm->data);
01495 goto error;
01496 default:
01497 LOG(L_CRIT, "BUG: handle_io: uknown fd type %d\n", fm->type);
01498 goto error;
01499 }
01500
01501 return ret;
01502 con_error:
01503 con->state=S_CONN_BAD;
01504 release_tcpconn(con, CONN_ERROR, tcpmain_sock);
01505 return ret;
01506 error:
01507 return -1;
01508 }
01509
01510
01511
01512 inline static void tcp_reader_timer_run(void)
01513 {
01514 ticks_t ticks;
01515
01516 ticks=get_ticks_raw();
01517 if (unlikely((ticks-tcp_reader_prev_ticks)<TCPCONN_TIMEOUT_MIN_RUN))
01518 return;
01519 tcp_reader_prev_ticks=ticks;
01520 local_timer_run(&tcp_reader_ltimer, ticks);
01521 }
01522
01523
01524
01525 void tcp_receive_loop(int unix_sock)
01526 {
01527
01528
01529 tcpmain_sock=unix_sock;
01530 if (init_io_wait(&io_w, get_max_open_fds(), tcp_poll_method)<0)
01531 goto error;
01532 tcp_reader_prev_ticks=get_ticks_raw();
01533 if (init_local_timer(&tcp_reader_ltimer, get_ticks_raw())!=0)
01534 goto error;
01535
01536 if (io_watch_add(&io_w, tcpmain_sock, POLLIN, F_TCPMAIN, 0)<0){
01537 LOG(L_CRIT, "ERROR: tcp_receive_loop: init: failed to add socket "
01538 " to the fd list\n");
01539 goto error;
01540 }
01541
01542
01543 if (cfg_child_init()) goto error;
01544
01545
01546 switch(io_w.poll_method){
01547 case POLL_POLL:
01548 while(1){
01549 io_wait_loop_poll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
01550 tcp_reader_timer_run();
01551 }
01552 break;
01553 #ifdef HAVE_SELECT
01554 case POLL_SELECT:
01555 while(1){
01556 io_wait_loop_select(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
01557 tcp_reader_timer_run();
01558 }
01559 break;
01560 #endif
01561 #ifdef HAVE_SIGIO_RT
01562 case POLL_SIGIO_RT:
01563 while(1){
01564 io_wait_loop_sigio_rt(&io_w, TCP_CHILD_SELECT_TIMEOUT);
01565 tcp_reader_timer_run();
01566 }
01567 break;
01568 #endif
01569 #ifdef HAVE_EPOLL
01570 case POLL_EPOLL_LT:
01571 while(1){
01572 io_wait_loop_epoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
01573 tcp_reader_timer_run();
01574 }
01575 break;
01576 case POLL_EPOLL_ET:
01577 while(1){
01578 io_wait_loop_epoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 1);
01579 tcp_reader_timer_run();
01580 }
01581 break;
01582 #endif
01583 #ifdef HAVE_KQUEUE
01584 case POLL_KQUEUE:
01585 while(1){
01586 io_wait_loop_kqueue(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
01587 tcp_reader_timer_run();
01588 }
01589 break;
01590 #endif
01591 #ifdef HAVE_DEVPOLL
01592 case POLL_DEVPOLL:
01593 while(1){
01594 io_wait_loop_devpoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0);
01595 tcp_reader_timer_run();
01596 }
01597 break;
01598 #endif
01599 default:
01600 LOG(L_CRIT, "BUG: tcp_receive_loop: no support for poll method "
01601 " %s (%d)\n",
01602 poll_method_name(io_w.poll_method), io_w.poll_method);
01603 goto error;
01604 }
01605 error:
01606 destroy_io_wait(&io_w);
01607 LOG(L_CRIT, "ERROR: tcp_receive_loop: exiting...");
01608 exit(-1);
01609 }
01610
01611
01612
01613 #ifdef USE_STUN
01614 int is_msg_complete(struct tcp_req* r)
01615 {
01616 if (TCP_REQ_HAS_CLEN(r)) {
01617 r->state = H_STUN_FP;
01618 return 0;
01619 }
01620 else {
01621
01622 r->state = H_STUN_END;
01623 r->flags |= F_TCP_REQ_COMPLETE |
01624 F_TCP_REQ_HAS_CLEN;
01625 return 1;
01626 }
01627 }
01628 #endif
01629
01630 #endif