/* * $Id$ */ #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "dprint.h" #include "route.h" #include "udp_server.h" #include "globals.h" static char id[]="@(#) $Id$"; static char version[]="sip_router 0.5"; static char help_msg[]= "\ Usage: sip_router -l address [-l address] [options]\n\ Options:\n\ -f file Configuration file (default " CFG_FILE ")\n\ -p port Listen on the specified port (default: 5060)\n\ -l address Listen on the specified address (multiple -l mean\n\ listening on more addresses). The default behaviour\n\ is to listen on the addresses returned by uname(2)\n\ \n\ -n processes Number of child processes to fork per interface\n\ (default: 8)\n\ \n\ -r Use dns to check if is necessary to add a \"received=\"\n\ field to a via\n\ -R Same as `-r´ but use reverse dns;\n\ (to use both use `-rR´)\n\ \n\ -v Turn on \"via:\" host checking when forwarding replies\n\ -d Debugging mode (multiple -d increase the level)\n\ -D Do not fork into daemon mode\n\ -E Log to stderr\n\ -V Version number\n\ -h This help message\n\ "; /* debuging function */ /* void receive_stdin_loop() { #define BSIZE 1024 char buf[BSIZE+1]; int len; while(1){ len=fread(buf,1,BSIZE,stdin); buf[len+1]=0; receive_msg(buf, len); printf("-------------------------\n"); } } */ /* global vars */ char* cfg_file = 0; unsigned short port_no = 0; /* port on which we listen */ int children_no = 0; /* number of children processing requests */ int debug = 0; int dont_fork = 0; int log_stderr = 0; int check_via = 0; /* check if reply first via host==us */ int received_dns = 0; /* use dns and/or rdns or to see if we need to add a ;received=x.x.x.x to via: */ char* names[MAX_LISTEN]; /* our names */ unsigned long addresses[MAX_LISTEN]; /* our ips */ int addresses_no=0; /* number of names/ips */ /* ipc related globals */ int process_no = 0; #ifdef ROUTE_SRV #endif #define MAX_FD 32 /* maximum number of inherited open file descriptors, (normally it shouldn't be bigger than 3) */ extern FILE* yyin; extern int yyparse(); /* daemon init, return 0 on success, -1 on error */ int daemonize(char* name) { pid_t pid; int r; if (log_stderr==0) openlog(name, LOG_PID, LOG_DAEMON); /* LOG_CONS, LOG_PERRROR ? */ if (chdir("/")<0){ LOG(L_CRIT,"cannot chroot:%s\n", strerror(errno)); goto error; } /* fork to become!= group leader*/ if ((pid=fork())<0){ LOG(L_CRIT, "Cannot fork:%s\n", strerror(errno)); goto error; } if (pid!=0){ /* parent process => exit*/ exit(0); } /* become session leader to drop the ctrl. terminal */ if (setsid()<0){ LOG(L_WARN, "setsid failed: %s\n",strerror(errno)); } /* fork again to drop group leadership */ if ((pid=fork())<0){ LOG(L_CRIT, "Cannot fork:%s\n", strerror(errno)); goto error; } if (pid!=0){ /*parent process => exit */ exit(0); } /* close any open file descriptors */ for (r=0;rh_addr_list[0]); printf("%s [%s] : %d\n",names[r], inet_ntoa(*(struct in_addr*)&addresses[r]), (unsigned short)port_no); } /* load config file or die */ cfg_stream=fopen (cfg_file, "r"); if (cfg_stream==0){ fprintf(stderr, "ERROR: loading config file(%s): %s\n", cfg_file, strerror(errno)); goto error; } yyin=cfg_stream; if (yyparse()!=0){ fprintf(stderr, "ERROR: config parser failure\n"); goto error; } print_rl(); /* init_daemon? */ if (!dont_fork){ if ( daemonize(argv[0]) <0 ) goto error; } return main_loop(); error: return -1; }