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
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #ifdef USE_TCP
00067
00068
00069 #include <sys/time.h>
00070 #include <sys/types.h>
00071 #include <sys/select.h>
00072 #include <sys/socket.h>
00073 #include <netinet/in.h>
00074 #include <netinet/in_systm.h>
00075 #include <netinet/ip.h>
00076 #include <netinet/tcp.h>
00077 #include <sys/uio.h>
00078 #include <netdb.h>
00079 #include <stdlib.h>
00080
00081 #include <unistd.h>
00082
00083 #include <errno.h>
00084 #include <string.h>
00085
00086 #ifdef HAVE_SELECT
00087 #include <sys/select.h>
00088 #endif
00089 #include <sys/poll.h>
00090
00091
00092 #include "ip_addr.h"
00093 #include "pass_fd.h"
00094 #include "tcp_conn.h"
00095 #include "globals.h"
00096 #include "pt.h"
00097 #include "locking.h"
00098 #include "mem/mem.h"
00099 #include "mem/shm_mem.h"
00100 #include "timer.h"
00101 #include "sr_module.h"
00102 #include "tcp_server.h"
00103 #include "tcp_init.h"
00104 #include "tsend.h"
00105 #include "ut.h"
00106 #ifdef USE_TLS
00107 #include "tls/tls_server.h"
00108 #endif
00109
00110 #define local_malloc pkg_malloc
00111 #define local_free pkg_free
00112
00113 #define HANDLE_IO_INLINE
00114 #include "io_wait.h"
00115 #include <fcntl.h>
00116
00117
00118
00119 enum fd_types { F_NONE, F_SOCKINFO ,
00120 F_TCPCONN , F_TCPCHILD ,
00121 F_PROC };
00122
00123 struct tcp_child {
00124 pid_t pid;
00125 int proc_no;
00126 int unix_sock;
00127 int busy;
00128 int n_reqs;
00129 };
00130
00131
00132 int tcp_accept_aliases=0;
00133 int tcp_connect_timeout=DEFAULT_TCP_CONNECT_TIMEOUT;
00134 int tcp_send_timeout=DEFAULT_TCP_SEND_TIMEOUT;
00135 int tcp_con_lifetime=DEFAULT_TCP_CONNECTION_LIFETIME;
00136 enum poll_types tcp_poll_method=0;
00137 int tcp_max_connections=DEFAULT_TCP_MAX_CONNECTIONS;
00138 int tcp_max_fd_no=0;
00139
00140 static int tcp_connections_no=0;
00141
00142
00143 struct tcp_conn_alias** tcpconn_aliases_hash=0;
00144
00145 struct tcp_connection** tcpconn_id_hash=0;
00146 gen_lock_t* tcpconn_lock=0;
00147
00148
00149 struct tcp_child *tcp_children=0;
00150 static int* connection_id=0;
00151
00152 int unix_tcp_sock = -1;
00153
00154 static int tcp_proto_no=-1;
00155
00156 static io_wait_h io_h;
00157
00158
00159
00160
00161
00162 static int init_sock_opt(int s)
00163 {
00164 int flags;
00165 int optval;
00166
00167 #ifdef DISABLE_NAGLE
00168 flags=1;
00169 if ( (tcp_proto_no!=-1) && (setsockopt(s, tcp_proto_no , TCP_NODELAY,
00170 &flags, sizeof(flags))<0) ){
00171 LM_WARN("could not disable Nagle: %s\n", strerror(errno));
00172 }
00173 #endif
00174
00175 optval = tos;
00176 if (setsockopt(s, IPPROTO_IP, IP_TOS, (void*)&optval,sizeof(optval)) ==-1){
00177 LM_WARN("setsockopt tos: %s\n", strerror(errno));
00178
00179 }
00180
00181 flags=fcntl(s, F_GETFL);
00182 if (flags==-1){
00183 LM_ERR("fnctl failed: (%d) %s\n", errno, strerror(errno));
00184 goto error;
00185 }
00186 if (fcntl(s, F_SETFL, flags|O_NONBLOCK)==-1){
00187 LM_ERR("set non-blocking failed: (%d) %s\n", errno, strerror(errno));
00188 goto error;
00189 }
00190 return 0;
00191 error:
00192 return -1;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202 static int tcp_blocking_connect(int fd, const struct sockaddr *servaddr, socklen_t addrlen)
00203 {
00204 int n;
00205 #if defined(HAVE_SELECT) && defined(BLOCKING_USE_SELECT)
00206 fd_set sel_set;
00207 fd_set orig_set;
00208 struct timeval timeout;
00209 #else
00210 struct pollfd pf;
00211 #endif
00212 int elapsed;
00213 int to;
00214 int ticks;
00215 int err;
00216 unsigned int err_len;
00217 int poll_err;
00218
00219 poll_err=0;
00220 to=tcp_connect_timeout;
00221 ticks=get_ticks();
00222 again:
00223 n=connect(fd, servaddr, addrlen);
00224 if (n==-1){
00225 if (errno==EINTR){
00226 elapsed=(get_ticks()-ticks)*TIMER_TICK;
00227 if (elapsed<to) goto again;
00228 else goto error_timeout;
00229 }
00230 if (errno!=EINPROGRESS && errno!=EALREADY){
00231 LM_ERR("(%d) %s\n", errno, strerror(errno));
00232 goto error;
00233 }
00234 }else goto end;
00235
00236
00237 #if defined(HAVE_SELECT) && defined(BLOCKING_USE_SELECT)
00238 FD_ZERO(&orig_set);
00239 FD_SET(fd, &orig_set);
00240 #else
00241 pf.fd=fd;
00242 pf.events=POLLOUT;
00243 #endif
00244 while(1){
00245 elapsed=(get_ticks()-ticks)*TIMER_TICK;
00246 if (elapsed<to)
00247 to-=elapsed;
00248 else
00249 goto error_timeout;
00250 #if defined(HAVE_SELECT) && defined(BLOCKING_USE_SELECT)
00251 sel_set=orig_set;
00252 timeout.tv_sec=to;
00253 timeout.tv_usec=0;
00254 n=select(fd+1, 0, &sel_set, 0, &timeout);
00255 #else
00256 n=poll(&pf, 1, to*1000);
00257 #endif
00258 if (n<0){
00259 if (errno==EINTR) continue;
00260 LM_ERR("poll/select failed: (%d) %s\n", errno, strerror(errno));
00261 goto error;
00262 }else if (n==0) continue;
00263 #if defined(HAVE_SELECT) && defined(BLOCKING_USE_SELECT)
00264 if (FD_ISSET(fd, &sel_set))
00265 #else
00266 if (pf.revents&(POLLERR|POLLHUP|POLLNVAL)){
00267 LM_ERR("poll error: flags %x\n", pf.revents);
00268 poll_err=1;
00269 }
00270 #endif
00271 {
00272 err_len=sizeof(err);
00273 getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &err_len);
00274 if ((err==0) && (poll_err==0)) goto end;
00275 if (err!=EINPROGRESS && err!=EALREADY){
00276 LM_ERR("failed to retrieve SO_ERROR (%d) %s\n", err,
00277 strerror(err));
00278 goto error;
00279 }
00280 }
00281 }
00282 error_timeout:
00283
00284 LM_ERR("timeout %d s elapsed from %d s\n", elapsed, tcp_connect_timeout);
00285 error:
00286 return -1;
00287 end:
00288 return 0;
00289 }
00290
00291
00292
00293
00294
00295 struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su,
00296 struct socket_info* ba, int type,
00297 int state)
00298 {
00299 struct tcp_connection *c;
00300
00301 c=(struct tcp_connection*)shm_malloc(sizeof(struct tcp_connection));
00302 if (c==0){
00303 LM_ERR("shared memory allocation failure\n");
00304 goto error;
00305 }
00306 memset(c, 0, sizeof(struct tcp_connection));
00307 c->s=sock;
00308 c->fd=-1;
00309 if (lock_init(&c->write_lock)==0){
00310 LM_ERR("init lock failed\n");
00311 goto error;
00312 }
00313
00314 c->rcv.src_su=*su;
00315
00316 c->refcnt=0;
00317 su2ip_addr(&c->rcv.src_ip, su);
00318 c->rcv.src_port=su_getport(su);
00319 c->rcv.bind_address=ba;
00320 if (ba){
00321 c->rcv.dst_ip=ba->address;
00322 c->rcv.dst_port=ba->port_no;
00323 }
00324 print_ip("tcpconn_new: new tcp connection to: ", &c->rcv.src_ip, "\n");
00325 LM_DBG("on port %d, type %d\n", c->rcv.src_port, type);
00326 init_tcp_req(&c->req);
00327 c->id=(*connection_id)++;
00328 c->rcv.proto_reserved1=0;
00329 c->rcv.proto_reserved2=0;
00330 c->state=state;
00331 c->extra_data=0;
00332 #ifdef USE_TLS
00333 if (type==PROTO_TLS){
00334 if (tls_tcpconn_init(c, sock)==-1) goto error;
00335 }else
00336 #endif
00337 {
00338 c->type=PROTO_TCP;
00339 c->rcv.proto=PROTO_TCP;
00340 c->timeout=get_ticks()+tcp_con_lifetime;
00341 }
00342 c->flags|=F_CONN_REMOVED;
00343
00344 tcp_connections_no++;
00345 return c;
00346
00347 error:
00348 if (c) shm_free(c);
00349 return 0;
00350 }
00351
00352
00353
00354
00355
00356 struct tcp_connection* tcpconn_connect(struct socket_info* send_sock,
00357 union sockaddr_union* server, int type)
00358 {
00359 int s;
00360 union sockaddr_union my_name;
00361 socklen_t my_name_len;
00362 struct tcp_connection* con;
00363
00364 s=socket(AF2PF(server->s.sa_family), SOCK_STREAM, 0);
00365 if (s==-1){
00366 LM_ERR("socket: (%d) %s\n", errno, strerror(errno));
00367 goto error;
00368 }
00369 if (init_sock_opt(s)<0){
00370 LM_ERR("init_sock_opt failed\n");
00371 goto error;
00372 }
00373 my_name_len = sockaddru_len(send_sock->su);
00374 memcpy( &my_name, &send_sock->su, my_name_len);
00375 su_setport( &my_name, 0);
00376 if (bind(s, &my_name.s, my_name_len )!=0) {
00377 LM_ERR("bind failed (%d) %s\n", errno,strerror(errno));
00378 goto error;
00379 }
00380
00381 if (tcp_blocking_connect(s, &server->s, sockaddru_len(*server))<0){
00382 LM_ERR("tcp_blocking_connect failed\n");
00383 goto error;
00384 }
00385 con=tcpconn_new(s, server, send_sock, type, S_CONN_CONNECT);
00386 if (con==0){
00387 LM_ERR("tcpconn_new failed, closing the socket\n");
00388 goto error;
00389 }
00390 return con;
00391
00392 error:
00393 if (s!=-1) close(s);
00394 return 0;
00395 }
00396
00397
00398
00399
00400
00401 struct tcp_connection* tcpconn_add(struct tcp_connection *c)
00402 {
00403 unsigned hash;
00404
00405 if (c){
00406 TCPCONN_LOCK;
00407
00408 hash=tcp_id_hash(c->id);
00409 c->id_hash=hash;
00410 tcpconn_listadd(tcpconn_id_hash[hash], c, id_next, id_prev);
00411
00412 hash=tcp_addr_hash(&c->rcv.src_ip, c->rcv.src_port);
00413
00414 c->con_aliases[0].port=c->rcv.src_port;
00415 c->con_aliases[0].hash=hash;
00416 c->con_aliases[0].parent=c;
00417 tcpconn_listadd(tcpconn_aliases_hash[hash], &c->con_aliases[0],
00418 next, prev);
00419 c->aliases++;
00420 TCPCONN_UNLOCK;
00421 LM_DBG("hashes: %d, %d\n", hash, c->id_hash);
00422 return c;
00423 }else{
00424 LM_CRIT("null connection pointer\n");
00425 return 0;
00426 }
00427 }
00428
00429
00430
00431 void _tcpconn_rm(struct tcp_connection* c)
00432 {
00433 int r;
00434 tcpconn_listrm(tcpconn_id_hash[c->id_hash], c, id_next, id_prev);
00435
00436 for (r=0; r<c->aliases; r++)
00437 tcpconn_listrm(tcpconn_aliases_hash[c->con_aliases[r].hash],
00438 &c->con_aliases[r], next, prev);
00439 lock_destroy(&c->write_lock);
00440 #ifdef USE_TLS
00441 if (c->type==PROTO_TLS) tls_tcpconn_clean(c);
00442 #endif
00443 shm_free(c);
00444 }
00445
00446
00447
00448
00449
00450 void tcpconn_rm(struct tcp_connection* c)
00451 {
00452 int r;
00453 TCPCONN_LOCK;
00454 tcpconn_listrm(tcpconn_id_hash[c->id_hash], c, id_next, id_prev);
00455
00456 for (r=0; r<c->aliases; r++)
00457 tcpconn_listrm(tcpconn_aliases_hash[c->con_aliases[r].hash],
00458 &c->con_aliases[r], next, prev);
00459 TCPCONN_UNLOCK;
00460 lock_destroy(&c->write_lock);
00461 #ifdef USE_TLS
00462 if ((c->type==PROTO_TLS)&&(c->extra_data)) tls_tcpconn_clean(c);
00463 #endif
00464 shm_free(c);
00465 }
00466
00467
00468
00469
00470
00471 struct tcp_connection* _tcpconn_find(int id, struct ip_addr* ip, int port, struct ip_addr* send_ip)
00472 {
00473
00474 struct tcp_connection *c;
00475 struct tcp_conn_alias* a;
00476 unsigned hash;
00477
00478 #ifdef EXTRA_DEBUG
00479 LM_DBG("%d port %d\n",id, port);
00480 if (ip) print_ip("tcpconn_find: ip ", ip, "\n");
00481 #endif
00482 if (id){
00483 hash=tcp_id_hash(id);
00484 for (c=tcpconn_id_hash[hash]; c; c=c->id_next){
00485 #ifdef EXTRA_DEBUG
00486 LM_DBG("c=%p, c->id=%d, port=%d\n",c, c->id, c->rcv.src_port);
00487 print_ip("ip=", &c->rcv.src_ip, "\n");
00488 #endif
00489 if ((id==c->id)&&(c->state!=S_CONN_BAD)) return c;
00490 }
00491 }else if (ip){
00492 hash=tcp_addr_hash(ip, port);
00493 for (a=tcpconn_aliases_hash[hash]; a; a=a->next){
00494 #ifdef EXTRA_DEBUG
00495 LM_DBG("a=%p, c=%p, c->id=%d, alias port= %d port=%d\n",
00496 a, a->parent, a->parent->id, a->port, a->parent->rcv.src_port);
00497 print_ip("ip=",&a->parent->rcv.src_ip,"\n");
00498 #endif
00499 if ( (a->parent->state!=S_CONN_BAD) && (port==a->port) &&
00500 (ip_addr_cmp(ip, &a->parent->rcv.src_ip))
00501 && (send_ip==NULL
00502 || ip_addr_cmp(send_ip, &a->parent->rcv.dst_ip)) )
00503 return a->parent;
00504 }
00505 }
00506 return 0;
00507 }
00508
00509
00510
00511
00512 struct tcp_connection* tcpconn_get(int id, struct ip_addr* ip, int port,
00513 int timeout, struct ip_addr* send_ip)
00514 {
00515 struct tcp_connection* c;
00516 TCPCONN_LOCK;
00517 c=_tcpconn_find(id, ip, port, send_ip);
00518 if (c) {
00519 c->refcnt++;
00520 c->timeout=get_ticks()+timeout;
00521 }
00522 TCPCONN_UNLOCK;
00523 return c;
00524 }
00525
00526
00527
00528
00529
00530 int tcpconn_add_alias(int id, int port, int proto)
00531 {
00532 struct tcp_connection* c;
00533 unsigned hash;
00534 struct tcp_conn_alias* a;
00535
00536 a=0;
00537
00538 port=port?port:((proto==PROTO_TLS)?SIPS_PORT:SIP_PORT);
00539 TCPCONN_LOCK;
00540
00541 c=_tcpconn_find(id, 0, 0, 0);
00542 if (c){
00543 hash=tcp_addr_hash(&c->rcv.src_ip, port);
00544
00545 for (a=tcpconn_aliases_hash[hash]; a; a=a->next){
00546 if ( (a->parent->state!=S_CONN_BAD) && (port==a->port) &&
00547 (ip_addr_cmp(&c->rcv.src_ip, &a->parent->rcv.src_ip)) ){
00548
00549 if (a->parent!=c) goto error_sec;
00550 else goto ok;
00551 }
00552 }
00553 if (c->aliases>=TCP_CON_MAX_ALIASES) goto error_aliases;
00554 c->con_aliases[c->aliases].parent=c;
00555 c->con_aliases[c->aliases].port=port;
00556 c->con_aliases[c->aliases].hash=hash;
00557 tcpconn_listadd(tcpconn_aliases_hash[hash],
00558 &c->con_aliases[c->aliases], next, prev);
00559 c->aliases++;
00560 }else goto error_not_found;
00561 ok:
00562 TCPCONN_UNLOCK;
00563 #ifdef EXTRA_DEBUG
00564 if (a) LM_DBG("alias already present\n");
00565 else LM_DBG("alias port %d for hash %d, id %d\n", port, hash, c->id);
00566 #endif
00567 return 0;
00568 error_aliases:
00569 TCPCONN_UNLOCK;
00570 LM_ERR("too many aliases for connection %p (%d)\n", c, c->id);
00571 return -1;
00572 error_not_found:
00573 TCPCONN_UNLOCK;
00574 LM_ERR("no connection found for id %d\n",id);
00575 return -1;
00576 error_sec:
00577 TCPCONN_UNLOCK;
00578 LM_ERR("possible port hijack attempt\n");
00579 LM_ERR("alias already present and points to another connection "
00580 "(%d : %d and %d : %d)\n", a->parent->id, port, c->id, port);
00581 return -1;
00582 }
00583
00584
00585
00586 void tcpconn_ref(struct tcp_connection* c)
00587 {
00588 TCPCONN_LOCK;
00589 c->refcnt++;
00590 TCPCONN_UNLOCK;
00591 }
00592
00593
00594
00595 void tcpconn_put(struct tcp_connection* c)
00596 {
00597 TCPCONN_LOCK;
00598 c->refcnt--;
00599 TCPCONN_UNLOCK;
00600 }
00601
00602
00603
00604
00605 int tcp_send(struct socket_info* send_sock, int type, char* buf, unsigned len,
00606 union sockaddr_union* to, int id)
00607 {
00608 struct tcp_connection *c;
00609 struct tcp_connection *tmp;
00610 struct ip_addr ip;
00611 int port;
00612 int fd;
00613 long response[2];
00614 int n;
00615
00616 port=0;
00617 if (to){
00618 su2ip_addr(&ip, to);
00619 port=su_getport(to);
00620 c=tcpconn_get(id, &ip, port, tcp_con_lifetime, (send_sock)?&(send_sock->address):0);
00621 }else if (id){
00622 c=tcpconn_get(id, 0, 0, tcp_con_lifetime, (send_sock)?&(send_sock->address):0);
00623 }else{
00624 LM_CRIT("tcp_send called with null id & to\n");
00625 return -1;
00626 }
00627
00628 if (id){
00629 if (c==0) {
00630 if (to){
00631
00632 c=tcpconn_get(0, &ip, port, tcp_con_lifetime, (send_sock)?&(send_sock->address):0);
00633 goto no_id;
00634 }else{
00635 LM_ERR("id %d not found, dropping\n", id);
00636 return -1;
00637 }
00638 }else goto get_fd;
00639 }
00640 no_id:
00641 if (c==0){
00642 LM_DBG("no open tcp connection found, opening new one\n");
00643
00644 if ((c=tcpconn_connect(send_sock, to, type))==0){
00645 LM_ERR("connect failed\n");
00646 return -1;
00647 }
00648 c->refcnt++;
00649
00650 fd=c->s;
00651
00652
00653 response[0]=(long)c;
00654 response[1]=CONN_NEW;
00655 n=send_fd(unix_tcp_sock, response, sizeof(response), c->s);
00656 if (n<=0){
00657 LM_ERR("failed send_fd: %s (%d)\n", strerror(errno), errno);
00658 n=-1;
00659 goto end;
00660 }
00661 goto send_it;
00662 }
00663 get_fd:
00664
00665
00666 LM_DBG("tcp connection found (%p), acquiring fd\n", c);
00667
00668 response[0]=(long)c;
00669 response[1]=CONN_GET_FD;
00670 n=send_all(unix_tcp_sock, response, sizeof(response));
00671 if (n<=0){
00672 LM_ERR("failed to get fd(write):%s (%d)\n",
00673 strerror(errno), errno);
00674 n=-1;
00675 goto release_c;
00676 }
00677 LM_DBG("c= %p, n=%d\n", c, n);
00678 tmp=c;
00679 n=receive_fd(unix_tcp_sock, &c, sizeof(c), &fd, MSG_WAITALL);
00680 if (n<=0){
00681 LM_ERR("failed to get fd(receive_fd):"
00682 " %s (%d)\n", strerror(errno), errno);
00683 n=-1;
00684 goto release_c;
00685 }
00686 if (c!=tmp){
00687 LM_CRIT("got different connection:"
00688 " %p (id= %d, refcnt=%d state=%d != "
00689 " %p (id= %d, refcnt=%d state=%d (n=%d)\n",
00690 c, c->id, c->refcnt, c->state,
00691 tmp, tmp->id, tmp->refcnt, tmp->state, n
00692 );
00693 n=-1;
00694 goto end;
00695 }
00696 LM_DBG("after receive_fd: c= %p n=%d fd=%d\n",c, n, fd);
00697
00698
00699
00700 send_it:
00701 LM_DBG("sending...\n");
00702 lock_get(&c->write_lock);
00703 #ifdef USE_TLS
00704 if (c->type==PROTO_TLS)
00705 n=tls_blocking_write(c, fd, buf, len);
00706 else
00707 #endif
00708
00709 n=tsend_stream(fd, buf, len, tcp_send_timeout*1000);
00710 lock_release(&c->write_lock);
00711 LM_DBG("after write: c= %p n=%d fd=%d\n",c, n, fd);
00712 LM_DBG("buf=\n%.*s\n", (int)len, buf);
00713 if (n<0){
00714 LM_ERR("failed to send\n");
00715
00716 c->state=S_CONN_BAD;
00717 c->timeout=0;
00718
00719 response[0]=(long)c;
00720 response[1]=CONN_ERROR;
00721 n=send_all(unix_tcp_sock, response, sizeof(response));
00722
00723 if (n<=0){
00724 LM_ERR("return failed (write):%s (%d)\n",
00725 strerror(errno), errno);
00726 }
00727 close(fd);
00728 return -1;
00729 }
00730 end:
00731 close(fd);
00732 release_c:
00733 tcpconn_put(c);
00734 return n;
00735 }
00736
00737
00738
00739
00740
00741 int tcp_init(struct socket_info* sock_info)
00742 {
00743 union sockaddr_union* addr;
00744 int optval;
00745 #ifdef DISABLE_NAGLE
00746 int flag;
00747 struct protoent* pe;
00748
00749 if (tcp_proto_no==-1){
00750 pe=getprotobyname("tcp");
00751 if (pe==0){
00752 LM_ERR("could not get TCP protocol number\n");
00753 tcp_proto_no=-1;
00754 }else{
00755 tcp_proto_no=pe->p_proto;
00756 }
00757 }
00758 #endif
00759
00760 addr=&sock_info->su;
00761
00762 if (init_su(addr, &sock_info->address, sock_info->port_no)<0){
00763 LM_ERR("could no init sockaddr_union\n");
00764 goto error;
00765 }
00766 sock_info->socket=socket(AF2PF(addr->s.sa_family), SOCK_STREAM, 0);
00767 if (sock_info->socket==-1){
00768 LM_ERR("socket: %s\n", strerror(errno));
00769 goto error;
00770 }
00771 #ifdef DISABLE_NAGLE
00772 flag=1;
00773 if ( (tcp_proto_no!=-1) &&
00774 (setsockopt(sock_info->socket, tcp_proto_no , TCP_NODELAY,
00775 &flag, sizeof(flag))<0) ){
00776 LM_ERR("could not disable Nagle: %s\n", strerror(errno));
00777 }
00778 #endif
00779
00780
00781 #if !defined(TCP_DONT_REUSEADDR)
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791 optval=1;
00792 if (setsockopt(sock_info->socket, SOL_SOCKET, SO_REUSEADDR,
00793 (void*)&optval, sizeof(optval))==-1) {
00794 LM_ERR("setsockopt %s\n", strerror(errno));
00795 goto error;
00796 }
00797 #endif
00798
00799 optval = tos;
00800 if (setsockopt(sock_info->socket, IPPROTO_IP, IP_TOS, (void*)&optval,
00801 sizeof(optval)) ==-1){
00802 LM_WARN("setsockopt tos: %s\n", strerror(errno));
00803
00804 }
00805 if (bind(sock_info->socket, &addr->s, sockaddru_len(*addr))==-1){
00806 LM_ERR("bind(%x, %p, %d) on %s:%d : %s\n",
00807 sock_info->socket, &addr->s,
00808 (unsigned)sockaddru_len(*addr),
00809 sock_info->address_str.s,
00810 sock_info->port_no,
00811 strerror(errno));
00812 goto error;
00813 }
00814 if (listen(sock_info->socket, 10)==-1){
00815 LM_ERR("listen(%x, %p, %d) on %s: %s\n",
00816 sock_info->socket, &addr->s,
00817 (unsigned)sockaddru_len(*addr),
00818 sock_info->address_str.s,
00819 strerror(errno));
00820 goto error;
00821 }
00822
00823 return 0;
00824 error:
00825 if (sock_info->socket!=-1){
00826 close(sock_info->socket);
00827 sock_info->socket=-1;
00828 }
00829 return -1;
00830 }
00831
00832
00833
00834
00835
00836
00837
00838
00839 static int send2child(struct tcp_connection* tcpconn)
00840 {
00841 int i;
00842 int min_busy;
00843 int idx;
00844
00845 min_busy=tcp_children[0].busy;
00846 idx=0;
00847 for (i=0; i<tcp_children_no; i++){
00848 if (!tcp_children[i].busy){
00849 idx=i;
00850 min_busy=0;
00851 break;
00852 }else if (min_busy>tcp_children[i].busy){
00853 min_busy=tcp_children[i].busy;
00854 idx=i;
00855 }
00856 }
00857
00858 tcp_children[idx].busy++;
00859 tcp_children[idx].n_reqs++;
00860 if (min_busy){
00861 LM_WARN("no free tcp receiver, connection passed to the least"
00862 "busy one (%d)\n", min_busy);
00863 }
00864 LM_DBG("to tcp child %d %d(%d), %p\n", idx, tcp_children[idx].proc_no,
00865 tcp_children[idx].pid, tcpconn);
00866 if (send_fd(tcp_children[idx].unix_sock, &tcpconn, sizeof(tcpconn),
00867 tcpconn->s)<=0){
00868 LM_ERR("send_fd failed\n");
00869 return -1;
00870 }
00871
00872 return 0;
00873 }
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884 static inline int handle_new_connect(struct socket_info* si)
00885 {
00886 union sockaddr_union su;
00887 struct tcp_connection* tcpconn;
00888 socklen_t su_len;
00889 int new_sock;
00890
00891
00892 su_len=sizeof(su);
00893 new_sock=accept(si->socket, &(su.s), &su_len);
00894 if (new_sock==-1){
00895 if ((errno==EAGAIN)||(errno==EWOULDBLOCK))
00896 return 0;
00897 LM_ERR("failed to accept connection(%d): %s\n", errno, strerror(errno));
00898 return -1;
00899 }
00900 if (tcp_connections_no>=tcp_max_connections){
00901 LM_ERR("maximum number of connections exceeded: %d/%d\n",
00902 tcp_connections_no, tcp_max_connections);
00903 close(new_sock);
00904 return 1;
00905 }
00906 if (init_sock_opt(new_sock)<0){
00907 LM_ERR("init_sock_opt failed\n");
00908 close(new_sock);
00909 return 1;
00910 }
00911
00912
00913 tcpconn=tcpconn_new(new_sock, &su, si, si->proto, S_CONN_ACCEPT);
00914 if (tcpconn){
00915 tcpconn->refcnt++;
00916
00917 tcpconn_add(tcpconn);
00918 LM_DBG("new connection: %p %d flags: %04x\n",
00919 tcpconn, tcpconn->s, tcpconn->flags);
00920
00921 if(send2child(tcpconn)<0){
00922 LM_ERR("no children available\n");
00923 TCPCONN_LOCK;
00924 tcpconn->refcnt--;
00925 if (tcpconn->refcnt==0){
00926 close(tcpconn->s);
00927 _tcpconn_rm(tcpconn);
00928 }else tcpconn->timeout=0;
00929 TCPCONN_UNLOCK;
00930 }
00931 }else{
00932 LM_ERR("tcpconn_new failed, closing socket\n");
00933 close(new_sock);
00934
00935 }
00936 return 1;
00937 }
00938
00939
00940
00941
00942 static void tcpconn_destroy(struct tcp_connection* tcpconn)
00943 {
00944 int fd;
00945
00946 TCPCONN_LOCK;
00947 tcpconn->refcnt--;
00948 if (tcpconn->refcnt==0){
00949 LM_DBG("destroying connection %p, flags %04x\n",
00950 tcpconn, tcpconn->flags);
00951 fd=tcpconn->s;
00952 #ifdef USE_TLS
00953
00954 if (tcpconn->type==PROTO_TLS)
00955 tls_close(tcpconn, fd);
00956 #endif
00957 _tcpconn_rm(tcpconn);
00958 close(fd);
00959 tcp_connections_no--;
00960 }else{
00961
00962 tcpconn->timeout=0;
00963 tcpconn->state=S_CONN_BAD;
00964 LM_DBG("delaying (%p, flags %04x) ...\n",
00965 tcpconn, tcpconn->flags);
00966
00967 }
00968 TCPCONN_UNLOCK;
00969 }
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984 inline static int handle_tcpconn_ev(struct tcp_connection* tcpconn, int fd_i)
00985 {
00986 int fd;
00987
00988
00989
00990
00991
00992
00993
00994 #if 0
00995 if ((tcpconn->refcnt!=0)){
00996
00997
00998
00999 LM_CRIT("io event on referenced tcpconn (%p), refcnt=%d, fd=%d\n",
01000 tcpconn, tcpconn->refcnt, tcpconn->s);
01001 return -1;
01002 }
01003 #endif
01004
01005 LM_DBG("data available on %p %d\n", tcpconn, tcpconn->s);
01006 if (io_watch_del(&io_h, tcpconn->s, fd_i, 0)==-1) goto error;
01007 tcpconn->flags|=F_CONN_REMOVED;
01008 tcpconn_ref(tcpconn);
01009 if (send2child(tcpconn)<0){
01010 LM_ERR("no children available\n");
01011 TCPCONN_LOCK;
01012 tcpconn->refcnt--;
01013 if (tcpconn->refcnt==0){
01014 fd=tcpconn->s;
01015 _tcpconn_rm(tcpconn);
01016 close(fd);
01017 }else tcpconn->timeout=0;
01018 TCPCONN_UNLOCK;
01019 }
01020 return 0;
01021
01022 error:
01023 return -1;
01024 }
01025
01026
01027
01028
01029
01030 static inline void set_tcp_timeout(struct tcp_connection *c)
01031 {
01032 unsigned int timeout = get_ticks() + tcp_con_lifetime;
01033
01034 if (c->lifetime) {
01035 if ( c->lifetime < timeout )
01036 c->timeout = timeout;
01037 else
01038 c->timeout = c->lifetime;
01039 c->lifetime = 0;
01040 } else {
01041 c->timeout = timeout;
01042 }
01043 }
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055 inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
01056 {
01057 struct tcp_connection* tcpconn;
01058 long response[2];
01059 int cmd;
01060 int bytes;
01061
01062 if (tcp_c->unix_sock<=0){
01063
01064 LM_CRIT("fd %d for %d (pid %d, ser no %d)\n", tcp_c->unix_sock,
01065 (int)(tcp_c-&tcp_children[0]), tcp_c->pid, tcp_c->proc_no);
01066 goto error;
01067 }
01068
01069
01070 bytes=recv_all(tcp_c->unix_sock, response, sizeof(response), MSG_DONTWAIT);
01071 if (bytes<(int)sizeof(response)){
01072 if (bytes==0){
01073
01074 LM_DBG("dead tcp child %d (pid %d, no %d)"
01075 " (shutting down?)\n", (int)(tcp_c-&tcp_children[0]),
01076 tcp_c->pid, tcp_c->proc_no );
01077
01078 io_watch_del(&io_h, tcp_c->unix_sock, fd_i, 0);
01079 goto error;
01080 }else if (bytes<0){
01081
01082
01083 if ((errno!=EAGAIN) && (errno!=EWOULDBLOCK)){
01084 LM_CRIT("read from tcp child %ld (pid %d, no %d) %s [%d]\n",
01085 (long)(tcp_c-&tcp_children[0]), tcp_c->pid,
01086 tcp_c->proc_no, strerror(errno), errno );
01087 }else{
01088 bytes=0;
01089 }
01090
01091 goto end;
01092 }else{
01093
01094 LM_CRIT("too few bytes received (%d)\n", bytes );
01095 bytes=0;
01096
01097
01098 goto end;
01099 }
01100 }
01101
01102 LM_DBG("reader response= %lx, %ld from %d \n",
01103 response[0], response[1], (int)(tcp_c-&tcp_children[0]));
01104 cmd=response[1];
01105 tcpconn=(struct tcp_connection*)response[0];
01106 if (tcpconn==0){
01107
01108 LM_CRIT("null tcpconn pointer received from tcp child %d (pid %d):"
01109 "%lx, %lx\n", (int)(tcp_c-&tcp_children[0]), tcp_c->pid,
01110 response[0], response[1]) ;
01111 goto end;
01112 }
01113 switch(cmd){
01114 case CONN_RELEASE:
01115 tcp_c->busy--;
01116 if (tcpconn->state==S_CONN_BAD){
01117 tcpconn_destroy(tcpconn);
01118 break;
01119 }
01120
01121 set_tcp_timeout( tcpconn );
01122 tcpconn_put(tcpconn);
01123
01124 io_watch_add(&io_h, tcpconn->s, F_TCPCONN, tcpconn);
01125 tcpconn->flags&=~F_CONN_REMOVED;
01126 LM_DBG("cmd CONN_RELEASE %p refcnt= %d\n",
01127 tcpconn, tcpconn->refcnt);
01128 break;
01129 case CONN_ERROR:
01130 case CONN_DESTROY:
01131 case CONN_EOF:
01132
01133 tcp_c->busy--;
01134
01135
01136
01137
01138 tcpconn_destroy(tcpconn);
01139 break;
01140 default:
01141 LM_CRIT("unknown cmd %d from tcp reader %d\n",
01142 cmd, (int)(tcp_c-&tcp_children[0]));
01143 }
01144 end:
01145 return bytes;
01146 error:
01147 return -1;
01148 }
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165 inline static int handle_ser_child(struct process_table* p, int fd_i)
01166 {
01167 struct tcp_connection* tcpconn;
01168 long response[2];
01169 int cmd;
01170 int bytes;
01171 int ret;
01172 int fd;
01173
01174 ret=-1;
01175 if (p->unix_sock<=0){
01176
01177 LM_CRIT("fd %d for %d (pid %d)\n",
01178 p->unix_sock, (int)(p-&pt[0]), p->pid);
01179 goto error;
01180 }
01181
01182
01183
01184 bytes=receive_fd(p->unix_sock, response, sizeof(response), &fd,
01185 MSG_DONTWAIT);
01186 if (bytes<(int)sizeof(response)){
01187
01188 if (bytes==0){
01189
01190 LM_DBG("dead child %d, pid %d"
01191 " (shutting down?)\n", (int)(p-&pt[0]), p->pid);
01192
01193 io_watch_del(&io_h, p->unix_sock, fd_i, 0);
01194 goto error;
01195 }else if (bytes<0){
01196
01197
01198 if ((errno!=EAGAIN) && (errno!=EWOULDBLOCK)){
01199 LM_CRIT("read from child %d (pid %d): %s [%d]\n",
01200 (int)(p-&pt[0]), p->pid, strerror(errno), errno);
01201 ret=-1;
01202 }else{
01203 ret=0;
01204 }
01205
01206 goto end;
01207 }else{
01208
01209 LM_CRIT("too few bytes received (%d)\n", bytes );
01210 ret=0;
01211
01212
01213 goto end;
01214 }
01215 }
01216 ret=1;
01217 LM_DBG("read response= %lx, %ld, fd %d from %d (%d)\n",
01218 response[0], response[1], fd, (int)(p-&pt[0]), p->pid);
01219 cmd=response[1];
01220 tcpconn=(struct tcp_connection*)response[0];
01221 if (tcpconn==0){
01222 LM_CRIT("null tcpconn pointer received from child %d (pid %d)"
01223 "%lx, %lx\n", (int)(p-&pt[0]), p->pid, response[0], response[1]) ;
01224 goto end;
01225 }
01226 switch(cmd){
01227 case CONN_ERROR:
01228 if (!(tcpconn->flags & F_CONN_REMOVED) && (tcpconn->s!=-1)){
01229 io_watch_del(&io_h, tcpconn->s, -1, IO_FD_CLOSING);
01230 tcpconn->flags|=F_CONN_REMOVED;
01231 }
01232 tcpconn_destroy(tcpconn);
01233 break;
01234 case CONN_GET_FD:
01235
01236
01237
01238 if (send_fd(p->unix_sock, &tcpconn, sizeof(tcpconn),
01239 tcpconn->s)<=0){
01240 LM_ERR("send_fd failed\n");
01241 }
01242 break;
01243 case CONN_NEW:
01244
01245
01246
01247 if (fd==-1){
01248 LM_CRIT(" cmd CONN_NEW: no fd received\n");
01249 break;
01250 }
01251 tcpconn->s=fd;
01252
01253 tcpconn_add(tcpconn);
01254
01255 tcpconn->timeout=get_ticks()+tcp_con_lifetime;
01256 io_watch_add(&io_h, tcpconn->s, F_TCPCONN, tcpconn);
01257 tcpconn->flags&=~F_CONN_REMOVED;
01258 break;
01259 default:
01260 LM_CRIT("unknown cmd %d\n", cmd);
01261 }
01262 end:
01263 return ret;
01264 error:
01265 return -1;
01266 }
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283 inline static int handle_io(struct fd_map* fm, int idx)
01284 {
01285 int ret;
01286
01287 switch(fm->type){
01288 case F_SOCKINFO:
01289 ret=handle_new_connect((struct socket_info*)fm->data);
01290 break;
01291 case F_TCPCONN:
01292 ret=handle_tcpconn_ev((struct tcp_connection*)fm->data, idx);
01293 break;
01294 case F_TCPCHILD:
01295 ret=handle_tcp_child((struct tcp_child*)fm->data, idx);
01296 break;
01297 case F_PROC:
01298 ret=handle_ser_child((struct process_table*)fm->data, idx);
01299 break;
01300 case F_NONE:
01301 LM_CRIT("empty fd map\n");
01302 goto error;
01303 default:
01304 LM_CRIT("uknown fd type %d\n", fm->type);
01305 goto error;
01306 }
01307 return ret;
01308 error:
01309 return -1;
01310 }
01311
01312
01313
01314
01315
01316
01317
01318
01319 static inline void tcpconn_timeout(int force)
01320 {
01321 struct tcp_connection *c, *next;
01322 unsigned int ticks;
01323 unsigned h;
01324 int fd;
01325
01326
01327 ticks=get_ticks();
01328 TCPCONN_LOCK;
01329 for(h=0; h<TCP_ID_HASH_SIZE; h++){
01330 c=tcpconn_id_hash[h];
01331 while(c){
01332 next=c->id_next;
01333 if (force ||((c->refcnt==0) && (ticks>c->timeout))) {
01334 if (!force)
01335 LM_DBG("timeout for hash=%d - %p"
01336 " (%d > %d)\n", h, c, ticks, c->timeout);
01337 fd=c->s;
01338 #ifdef USE_TLS
01339 if (c->type==PROTO_TLS)
01340 tls_close(c, fd);
01341 #endif
01342 _tcpconn_rm(c);
01343 if ((!force)&&(fd>0)&&(c->refcnt==0)) {
01344 if (!(c->flags & F_CONN_REMOVED)){
01345 io_watch_del(&io_h, fd, -1, IO_FD_CLOSING);
01346 c->flags|=F_CONN_REMOVED;
01347 }
01348 close(fd);
01349 }
01350 tcp_connections_no--;
01351 }
01352 c=next;
01353 }
01354 }
01355 TCPCONN_UNLOCK;
01356 }
01357
01358
01359
01360
01361 void tcp_main_loop(void)
01362 {
01363
01364 struct socket_info* si;
01365 int r;
01366
01367
01368
01369
01370
01371 if (init_io_wait(&io_h, tcp_max_fd_no, tcp_poll_method)<0)
01372 goto error;
01373
01374
01375
01376 for (si=tcp_listen; si; si=si->next){
01377 if ((si->proto==PROTO_TCP) &&(si->socket!=-1)){
01378 if (io_watch_add(&io_h, si->socket, F_SOCKINFO, si)<0){
01379 LM_CRIT("failed to add listen socket to the fd list\n");
01380 goto error;
01381 }
01382 }else{
01383 LM_CRIT("non tcp address in tcp_listen\n");
01384 }
01385 }
01386 #ifdef USE_TLS
01387 if (!tls_disable){
01388 for (si=tls_listen; si; si=si->next){
01389 if ((si->proto==PROTO_TLS) && (si->socket!=-1)){
01390 if (io_watch_add(&io_h, si->socket, F_SOCKINFO, si)<0){
01391 LM_CRIT("failed to add tls listen socket to the fd list\n");
01392 goto error;
01393 }
01394 }else{
01395 LM_CRIT("non tls address in tls_listen\n");
01396 }
01397 }
01398 }
01399 #endif
01400
01401
01402 for (r=1; r<counted_processes; r++){
01403
01404
01405 if (r!=process_no && pt[r].unix_sock>0)
01406 if (io_watch_add(&io_h, pt[r].unix_sock, F_PROC, &pt[r])<0){
01407 LM_CRIT("failed to add process %d (%s) unix socket "
01408 "to the fd list\n", r, pt[r].desc);
01409 goto error;
01410 }
01411 }
01412
01413 for (r=0; r<tcp_children_no; r++){
01414 if (tcp_children[r].unix_sock>0)
01415 if (io_watch_add(&io_h, tcp_children[r].unix_sock, F_TCPCHILD,
01416 &tcp_children[r]) <0){
01417 LM_CRIT("failed to add tcp child %d unix socket to "
01418 "the fd list\n", r);
01419 goto error;
01420 }
01421 }
01422
01423
01424 switch(io_h.poll_method){
01425 case POLL_POLL:
01426 while(1){
01427
01428 io_wait_loop_poll(&io_h, TCP_MAIN_SELECT_TIMEOUT, 0);
01429
01430 tcpconn_timeout(0);
01431 }
01432 break;
01433 #ifdef HAVE_SELECT
01434 case POLL_SELECT:
01435 while(1){
01436 io_wait_loop_select(&io_h, TCP_MAIN_SELECT_TIMEOUT, 0);
01437 tcpconn_timeout(0);
01438 }
01439 break;
01440 #endif
01441 #ifdef HAVE_SIGIO_RT
01442 case POLL_SIGIO_RT:
01443 while(1){
01444 io_wait_loop_sigio_rt(&io_h, TCP_MAIN_SELECT_TIMEOUT);
01445 tcpconn_timeout(0);
01446 }
01447 break;
01448 #endif
01449 #ifdef HAVE_EPOLL
01450 case POLL_EPOLL_LT:
01451 while(1){
01452 io_wait_loop_epoll(&io_h, TCP_MAIN_SELECT_TIMEOUT, 0);
01453 tcpconn_timeout(0);
01454 }
01455 break;
01456 case POLL_EPOLL_ET:
01457 while(1){
01458 io_wait_loop_epoll(&io_h, TCP_MAIN_SELECT_TIMEOUT, 1);
01459 tcpconn_timeout(0);
01460 }
01461 break;
01462 #endif
01463 #ifdef HAVE_KQUEUE
01464 case POLL_KQUEUE:
01465 while(1){
01466 io_wait_loop_kqueue(&io_h, TCP_MAIN_SELECT_TIMEOUT, 0);
01467 tcpconn_timeout(0);
01468 }
01469 break;
01470 #endif
01471 #ifdef HAVE_DEVPOLL
01472 case POLL_DEVPOLL:
01473 while(1){
01474 io_wait_loop_devpoll(&io_h, TCP_MAIN_SELECT_TIMEOUT, 0);
01475 tcpconn_timeout(0);
01476 }
01477 break;
01478 #endif
01479 default:
01480 LM_CRIT("no support for poll method %s (%d)\n",
01481 poll_method_name(io_h.poll_method), io_h.poll_method);
01482 goto error;
01483 }
01484 error:
01485 destroy_io_wait(&io_h);
01486 LM_CRIT("exiting...");
01487 exit(-1);
01488 }
01489
01490
01491
01492
01493 void destroy_tcp(void)
01494 {
01495 if (tcpconn_id_hash){
01496 tcpconn_timeout(1);
01497 shm_free(tcpconn_id_hash);
01498 tcpconn_id_hash=0;
01499 }
01500 if (connection_id){
01501 shm_free(connection_id);
01502 connection_id=0;
01503 }
01504 if (tcpconn_aliases_hash){
01505 shm_free(tcpconn_aliases_hash);
01506 tcpconn_aliases_hash=0;
01507 }
01508 if (tcpconn_lock){
01509 lock_destroy(tcpconn_lock);
01510 lock_dealloc((void*)tcpconn_lock);
01511 tcpconn_lock=0;
01512 }
01513 }
01514
01515
01516
01517
01518
01519
01520
01521
01522 int init_tcp(void)
01523 {
01524 char* poll_err;
01525
01526
01527 tcpconn_lock=lock_alloc();
01528 if (tcpconn_lock==0){
01529 LM_CRIT("could not alloc lock\n");
01530 goto error;
01531 }
01532 if (lock_init(tcpconn_lock)==0){
01533 LM_CRIT("could not init lock\n");
01534 lock_dealloc((void*)tcpconn_lock);
01535 tcpconn_lock=0;
01536 goto error;
01537 }
01538
01539 tcp_children = (struct tcp_child*)pkg_malloc
01540 ( tcp_children_no*sizeof(struct tcp_child) );
01541 if (tcp_children==0) {
01542 LM_CRIT("could not alloc tcp_children array in pkg memory\n");
01543 goto error;
01544 }
01545 memset( tcp_children, 0, tcp_children_no*sizeof(struct tcp_child));
01546
01547 connection_id=(int*)shm_malloc(sizeof(int));
01548 if (connection_id==0){
01549 LM_CRIT("could not alloc globals in shm memory\n");
01550 goto error;
01551 }
01552 *connection_id=1;
01553
01554 tcpconn_aliases_hash=(struct tcp_conn_alias**)
01555 shm_malloc(TCP_ALIAS_HASH_SIZE* sizeof(struct tcp_conn_alias*));
01556 if (tcpconn_aliases_hash==0){
01557 LM_CRIT("could not alloc address hashtable in shm memory\n");
01558 goto error;
01559 }
01560 tcpconn_id_hash=(struct tcp_connection**)shm_malloc(TCP_ID_HASH_SIZE*
01561 sizeof(struct tcp_connection*));
01562 if (tcpconn_id_hash==0){
01563 LM_CRIT("could not alloc id hashtable in shm memory\n");
01564 goto error;
01565 }
01566
01567 memset((void*)tcpconn_aliases_hash, 0,
01568 TCP_ALIAS_HASH_SIZE * sizeof(struct tcp_conn_alias*));
01569 memset((void*)tcpconn_id_hash, 0,
01570 TCP_ID_HASH_SIZE * sizeof(struct tcp_connection*));
01571
01572
01573
01574
01575 poll_err=check_poll_method(tcp_poll_method);
01576
01577
01578 if (poll_err || (tcp_poll_method==0)){
01579 tcp_poll_method=choose_poll_method();
01580 if (poll_err){
01581 LM_ERR("%s, using %s instead\n",
01582 poll_err, poll_method_name(tcp_poll_method));
01583 }else{
01584 LM_INFO("using %s as the TCP io watch method"
01585 " (auto detected)\n", poll_method_name(tcp_poll_method));
01586 }
01587 }else{
01588 LM_INFO("using %s as the TCP io watch method (config)\n",
01589 poll_method_name(tcp_poll_method));
01590 }
01591
01592 return 0;
01593 error:
01594
01595 destroy_tcp();
01596 return -1;
01597 }
01598
01599
01600
01601
01602 int tcp_init_children(int *chd_rank)
01603 {
01604 int r;
01605
01606 int reader_fd[2];
01607 pid_t pid;
01608 struct socket_info *si;
01609
01610
01611
01612
01613
01614 for(r=0, si=tcp_listen; si; si=si->next, r++);
01615 #ifdef USE_TLS
01616 if (! tls_disable)
01617 for (si=tls_listen; si; si=si->next, r++);
01618 #endif
01619
01620 tcp_max_fd_no=counted_processes*2 +r-1 +3;
01621 tcp_max_fd_no+=tcp_max_connections;
01622
01623
01624
01625
01626
01627 for(r=0; r<tcp_children_no; r++){
01628
01629
01630
01631
01632 if (socketpair(AF_UNIX, SOCK_STREAM, 0, reader_fd)<0){
01633 LM_ERR("socketpair failed: %s\n", strerror(errno));
01634 goto error;
01635 }
01636
01637 (*chd_rank)++;
01638 pid=internal_fork("SIP receiver TCP");
01639 if (pid<0){
01640 LM_ERR("fork failed\n");
01641 goto error;
01642 }else if (pid>0){
01643
01644 close(reader_fd[1]);
01645 tcp_children[r].pid=pid;
01646 tcp_children[r].proc_no=process_no;
01647 tcp_children[r].busy=0;
01648 tcp_children[r].n_reqs=0;
01649 tcp_children[r].unix_sock=reader_fd[0];
01650 }else{
01651
01652 set_proc_attrs("TCP receiver");
01653 pt[process_no].idx=r;
01654 bind_address=0;
01655
01656 if (init_child(*chd_rank) < 0) {
01657 LM_ERR("init_children failed\n");
01658 exit(-1);
01659 }
01660 tcp_receive_loop(reader_fd[1]);
01661 exit(-1);
01662 }
01663 }
01664 return 0;
01665 error:
01666 return -1;
01667 }
01668
01669 #endif