⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 RTP Proxy,用于Voip网络数据的代理传递
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2004-2006 Maxim Sobolev <sobomax@FreeBSD.org> * Copyright (c) 2006-2007 Sippy Software, Inc., http://www.sippysoft.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: main.c,v 1.71 2008/04/03 20:51:45 sobomax Exp $ * */#include <sys/types.h>#include <sys/time.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/resource.h>#include <sys/un.h>#include <sys/uio.h>#include <ctype.h>#include <sys/select.h>#include <sys/stat.h>#include <assert.h>#include <errno.h>#include <fcntl.h>#include <limits.h>#include <netdb.h>#include <poll.h>#include <sched.h>#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <string.h>#include <strings.h>#include <unistd.h>#include "rtp.h"#include "rtp_resizer.h"#include "rtp_server.h"#include "rtpp_defines.h"#include "rtpp_command.h"#include "rtpp_log.h"#include "rtpp_record.h"#include "rtpp_session.h"#include "rtpp_util.h"static const char *cmd_sock = CMD_SOCK;static const char *pid_file = PID_FILE;static rtpp_log_t glog;static void setbindhost(struct sockaddr *, int, const char *, const char *);static void usage(void);static void send_packet(struct cfg *, struct rtpp_session *, int,  struct rtp_packet *);static voidsetbindhost(struct sockaddr *ia, int pf, const char *bindhost,  const char *servname){    int n;    /*     * If user specified * then change it to NULL,     * that will make getaddrinfo to return addr_any socket     */    if (bindhost && (strcmp(bindhost, "*") == 0))	bindhost = NULL;    if ((n = resolve(ia, pf, bindhost, servname, AI_PASSIVE)) != 0)	errx(1, "setbindhost: %s", gai_strerror(n));}static voidusage(void){    fprintf(stderr, "usage: rtpproxy [-2fvF] [-l addr1[/addr2]] "      "[-6 addr1[/addr2]] [-s path]\n\t[-t tos] [-r rdir [-S sdir]] [-T ttl] "      "[-L nfiles] [-m port_min]\n\t[-M port_max] [-u uname[:gname]]\n");    exit(1);}static voidfatsignal(int sig){    rtpp_log_write(RTPP_LOG_INFO, glog, "got signal %d", sig);    exit(0);}static voidehandler(void){    unlink(cmd_sock);    unlink(pid_file);    rtpp_log_write(RTPP_LOG_INFO, glog, "rtpproxy ended");    rtpp_log_close(glog);}static void init_config(struct cfg *cf, int argc, char **argv){    int ch, i;    char *bh[2], *bh6[2], *cp;    bh[0] = bh[1] = bh6[0] = bh6[1] = NULL;    cf->port_min = PORT_MIN;    cf->port_max = PORT_MAX;    cf->max_ttl = SESSION_TIMEOUT;    cf->tos = TOS;    cf->rrtcp = 1;    if (getrlimit(RLIMIT_NOFILE, &(cf->nofile_limit)) != 0)	err(1, "getrlimit");    while ((ch = getopt(argc, argv, "vf2Rl:6:s:S:t:r:p:T:L:m:M:u:F")) != -1)	switch (ch) {	case 'f':	    cf->nodaemon = 1;	    break;	case 'l':	    bh[0] = optarg;	    bh[1] = strchr(bh[0], '/');	    if (bh[1] != NULL) {		*bh[1] = '\0';		bh[1]++;		cf->bmode = 1;	    }	    break;	case '6':	    bh6[0] = optarg;	    bh6[1] = strchr(bh6[0], '/');	    if (bh6[1] != NULL) {		*bh6[1] = '\0';		bh6[1]++;		cf->bmode = 1;	    }	    break;	case 's':	    if (strncmp("udp:", optarg, 4) == 0) {		cf->umode = 1;		optarg += 4;	    } else if (strncmp("udp6:", optarg, 5) == 0) {		cf->umode = 6;		optarg += 5;	    } else if (strncmp("unix:", optarg, 5) == 0) {		cf->umode = 0;		optarg += 5;	    }	    cmd_sock = optarg;	    break;	case 't':	    cf->tos = atoi(optarg);	    break;	case '2':	    cf->dmode = 1;	    break;	case 'v':	    printf("Basic version: %d\n", CPROTOVER);	    for (i = 1; proto_caps[i].pc_id != NULL; ++i) {		printf("Extension %s: %s\n", proto_caps[i].pc_id,		    proto_caps[i].pc_description);	    }	    exit(0);	    break;	case 'r':	    cf->rdir = optarg;	    break;	case 'S':	    cf->sdir = optarg;	    break;	case 'R':	    cf->rrtcp = 0;	    break;	case 'p':	    pid_file = optarg;	    break;	case 'T':	    cf->max_ttl = atoi(optarg);	    break;	case 'L':	    cf->nofile_limit.rlim_cur = cf->nofile_limit.rlim_max = atoi(optarg);	    if (setrlimit(RLIMIT_NOFILE, &(cf->nofile_limit)) != 0)		err(1, "setrlimit");	    if (getrlimit(RLIMIT_NOFILE, &(cf->nofile_limit)) != 0)		err(1, "getrlimit");	    if (cf->nofile_limit.rlim_max < atoi(optarg))		warnx("limit allocated by setrlimit (%d) is less than "		  "requested (%d)", (int) cf->nofile_limit.rlim_max,		  atoi(optarg));	    break;	case 'm':	    cf->port_min = atoi(optarg);	    break;	case 'M':	    cf->port_max = atoi(optarg);	    break;	case 'u':	    cf->run_uname = optarg;	    cp = strchr(optarg, ':');	    if (cp != NULL) {		if (cp == optarg)		    cf->run_uname = NULL;		cp[0] = '\0';		cp++;	    }	    cf->run_gname = cp;	    break;	case 'F':	    cf->no_check = 1;	    break;	case '?':	default:	    usage();	}    if (cf->rdir == NULL && cf->sdir != NULL)	errx(1, "-S switch requires -r switch");    if (cf->no_check == 0 && getuid() == 0 && cf->run_uname == NULL) {	if (cf->umode != 0) {	    errx(1, "running this program as superuser in a remote control "	      "mode is strongly not recommended, as it poses serious security "	      "threat to your system. Use -u option to run as an unprivileged "	      "user or -F is you want to run as a superuser anyway.");	} else {	    warnx("WARNING!!! Running this program as superuser is strongly "	      "not recommended, as it may pose serious security threat to "	      "your system. Use -u option to run as an unprivileged user "	      "or -F to surpress this warning.");	}    }    if (cf->port_min <= 0 || cf->port_min > 65535)	errx(1, "invalid value of the port_min argument, "	  "not in the range 1-65535");    if (cf->port_max <= 0 || cf->port_max > 65535)	errx(1, "invalid value of the port_max argument, "	  "not in the range 1-65535");    if (cf->port_min > cf->port_max)	errx(1, "port_min should be less than port_max");    /* make sure that port_min and port_max are even */    if ((cf->port_min % 2) != 0)	cf->port_min++;    if ((cf->port_max % 2) != 0)	cf->port_max--;    cf->nextport[0] = cf->nextport[1] = cf->port_min;    cf->sessions = malloc((sizeof cf->sessions[0]) *      (((cf->port_max - cf->port_min + 1) * 2) + 1));    cf->rtp_servers =  malloc((sizeof cf->rtp_servers[0]) *      (((cf->port_max - cf->port_min + 1) * 2) + 1));    cf->pfds = malloc((sizeof cf->pfds[0]) *      (((cf->port_max - cf->port_min + 1) * 2) + 1));    if (bh[0] == NULL && bh[1] == NULL && bh6[0] == NULL && bh6[1] == NULL) {	if (cf->umode != 0)	    errx(1, "explicit binding address has to be specified in UDP "	      "command mode");	bh[0] = "*";    }    for (i = 0; i < 2; i++) {	if (bh[i] != NULL && *bh[i] == '\0')	    bh[i] = NULL;	if (bh6[i] != NULL && *bh6[i] == '\0')	    bh6[i] = NULL;    }    i = ((bh[0] == NULL) ? 0 : 1) + ((bh[1] == NULL) ? 0 : 1) +      ((bh6[0] == NULL) ? 0 : 1) + ((bh6[1] == NULL) ? 0 : 1);    if (cf->bmode != 0) {	if (bh[0] != NULL && bh6[0] != NULL)	    errx(1, "either IPv4 or IPv6 should be configured for external "	      "interface in bridging mode, not both");	if (bh[1] != NULL && bh6[1] != NULL)	    errx(1, "either IPv4 or IPv6 should be configured for internal "	      "interface in bridging mode, not both");	if (i != 2)	    errx(1, "incomplete configuration of the bridging mode - exactly "	      "2 listen addresses required, %d provided", i);    } else if (i != 1) {	errx(1, "exactly 1 listen addresses required, %d provided", i);    }    for (i = 0; i < 2; i++) {	cf->bindaddr[i] = NULL;	if (bh[i] != NULL) {	    cf->bindaddr[i] = malloc(sizeof(struct sockaddr_storage));	    setbindhost(cf->bindaddr[i], AF_INET, bh[i], SERVICE);	    continue;	}	if (bh6[i] != NULL) {	    cf->bindaddr[i] = malloc(sizeof(struct sockaddr_storage));	    setbindhost(cf->bindaddr[i], AF_INET6, bh6[i], SERVICE);	    continue;	}    }    if (cf->bindaddr[0] == NULL) {	cf->bindaddr[0] = cf->bindaddr[1];	cf->bindaddr[1] = NULL;    }}static intinit_controlfd(struct cfg *cf){    struct sockaddr_un ifsun;    struct sockaddr_storage ifsin;    char *cp;    int i, controlfd, flags;    if (cf->umode == 0) {	unlink(cmd_sock);	memset(&ifsun, '\0', sizeof ifsun);#if !defined(__linux__) && !defined(__solaris__)	ifsun.sun_len = strlen(cmd_sock);#endif	ifsun.sun_family = AF_LOCAL;	strcpy(ifsun.sun_path, cmd_sock);	controlfd = socket(PF_LOCAL, SOCK_STREAM, 0);	if (controlfd == -1)	    err(1, "can't create socket");	setsockopt(controlfd, SOL_SOCKET, SO_REUSEADDR, &controlfd,	  sizeof controlfd);	if (bind(controlfd, sstosa(&ifsun), sizeof ifsun) < 0)	    err(1, "can't bind to a socket");	if (listen(controlfd, 32) != 0)	    err(1, "can't listen on a socket");    } else {	cp = strrchr(cmd_sock, ':');	if (cp != NULL) {	    *cp = '\0';	    cp++;	}	if (cp == NULL || *cp == '\0')	    cp = CPORT;	i = (cf->umode == 6) ? AF_INET6 : AF_INET;	setbindhost(sstosa(&ifsin), i, cmd_sock, cp);	controlfd = socket(i, SOCK_DGRAM, 0);	if (controlfd == -1)	    err(1, "can't create socket");	if (bind(controlfd, sstosa(&ifsin), SS_LEN(&ifsin)) < 0)	    err(1, "can't bind to a socket");    }    flags = fcntl(controlfd, F_GETFL);    fcntl(controlfd, F_SETFL, flags | O_NONBLOCK);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -