예제 #1
0
파일: testmock.c 프로젝트: bronson/io
static void prepare_mock_test(io_poller *poller, const char *name)
{
	switch(name[0]) {
	case 'c':	// client
		io_mock_set_events(poller, &client_events);
		// the test script uses two outgoing connections
		initiate_connection(poller, "127.0.0.1:6543");
		initiate_connection(poller, "127.0.0.1:6543");
		break;
	
	case 's':	// server
		io_mock_set_events(poller, &server_events);
		create_listener(poller, "127.0.0.1:6543");
		break;

	case 'e':	// error
		io_mock_set_events(poller, &error_events);
		create_listener(poller, "127.0.0.1:6543");
		create_listener(poller, "127.0.0.1:6544");
		initiate_connection(poller, "127.0.0.1:6500");
		break;
		
	default:
		fprintf(stderr, "Specify either 'client' or 'server', not '%s'.\n", optarg);
		exit(1);
	}
}
예제 #2
0
파일: main.c 프로젝트: AdrianCohea/Clara
int main()
{
    if(signal(SIGINT, handle_signals) == SIG_ERR)
    {
        perror("signal");
        exit(0);
    }
    if(signal(SIGTERM, handle_signals) == SIG_ERR)
    {
        perror("signal");
        exit(0);
    }

    atexit(exit_gracefully);

    sfd = create_listener(AF_INET, SOCK_STREAM, 0, "127.0.0.1", 4141);
    sfd6 = create_listener(AF_INET6, SOCK_STREAM, 0, "::1", 4141);

    if(sfd >= 0)
    {
        thread_ipv4 = get_server_thread(sfd, AF_INET, serve_forever);
    }

    if(sfd6 >= 0)
    {
        thread_ipv6 = get_server_thread(sfd6, AF_INET6, serve_forever);
    }

    if(thread_ipv4)
        pthread_join(*thread_ipv4, 0);
    if(thread_ipv6)
        pthread_join(*thread_ipv6, 0);

    return 0;
}
예제 #3
0
int main(int argc, char *argv[])
{
    if (argc < 3) {
        usage();
    }
    if (getenv("NOPOLL_TEST_DEBUG"))
        debug_local = 1;
    if (getenv("NOPOLL_TEST_DEBUG_NOPOLL"))
        debug_nopoll = 1;

    if (strcmp(argv[1], "server") == 0) {
        return create_listener(argv[2]);
    }
    else if (strcmp(argv[1], "client") == 0) {
        if (argc < 6)
            usage();
        instanceID = strdup(argv[2]);
        const char * host = argv[3];
        const char * port = argv[4];
        int duration = atoi(argv[5]);
        if (duration <= 0) {
            printf("Duration should be greater than 0 seconds.\n");
            usage();
        }
        return create_client(host, port, duration);
    }
    else {
        printf("First argument should be  \"server\" or \"client\"\n");
        exit(1);
    }
}
예제 #4
0
파일: server.c 프로젝트: fenglyu/libel
int main() {
  int listenfd = create_listener();
  
  el_loop *loop = el_loop_new();
  event *e = el_event_new(listenfd, READ_EVENT, onaccept, loop);
  el_event_add(loop, e);
  return el_loop_run(loop);
}
예제 #5
0
파일: testmock.c 프로젝트: bronson/io
static void process_args(io_poller *poller, int argc, char **argv)
{
    char buf[256], *cp;
    int optidx, i, c;

	optidx = 0;
	static struct option longopts[] = {
		// name, has_arg (1=reqd,2=opt), flag, val
		{"mock", 1, 0, 'm'},
		{"client", 1, 0, 'c'},
		{"server", 1, 0, 's'},
		{0, 0, 0, 0},
	};

	// dynamically create the option string from the long
	// options.  Why oh why doesn't glibc do this for us???
	cp = buf;
	for(i=0; longopts[i].name; i++) {
		if(!longopts[i].flag) {
			*cp++ = longopts[i].val;
			if(longopts[i].has_arg > 0) *cp++ = ':';
			if(longopts[i].has_arg > 1) *cp++ = ':';
		}
	}
	*cp++ = '\0';

	for(;;) {
		c = getopt_long(argc, argv, buf, longopts, &optidx);
		if(c == -1) break;
		
		switch(c) {
        case 'c':
        	init_poller(poller, IO_POLLER_ANY);
        	initiate_connection(poller, optarg);
            break;

		case 'm':
			init_poller(poller, IO_POLLER_MOCK);
			prepare_mock_test(poller, optarg);
			break;

		case 's':
			init_poller(poller, IO_POLLER_ANY);
			create_listener(poller, optarg);
			break;
			
		case '?':
			// getopt_long already printed the error message
			exit(1);
		}
	}
}
예제 #6
0
파일: simple.c 프로젝트: zhangjinde/h2o
int main(int argc, char **argv)
{
    h2o_hostconf_t *hostconf;

    signal(SIGPIPE, SIG_IGN);

    h2o_config_init(&config);
    hostconf = h2o_config_register_host(&config, "default");
    register_handler(hostconf, "/post-test", post_test);
    register_handler(hostconf, "/chunked-test", chunked_test);
    h2o_file_register(h2o_config_register_path(hostconf, "/"), "examples/doc_root", NULL, NULL, 0);

#if 0 /* reproxy is not yet implemented */
    register_handler(hostconf, "/reproxy-test", reproxy_test);
    h2o_reproxy_register(hostconf);
#endif

#if H2O_USE_LIBUV
    uv_loop_t loop;
    uv_loop_init(&loop);
    h2o_context_init(&ctx, &loop, &config);
#else
    h2o_context_init(&ctx, h2o_evloop_create(), &config);
#endif

    /* disabled by default: uncomment the block below to use HTTPS instead of HTTP */
    /*
    if (setup_ssl("server.crt", "server.key") != 0)
        goto Error;
    */

    /* disabled by default: uncomment the line below to enable access logging */
    /* h2o_access_log_register(&config.default_host, "/dev/stdout", NULL); */

    if (create_listener() != 0) {
        fprintf(stderr, "failed to listen to 127.0.0.1:7890:%s\n", strerror(errno));
        goto Error;
    }

#if H2O_USE_LIBUV
    uv_run(ctx.loop, UV_RUN_DEFAULT);
#else
    while (h2o_evloop_run(ctx.loop) == 0)
        ;
#endif

Error:
    return 1;
}
예제 #7
0
    int create_listener (
        scoped_ptr<listener>& new_listener,
        unsigned short port,
        const std::string& ip
    )
    {
        new_listener.reset();
        listener* temp;
        int status = create_listener(temp,port,ip);

        if (status == 0)
            new_listener.reset(temp);

        return status;
    }
예제 #8
0
    void server::
    open_listening_socket (
    )
    {
        if (!sock)
        {
            int status = create_listener(sock,listening_port,listening_ip);
            const int port_used = listening_port;

            // if there was an error then clear this object
            if (status < 0)
            {
                max_connections_mutex.lock();
                listening_port_mutex.lock();
                listening_ip_mutex.lock();
                listening_ip = "";        
                listening_port = 0;
                max_connections = 1000;
                graceful_close_timeout = 500;
                listening_port_mutex.unlock();
                listening_ip_mutex.unlock();
                max_connections_mutex.unlock();
            }



            // throw an exception for the error
            if (status == PORTINUSE)
            {
                throw dlib::socket_error(
                    EPORT_IN_USE,
                    "error occurred in server::start()\nport " + cast_to_string(port_used) + " already in use"
                );
            }
            else if (status == OTHER_ERROR)
            {
                throw dlib::socket_error(
                    "error occurred in server::start()\nunable to create listener"
                );            
            }
        }

        running_mutex.lock();
        running = true;
        running_mutex.unlock();
    }
예제 #9
0
파일: directconn.c 프로젝트: VoxOx/VoxOx
void
msn_directconn_listen(MsnDirectConn *directconn)
{
	int port;
	int fd;

	port = 7000;

	for (fd = -1; fd < 0;)
		fd = create_listener(++port);

	directconn->fd = fd;

	directconn->inpa = gaim_input_add(fd, GAIM_INPUT_READ, connect_cb,
		directconn);

	directconn->port = port;
	directconn->c = 0;
}
예제 #10
0
파일: websocket.c 프로젝트: fetus-hina/h2o
int main(int argc, char **argv)
{
    h2o_hostconf_t *hostconf;
    h2o_pathconf_t *pathconf;

    h2o_config_init(&config);
    hostconf = h2o_config_register_host(&config, h2o_iovec_init(H2O_STRLIT("default")), 65535);
    pathconf = h2o_config_register_path(hostconf, "/", 0);
    h2o_create_handler(pathconf, sizeof(h2o_handler_t))->on_req = on_req;

#if H2O_USE_LIBUV
    uv_loop_t loop;
    uv_loop_init(&loop);
    h2o_context_init(&ctx, &loop, &config);
#else
    h2o_context_init(&ctx, h2o_evloop_create(), &config);
#endif

    /* disabled by default: uncomment the block below to use HTTPS instead of HTTP */
    /*
    if (setup_ssl("server.crt", "server.key") != 0)
        goto Error;
    */

    accept_ctx.ctx = &ctx;
    accept_ctx.hosts = config.hosts;

    if (create_listener() != 0) {
        fprintf(stderr, "failed to listen to 127.0.0.1:7890:%s\n", strerror(errno));
        goto Error;
    }

#if H2O_USE_LIBUV
    uv_run(ctx.loop, UV_RUN_DEFAULT);
#else
    while (h2o_evloop_run(ctx.loop, INT32_MAX) == 0)
        ;
#endif

Error:
    return 1;
}
예제 #11
0
/*   Main
 * ---------------------------------------------------------------------
 * - just calls functions for parsing parameters, socket creation and
 *   for the most important function for accepting connections
 */
int main(int argc, char *argv[])
{
  signal(SIGCHLD, &wait_for_children);
  signal(SIGTERM, &term_children_and_exit);
  signal(SIGINT, &term_children_and_exit);

  long port = 0;
  if (parse_arguments(argc, argv, &port) != EXIT_SUCCESS)
    return EXIT_FAILURE;

  struct sockaddr_in socket_in;
  int sock; // filedescriptor pro socket
  if (create_listener(&sock, &socket_in, &port) != EXIT_SUCCESS)
    return EXIT_FAILURE;

  if (accept_connection(&sock, &socket_in) != EXIT_SUCCESS)
    return EXIT_FAILURE;

  close(sock);
  return EXIT_SUCCESS;
}
예제 #12
0
int
handle_connections(int portnum)
{
  int listenfd;
  int acceptfd;
  pid_t childpid;

  listenfd = create_listener(portnum);
  if (listenfd < 0) {
    fprintf(stderr, "Warning: Exiting main network event loop\n");
    return -1;
  }

  while (1) {
    fprintf(stderr, "Notice: Waiting for a connection...\n");
    acceptfd = wait_for_connection(listenfd);
    if (acceptfd < 0) {
      fprintf(stderr, "Warning: Exiting main network event loop\n");
      return -1;
    }

    childpid = fork();

    if (childpid > 0) {
      close(acceptfd);
      fprintf(stderr, "Notice: Child process id=%d forked to handle incoming connection\n", childpid);
    }
    else if (childpid == 0) {
      close(listenfd);
      fprintf(stderr, "Notice: Processing request in child process\n");
      read_incoming_data(acceptfd);
      exit(0);
    }
    else {
      perror("fork");
      fprintf(stderr, "Error: Unable to create child process to handle new connection\n");
    }
  }
} /* handle_connections() */
예제 #13
0
파일: simple.c 프로젝트: Gwill/h2o
int main(int argc, char **argv)
{
    signal(SIGPIPE, SIG_IGN);

    h2o_config_init(&config);
    register_handler(&config.default_host, post_test);
    register_handler(&config.default_host, chunked_test);
    register_handler(&config.default_host, reproxy_test);
    h2o_register_file_handler(&config.default_host, "/", "htdocs", "index.html");
    h2o_define_mimetype(&config.default_host.mimemap, "html", "text/html");
    h2o_register_reproxy_filter(&config.default_host);

#if H2O_USE_LIBUV
    uv_loop_t loop;
    uv_loop_init(&loop);
    h2o_context_init(&ctx, &loop, &config);
#else
    h2o_context_init(&ctx, h2o_evloop_create(), &config);
#endif

    //ssl_ctx = h2o_ssl_new_server_context("server.crt", "server.key", h2o_http2_tls_identifiers);
    //h2o_register_access_logger(&ctx, "/dev/stdout");

    if (create_listener() != 0) {
        fprintf(stderr, "failed to listen to 127.0.0.1:7890:%s\n", strerror(errno));
        goto Error;
    }

#if H2O_USE_LIBUV
    uv_run(ctx.loop, UV_RUN_DEFAULT);
#else
    while (h2o_evloop_run(ctx.loop) == 0)
        ;
#endif

Error:
    return 1;
}
예제 #14
0
int32_t init_tcp_server(int32_t portnr, char* ip,
                        void (*rcv_cb)(int32_t fd, char* data, int32_t len))
{
    int fd;
    struct fd_obj* new_fdo = NULL;

    fd = create_listener(ip, portnr, SOCK_STREAM, IPPROTO_TCP, 10);
    if(fd == -1){
        return fd;
    }

	tcp_app_callback = rcv_cb;
	new_fdo = add_fdo(fd);
	if(new_fdo == NULL)	{
		DEBUG_MSG("Can't add fd's.");
	} else {
		new_fdo->fh = accept_new_client;
	}

	DEBUG_MSG("Setup TCP server OK.");

	return 0;
}
예제 #15
0
파일: main.c 프로젝트: m45t3r/yaftpd
int main (int argc, char **argv) {
    int listenfd;
    pid_t childpid;
    char recvline[MAXLINE + 1];
    ssize_t  n;

    if (argc != 2) {
        fprintf(stderr,"usage: %s PORT\n",argv[0]);
        fprintf(stderr,"Run FTP server in port PORT\n");
        exit(EXIT_FAILURE);
    }

    if ((listenfd = create_listener(INADDR_ANY, atoi(argv[1]), 1)) == -1) {
        perror("create_listener");
        exit(EXIT_FAILURE);
    }

    printf("YAFTPd is running in port %s\n",argv[1]);

    for (;;) {
        if ((CONN_FD = accept(listenfd, (struct sockaddr *) NULL, NULL)) == -1 ) {
            perror("accept");
            exit(EXIT_FAILURE);
        }

        if ((childpid = fork()) == 0) { // Child proccess
            printf("Succesful connection at %s. New child PID: %d\n", get_socket_ip(CONN_FD), getpid());
            close(listenfd);

            /* When the user connects show info message about server version */ 
            char* msg = version_info();
            write(CONN_FD, msg, strlen(msg));

            while ((n=read(CONN_FD, recvline, MAXLINE)) > 0) {
                recvline[n]=0;
                printf("PID %d SEND: ", getpid());
                if ((fputs(recvline,stdout)) == EOF) {
                    perror("fputs");
                    exit(EXIT_FAILURE);
                }
                int result = parse_command(recvline);
                if(result == 1) {
                    // If parse_command returns 1, we should exit the current
                    // proccess
                    exit(EXIT_SUCCESS);
                } else if (result == -1) {
                    // In case of error too, but we should inform the system.
                    perror("parse_command");
                    exit(EXIT_FAILURE);
                } else {
                    // If parse_command returns 0, we should continue the
                    // process.
                    continue;
                }
            }

            printf("Finished connection with child PID: %d\n", getpid());

        } else { // Parent proccess
            close(CONN_FD);
        }
    }
    exit(EXIT_SUCCESS);
}
예제 #16
0
파일: main.c 프로젝트: mmontone/UCW-boxset
int
main(int argc, char **argv)
{
    FdEventHandlerPtr listener;
    int i;
    int rc;
    int expire = 0, printConfig = 0;

    initAtoms();
    CONFIG_VARIABLE(daemonise, CONFIG_BOOLEAN, "Run as a daemon");
    CONFIG_VARIABLE(pidFile, CONFIG_ATOM, "File with pid of running daemon.");

    preinitChunks();
    preinitLog();
    preinitObject();
    preinitIo();
    preinitDns();
    preinitServer();
    preinitHttp();
    preinitDiskcache();
    preinitLocal();
    preinitForbidden();
    preinitSocks();
	preinitOffline();

    i = 1;
    while(i < argc) {
        if(argv[i][0] != '-')
            break;
        if(strcmp(argv[i], "--") == 0) {
            i++;
            break;
        } else if(strcmp(argv[i], "-h") == 0) {
            usage(argv[0]);
            exit(0);
        } else if(strcmp(argv[i], "-v") == 0) {
            printConfig = 1;
            i++;
        } else if(strcmp(argv[i], "-x") == 0) {
            expire = 1;
            i++;
        } else if(strcmp(argv[i], "-c") == 0) {
            i++;
            if(i >= argc) {
                usage(argv[0]);
                exit(1);
            }
            if(configFile)
                releaseAtom(configFile);
            configFile = internAtom(argv[i]);
            i++;
        } else {
            usage(argv[0]);
            exit(1);
        }
    }

    if(configFile)
        configFile = expandTilde(configFile);

    if(configFile == NULL) {
        configFile = expandTilde(internAtom("~/.polipo"));
        if(configFile)
            if(access(configFile->string, F_OK) < 0) {
                releaseAtom(configFile);
                configFile = NULL;
            }
    }

    if(configFile == NULL) {
        if(access("/etc/polipo/config", F_OK) >= 0)
            configFile = internAtom("/etc/polipo/config");
        if(configFile && access(configFile->string, F_OK) < 0) {
            releaseAtom(configFile);
            configFile = NULL;
        }
    }

    rc = parseConfigFile(configFile);
    if(rc < 0)
        exit(1);

    while(i < argc) {
        rc = parseConfigLine(argv[i], "command line", 0, 0);
        if(rc < 0)
            exit(1);
        i++;
    }

    initChunks();
    initLog();
    initObject();
    if(!expire && !printConfig)
        initEvents();
    initIo();
    initDns();
    initHttp();
    initServer();
    initDiskcache();
    initForbidden();
    initSocks();
	initOffline();

    if(printConfig) {
        printConfigVariables(stdout, 0);
        exit(0);
    }

    if(expire) {
        expireDiskObjects();
        exit(0);
    }

    if(daemonise)
        do_daemonise(logFile == NULL || logFile->length == 0);

    if(pidFile)
        writePid(pidFile->string);

    listener = create_listener(proxyAddress->string, 
                               proxyPort, httpAccept, NULL);
    if(!listener) {
        if(pidFile) unlink(pidFile->string);
        exit(1);
    }

    eventLoop();

    if(pidFile) unlink(pidFile->string);
    return 0;
}
예제 #17
0
void lt_main(void *arg)
{
    int fd, opt = 1;
    proxy_server *srv = (proxy_server*)arg;
    lthread_t *lt_accept = NULL;
    struct sockaddr cin = {0};
    socklen_t addrlen = sizeof(struct sockaddr);
    proxy_conn_t *proxy = NULL;

    DEFINE_LTHREAD;
    lthread_detach();

    srv->listen_fd = create_listener("0.0.0.0", 9000);
    if(srv->listen_fd < 0) {
        exit(1);
    }
    fprintf(stderr, "listener creating :9000\n");

    lthread_create(&lt_accept, (void*)lt_accept_loop, (void*)srv);

    while(!srv->is_die) {
        fd = lthread_accept(srv->listen_fd, &cin, &addrlen);
        if(fd < 0) {
            perror("accept error");
            break;
        }
        if(srv->quiting) {
            lthread_close(fd);
            break;
        }
        if(srv->is_die) {
            //already die, close and break
            lthread_close(fd);
            fprintf(stderr, "server already die :9000\n");
            break;
        }

        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)) == -1) {
            perror("failed to set SOREUSEADDR on socket");
            break;
        }

        fprintf(stderr, "accept new client\n");
        proxy = proxy_conn_create(fd, 0);
        if(0 != chan_send(srv->accepts_ch, proxy)) {
            //send failed, free proxy
            proxy_conn_free(proxy);
            break;
        }

        //yield myself
        lthread_sleep((uint64_t)0);
    }
    if(-1 != srv->listen_fd) {
        close(srv->listen_fd);
        srv->listen_fd = -1;
    }
    if(!srv->is_die) {
        srv->is_die = 1;
        chan_close(srv->die_ch);
        fprintf(stderr, "srv die\n");
    }

    fprintf(stderr, "lt_accept end\n");
    lthread_join(lt_accept, NULL, LTHREAD_FOREVER);

    //server release
    server_release(srv);
}
예제 #18
0
int
handle_command(struct cfg *cf, int controlfd, double dtime)
{
    int len, argc, i, pidx, asymmetric;
    int external, pf, lidx, playcount, weak, tpf;
    int fds[2], lport, n;
    socklen_t rlen;
    char buf[1024 * 8];
    char *cp, *call_id, *from_tag, *to_tag, *addr, *port, *cookie;
    char *pname, *codecs, *recording_name, *t;
    struct rtpp_session *spa, *spb;
    char **ap, *argv[10];
    const char *rname, *errmsg;
    struct sockaddr *ia[2], *lia[2];
    struct sockaddr_storage raddr;
    int requested_nsamples;
    enum {DELETE, RECORD, PLAY, NOPLAY, COPY, UPDATE, LOOKUP, QUERY} op;
    int max_argc;
    char *socket_name_u, *notify_tag;
    struct sockaddr *local_addr;
    char c;

    requested_nsamples = -1;
    ia[0] = ia[1] = NULL;
    spa = spb = NULL;
    lia[0] = lia[1] = cf->bindaddr[0];
    lidx = 1;
    fds[0] = fds[1] = -1;
    recording_name = NULL;
    socket_name_u = notify_tag = NULL;
    local_addr = NULL;
    codecs = NULL;

    if (cf->umode == 0) {
	for (;;) {
	    len = read(controlfd, buf, sizeof(buf) - 1);
	    if (len != -1 || (errno != EAGAIN && errno != EINTR))
		break;
	    sched_yield();
	}
    } else {
	rlen = sizeof(raddr);
	len = recvfrom(controlfd, buf, sizeof(buf) - 1, 0,
	  sstosa(&raddr), &rlen);
    }
    if (len == -1) {
	if (errno != EAGAIN && errno != EINTR)
	    rtpp_log_ewrite(RTPP_LOG_ERR, cf->glog, "can't read from control socket");
	return -1;
    }
    buf[len] = '\0';

    rtpp_log_write(RTPP_LOG_DBUG, cf->glog, "received command \"%s\"", buf);

    cp = buf;
    argc = 0;
    memset(argv, 0, sizeof(argv));
    for (ap = argv; (*ap = rtpp_strsep(&cp, "\r\n\t ")) != NULL;)
	if (**ap != '\0') {
	    argc++;
	    if (++ap >= &argv[10])
		break;
	}
    cookie = NULL;
    if (argc < 1 || (cf->umode != 0 && argc < 2)) {
	rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
	reply_error(cf, controlfd, &raddr, rlen, cookie, 0);
	return 0;
    }

    /* Stream communication mode doesn't use cookie */
    if (cf->umode != 0) {
	cookie = argv[0];
	for (i = 1; i < argc; i++)
	    argv[i - 1] = argv[i];
	argc--;
	argv[argc] = NULL;
    } else {
	cookie = NULL;
    }

    addr = port = NULL;
    switch (argv[0][0]) {
    case 'u':
    case 'U':
	/* U[opts] callid remote_ip remote_port from_tag [to_tag] */
	op = UPDATE;
	rname = "update/create";
	break;

    case 'l':
    case 'L':
	op = LOOKUP;
	rname = "lookup";
	break;

    case 'd':
    case 'D':
	op = DELETE;
	rname = "delete";
	break;

    case 'p':
    case 'P':
	/*
	 * P callid pname codecs from_tag to_tag
	 *
	 *   <codecs> could be either comma-separated list of supported
	 *   payload types or word "session" (without quotes), in which
	 *   case list saved on last session update will be used instead.
	 */
	op = PLAY;
	rname = "play";
	playcount = 1;
	pname = argv[2];
	codecs = argv[3];
	break;

    case 'r':
    case 'R':
	op = RECORD;
	rname = "record";
	break;

    case 'c':
    case 'C':
	op = COPY;
	rname = "copy";
	break;

    case 's':
    case 'S':
	op = NOPLAY;
	rname = "noplay";
	break;

    case 'v':
    case 'V':
	if (argv[0][1] == 'F' || argv[0][1] == 'f') {
	    int i, known;
	    /*
	     * Wait for protocol version datestamp and check whether we
	     * know it.
	     */
	    if (argc != 2 && argc != 3) {
		rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
		reply_error(cf, controlfd, &raddr, rlen, cookie, 2);
		return 0;
	    }
	    /*
	     * Only list 20081224 protocol mod as supported if
	     * user actually enabled notification with -n
	     */
	    if (strcmp(argv[1], "20081224") == 0 &&
	      cf->timeout_handler.socket_name == NULL) {
		reply_number(cf, controlfd, &raddr, rlen, cookie, 0);
		return 0;
	    }
	    for (known = i = 0; proto_caps[i].pc_id != NULL; ++i) {
		if (!strcmp(argv[1], proto_caps[i].pc_id)) {
		    known = 1;
		    break;
		}
	    }
	    reply_number(cf, controlfd, &raddr, rlen, cookie, known);
	    return 0;
	}
	if (argc != 1 && argc != 2) {
	    rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
	    reply_error(cf, controlfd, &raddr, rlen, cookie, 2);
	    return 0;
	}
	/* This returns base version. */
	reply_number(cf, controlfd, &raddr, rlen, cookie, CPROTOVER);
	return 0;

    case 'i':
    case 'I':
	if (cookie == NULL)
	    len = sprintf(buf, "sessions created: %llu\nactive sessions: %d\n"
	      "active streams: %d\n", cf->sessions_created,
	      cf->sessions_active, cf->nsessions / 2);
	else
	    len = sprintf(buf, "%s sessions created: %llu\nactive sessions: %d\n"
	      "active streams: %d\n", cookie, cf->sessions_created,
	      cf->sessions_active, cf->nsessions / 2);
	for (i = 1; i < cf->nsessions; i++) {
	    char addrs[4][256];

	    spa = cf->sessions[i];
	    if (spa == NULL || spa->sidx[0] != i)
		continue;
	    /* RTCP twin session */
	    if (spa->rtcp == NULL) {
		spb = spa->rtp;
		buf[len++] = '\t';
	    } else {
		spb = spa->rtcp;
		buf[len++] = '\t';
		buf[len++] = 'C';
		buf[len++] = ' ';
	    }

	    addr2char_r(spb->laddr[1], addrs[0], sizeof(addrs[0]));
	    if (spb->addr[1] == NULL) {
		strcpy(addrs[1], "NONE");
	    } else {
		sprintf(addrs[1], "%s:%d", addr2char(spb->addr[1]),
		  addr2port(spb->addr[1]));
	    }
	    addr2char_r(spb->laddr[0], addrs[2], sizeof(addrs[2]));
	    if (spb->addr[0] == NULL) {
		strcpy(addrs[3], "NONE");
	    } else {
		sprintf(addrs[3], "%s:%d", addr2char(spb->addr[0]),
		  addr2port(spb->addr[0]));
	    }

	    len += sprintf(buf + len,
	      "%s/%s: caller = %s:%d/%s, callee = %s:%d/%s, "
	      "stats = %lu/%lu/%lu/%lu, ttl = %d/%d\n",
	      spb->call_id, spb->tag, addrs[0], spb->ports[1], addrs[1],
	      addrs[2], spb->ports[0], addrs[3], spa->pcount[0], spa->pcount[1],
	      spa->pcount[2], spa->pcount[3], spb->ttl[0], spb->ttl[1]);
	    if (len + 512 > sizeof(buf)) {
		doreply(cf, controlfd, buf, len, &raddr, rlen);
		len = 0;
	    }
	}
	if (len > 0)
	    doreply(cf, controlfd, buf, len, &raddr, rlen);;
	return 0;
	break;

    case 'q':
    case 'Q':
	op = QUERY;
	rname = "query";
	break;

    case 'x':
    case 'X':
        /* Delete all active sessions */
        rtpp_log_write(RTPP_LOG_INFO, cf->glog, "deleting all active sessions");
        for (i = 1; i < cf->nsessions; i++) {
	    spa = cf->sessions[i];
	    if (spa == NULL || spa->sidx[0] != i)
		continue;
	    /* Skip RTCP twin session */
	    if (spa->rtcp != NULL) {
		remove_session(cf, spa);
	    }
        }
        reply_ok(cf, controlfd, &raddr, rlen, cookie);
        return 0;
        break;

    default:
	rtpp_log_write(RTPP_LOG_ERR, cf->glog, "unknown command");
	reply_error(cf, controlfd, &raddr, rlen, cookie, 3);
	return 0;
    }
    call_id = argv[1];
    if (op == UPDATE || op == LOOKUP || op == PLAY) {
	max_argc = (op == UPDATE ? 8 : 6);
	if (argc < 5 || argc > max_argc) {
	    rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
	    reply_error(cf, controlfd, &raddr, rlen, cookie, 4);
	    return 0;
	}
	from_tag = argv[4];
	to_tag = argv[5];
	if (op == PLAY && argv[0][1] != '\0')
	    playcount = atoi(argv[0] + 1);
	if (op == UPDATE && argc > 6) {
	    socket_name_u = argv[6];
	    if (strncmp("unix:", socket_name_u, 5) == 0)
		socket_name_u += 5;
	    if (argc == 8) {
		notify_tag = argv[7];
		len = url_unquote((uint8_t *)notify_tag, strlen(notify_tag));
		if (len == -1) {
		    rtpp_log_write(RTPP_LOG_ERR, cf->glog,
		      "command syntax error - invalid URL encoding");
		    reply_error(cf, controlfd, &raddr, rlen, cookie, 4);
		    return 0;
		}
		notify_tag[len] = '\0';
	    }
	}
    }
    if (op == COPY) {
	if (argc < 4 || argc > 5) {
	    rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
	    reply_error(cf, controlfd, &raddr, rlen, cookie, 1);
	    return 0;
	}
	recording_name = argv[2];
	from_tag = argv[3];
	to_tag = argv[4];
    }
    if (op == DELETE || op == RECORD || op == NOPLAY || op == QUERY) {
	if (argc < 3 || argc > 4) {
	    rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
	    reply_error(cf, controlfd, &raddr, rlen, cookie, 1);
	    return 0;
	}
	from_tag = argv[2];
	to_tag = argv[3];
    }
    if (op == DELETE || op == RECORD || op == COPY || op == NOPLAY) {
	/* D, R and S commands don't take any modifiers */
	if (argv[0][1] != '\0') {
	    rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
	    reply_error(cf, controlfd, &raddr, rlen, cookie, 1);
	    return 0;
	}
    }
    if (op == UPDATE || op == LOOKUP || op == DELETE) {
	addr = argv[2];
	port = argv[3];
	/* Process additional command modifiers */
	external = 1;
	/* In bridge mode all clients are assumed to be asymmetric */
	asymmetric = (cf->bmode != 0) ? 1 : 0;
	pf = AF_INET;
	weak = 0;
	for (cp = argv[0] + 1; *cp != '\0'; cp++) {
	    switch (*cp) {
	    case 'a':
	    case 'A':
		asymmetric = 1;
		break;

	    case 'e':
	    case 'E':
		if (lidx < 0) {
		    rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
		    reply_error(cf, controlfd, &raddr, rlen, cookie, 1);
		    return 0;
		}
		lia[lidx] = cf->bindaddr[1];
		lidx--;
		break;

	    case 'i':
	    case 'I':
		if (lidx < 0) {
		    rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
		    reply_error(cf, controlfd, &raddr, rlen, cookie, 1);
		    return 0;
		}
		lia[lidx] = cf->bindaddr[0];
		lidx--;
		break;

	    case '6':
		pf = AF_INET6;
		break;

	    case 's':
	    case 'S':
		asymmetric = 0;
		break;

	    case 'w':
	    case 'W':
		weak = 1;
		break;

	    case 'z':
	    case 'Z':
		requested_nsamples = (strtol(cp + 1, &cp, 10) / 10) * 80;
		if (requested_nsamples <= 0) {
		    rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
		    reply_error(cf, controlfd, &raddr, rlen, cookie, 1);
		    return 0;
		}
		cp--;
		break;

	    case 'c':
	    case 'C':
		cp += 1;
		for (t = cp; *cp != '\0'; cp++) {
		    if (!isdigit(*cp) && *cp != ',')
			break;
		}
		if (t == cp) {
		    rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
		    reply_error(cf, controlfd, &raddr, rlen, cookie, 1);
		    return 0;
		}
		codecs = alloca(cp - t + 1);
		memcpy(codecs, t, cp - t);
		codecs[cp - t] = '\0';
		cp--;
		break;

	    case 'l':
	    case 'L':
		len = extractaddr(cp + 1, &t, &cp, &tpf);
		if (len == -1) {
		    rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
		    reply_error(cf, controlfd, &raddr, rlen, cookie, 1);
		    return 0;
		}
		c = t[len];
		t[len] = '\0';
		local_addr = host2bindaddr(cf, t, tpf, &errmsg);
		if (local_addr == NULL) {
		    rtpp_log_write(RTPP_LOG_ERR, cf->glog,
		      "invalid local address: %s: %s", t, errmsg);
		    reply_error(cf, controlfd, &raddr, rlen, cookie, 1);
		    return 0;
		}
		t[len] = c;
		cp--;
		break;

	    case 'r':
	    case 'R':
		len = extractaddr(cp + 1, &t, &cp, &tpf);
		if (len == -1) {
		    rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
		    reply_error(cf, controlfd, &raddr, rlen, cookie, 1);
		    return 0;
		}
		c = t[len];
		t[len] = '\0';
		local_addr = alloca(sizeof(struct sockaddr_storage));
		n = resolve(local_addr, tpf, t, SERVICE, AI_PASSIVE);
		if (n != 0) {
		    rtpp_log_write(RTPP_LOG_ERR, cf->glog,
		      "invalid remote address: %s: %s", t, gai_strerror(n));
		    reply_error(cf, controlfd, &raddr, rlen, cookie, 1);
		    return 0;
		}
		if (local4remote(cf, local_addr, satoss(local_addr)) == -1) {
		    rtpp_log_write(RTPP_LOG_ERR, cf->glog,
		      "can't find local address for remote address: %s", t);
		    reply_error(cf, controlfd, &raddr, rlen, cookie, 1);
		    return 0;
		}
		local_addr = addr2bindaddr(cf, local_addr, &errmsg);
		if (local_addr == NULL) {
		    rtpp_log_write(RTPP_LOG_ERR, cf->glog,
		      "invalid local address: %s", errmsg);
		    reply_error(cf, controlfd, &raddr, rlen, cookie, 1);
		    return 0;
		}
		t[len] = c;
		cp--;
		break;

	    default:
		rtpp_log_write(RTPP_LOG_ERR, cf->glog, "unknown command modifier `%c'",
		  *cp);
		break;
	    }
	}
	if (op != DELETE && addr != NULL && port != NULL && strlen(addr) >= 7) {
	    struct sockaddr_storage tia;

	    if ((n = resolve(sstosa(&tia), pf, addr, port,
	      AI_NUMERICHOST)) == 0) {
		if (!ishostnull(sstosa(&tia))) {
		    for (i = 0; i < 2; i++) {
			ia[i] = malloc(SS_LEN(&tia));
			if (ia[i] == NULL) {
			    handle_nomem(cf, controlfd, &raddr, rlen, cookie,
			      5, ia, fds, spa, spb);
			    return 0;
			}
			memcpy(ia[i], &tia, SS_LEN(&tia));
		    }
		    /* Set port for RTCP, will work both for IPv4 and IPv6 */
		    n = ntohs(satosin(ia[1])->sin_port);
		    satosin(ia[1])->sin_port = htons(n + 1);
		}
	    } else {
		rtpp_log_write(RTPP_LOG_ERR, cf->glog, "getaddrinfo: %s",
		  gai_strerror(n));
	    }
	}
    }

    /*
     * Record and delete need special handling since they apply to all
     * streams in the session.
     */
    switch (op) {
    case DELETE:
	i = handle_delete(cf, call_id, from_tag, to_tag, weak);
	break;

    case RECORD:
	i = handle_record(cf, call_id, from_tag, to_tag);
	break;

    default:
	i = find_stream(cf, call_id, from_tag, to_tag, &spa);
	if (i != -1 && op != UPDATE)
	    i = NOT(i);
	break;
    }

    if (i == -1 && op != UPDATE) {
	rtpp_log_write(RTPP_LOG_INFO, cf->glog,
	  "%s request failed: session %s, tags %s/%s not found", rname,
	  call_id, from_tag, to_tag != NULL ? to_tag : "NONE");
	if (op == LOOKUP) {
	    for (i = 0; i < 2; i++)
		if (ia[i] != NULL)
		    free(ia[i]);
	    reply_port(cf, controlfd, &raddr, rlen, cookie, 0, lia);
	    return 0;
	}
	reply_error(cf, controlfd, &raddr, rlen, cookie, 8);
	return 0;
    }

    switch (op) {
    case DELETE:
    case RECORD:
	reply_ok(cf, controlfd, &raddr, rlen, cookie);
	return 0;

    case NOPLAY:
	handle_noplay(cf, spa, i);
	reply_ok(cf, controlfd, &raddr, rlen, cookie);
	return 0;

    case PLAY:
	handle_noplay(cf, spa, i);
	if (strcmp(codecs, "session") == 0) {
	    if (spa->codecs[i] == NULL) {
		reply_error(cf, controlfd, &raddr, rlen, cookie, 6);
		return 0;
	    }
	    codecs = spa->codecs[i];
	}
	if (playcount != 0 && handle_play(cf, spa, i, codecs, pname, playcount) != 0) {
	    reply_error(cf, controlfd, &raddr, rlen, cookie, 6);
	    return 0;
	}
	reply_ok(cf, controlfd, &raddr, rlen, cookie);
	return 0;

    case COPY:
	handle_copy(cf, spa, i, recording_name);
	reply_ok(cf, controlfd, &raddr, rlen, cookie);
	return 0;

    case QUERY:
	handle_query(cf, controlfd, &raddr, rlen, cookie, spa, i);
	return 0;

    case LOOKUP:
    case UPDATE:
	/* those are handled below */
	break;

    default:
	/* Programmatic error, should not happen */
	abort();
    }

    pidx = 1;
    lport = 0;
    if (i != -1) {
	assert(op == UPDATE || op == LOOKUP);
	if (spa->fds[i] == -1) {
	    if (local_addr != NULL) {
		spa->laddr[i] = local_addr;
	    }
	    if (create_listener(cf, spa->laddr[i], &lport, fds) == -1) {
		rtpp_log_write(RTPP_LOG_ERR, spa->log, "can't create listener");
		reply_error(cf, controlfd, &raddr, rlen, cookie, 7);
		return 0;
	    }
	    assert(spa->fds[i] == -1);
	    spa->fds[i] = fds[0];
	    assert(spa->rtcp->fds[i] == -1);
	    spa->rtcp->fds[i] = fds[1];
	    spa->ports[i] = lport;
	    spa->rtcp->ports[i] = lport + 1;
	    spa->complete = spa->rtcp->complete = 1;
	    append_session(cf, spa, i);
	    append_session(cf, spa->rtcp, i);
	}
	if (weak)
	    spa->weak[i] = 1;
	else if (op == UPDATE)
	    spa->strong = 1;
	lport = spa->ports[i];
	lia[0] = spa->laddr[i];
	pidx = (i == 0) ? 1 : 0;
	spa->ttl_mode = cf->ttl_mode;
	spa->ttl[0] = cf->max_ttl;
	spa->ttl[1] = cf->max_ttl;
	if (op == UPDATE) {
	    rtpp_log_write(RTPP_LOG_INFO, spa->log,
	      "adding %s flag to existing session, new=%d/%d/%d",
	      weak ? ( i ? "weak[1]" : "weak[0]" ) : "strong",
	      spa->strong, spa->weak[0], spa->weak[1]);
	}
	rtpp_log_write(RTPP_LOG_INFO, spa->log,
	  "lookup on ports %d/%d, session timer restarted", spa->ports[0],
	  spa->ports[1]);
    } else {
	assert(op == UPDATE);
	rtpp_log_write(RTPP_LOG_INFO, cf->glog,
	  "new session %s, tag %s requested, type %s",
	  call_id, from_tag, weak ? "weak" : "strong");

	if (local_addr != NULL) {
	    lia[0] = lia[1] = local_addr;
	    if (lia[0] == NULL) {
		rtpp_log_write(RTPP_LOG_ERR, spa->log,
		  "can't create listener: %s", t);
		reply_error(cf, controlfd, &raddr, rlen, cookie, 10);
		return 0;
	    }
	}
	if (create_listener(cf, lia[0], &lport, fds) == -1) {
	    rtpp_log_write(RTPP_LOG_ERR, cf->glog, "can't create listener");
	    reply_error(cf, controlfd, &raddr, rlen, cookie, 10);
	    return 0;
	}

	/*
	 * Session creation. If creation is requested with weak flag,
	 * set weak[0].
	 */
	spa = malloc(sizeof(*spa));
	if (spa == NULL) {
	    handle_nomem(cf, controlfd, &raddr, rlen, cookie, 11, ia,
	      fds, spa, spb);
	    return 0;
	}
	/* spb is RTCP twin session for this one. */
	spb = malloc(sizeof(*spb));
	if (spb == NULL) {
	    handle_nomem(cf, controlfd, &raddr, rlen, cookie, 12, ia,
	      fds, spa, spb);
	    return 0;
	}
	memset(spa, 0, sizeof(*spa));
	memset(spb, 0, sizeof(*spb));
	for (i = 0; i < 2; i++) {
	    spa->fds[i] = spb->fds[i] = -1;
	    spa->last_update[i] = 0;
	    spb->last_update[i] = 0;
	}
	spa->call_id = strdup(call_id);
	if (spa->call_id == NULL) {
	    handle_nomem(cf, controlfd, &raddr, rlen, cookie, 13, ia,
	      fds, spa, spb);
	    return 0;
	}
	spb->call_id = spa->call_id;
	spa->tag = strdup(from_tag);
	if (spa->tag == NULL) {
	    handle_nomem(cf, controlfd, &raddr, rlen, cookie, 14, ia,
	      fds, spa, spb);
	    return 0;
	}
	spb->tag = spa->tag;
	for (i = 0; i < 2; i++) {
	    spa->rrcs[i] = NULL;
	    spb->rrcs[i] = NULL;
	    spa->laddr[i] = lia[i];
	    spb->laddr[i] = lia[i];
	}
	spa->strong = spa->weak[0] = spa->weak[1] = 0;
	if (weak)
	    spa->weak[0] = 1;
	else
	    spa->strong = 1;
	assert(spa->fds[0] == -1);
	spa->fds[0] = fds[0];
	assert(spb->fds[0] == -1);
	spb->fds[0] = fds[1];
	spa->ports[0] = lport;
	spb->ports[0] = lport + 1;
	spa->ttl[0] = cf->max_ttl;
	spa->ttl[1] = cf->max_ttl;
	spb->ttl[0] = -1;
	spb->ttl[1] = -1;
	spa->log = rtpp_log_open(cf, "rtpproxy", spa->call_id, 0);
	spb->log = spa->log;
	spa->rtcp = spb;
	spb->rtcp = NULL;
	spa->rtp = NULL;
	spb->rtp = spa;
	spa->sridx = spb->sridx = -1;

	append_session(cf, spa, 0);
	append_session(cf, spa, 1);
	append_session(cf, spb, 0);
	append_session(cf, spb, 1);

	hash_table_append(cf, spa);

	cf->sessions_created++;
	cf->sessions_active++;
	/*
	 * Each session can consume up to 5 open file descriptors (2 RTP,
	 * 2 RTCP and 1 logging) so that warn user when he is likely to
	 * exceed 80% mark on hard limit.
	 */
	if (cf->sessions_active > (cf->nofile_limit.rlim_max * 80 / (100 * 5)) &&
	  cf->nofile_limit_warned == 0) {
	    cf->nofile_limit_warned = 1;
	    rtpp_log_write(RTPP_LOG_WARN, cf->glog, "passed 80%% "
	      "threshold on the open file descriptors limit (%d), "
	      "consider increasing the limit using -L command line "
	      "option", (int)cf->nofile_limit.rlim_max);
	}

	rtpp_log_write(RTPP_LOG_INFO, spa->log, "new session on a port %d created, "
	  "tag %s", lport, from_tag);
	if (cf->record_all != 0) {
	    handle_copy(cf, spa, 0, NULL);
	    handle_copy(cf, spa, 1, NULL);
	}
    }

    if (op == UPDATE) {
	if (cf->timeout_handler.socket_name == NULL && socket_name_u != NULL)
	    rtpp_log_write(RTPP_LOG_ERR, spa->log, "must permit notification socket with -n");
	if (spa->timeout_data.notify_tag != NULL) {
	    free(spa->timeout_data.notify_tag);
	    spa->timeout_data.notify_tag = NULL;
	}
	if (cf->timeout_handler.socket_name != NULL && socket_name_u != NULL) {
	    if (strcmp(cf->timeout_handler.socket_name, socket_name_u) != 0) {
		rtpp_log_write(RTPP_LOG_ERR, spa->log, "invalid socket name %s", socket_name_u);
		socket_name_u = NULL;
	    } else {
		rtpp_log_write(RTPP_LOG_INFO, spa->log, "setting timeout handler");
		spa->timeout_data.handler = &cf->timeout_handler;
		spa->timeout_data.notify_tag = strdup(notify_tag);
	    }
	} else if (socket_name_u == NULL && spa->timeout_data.handler != NULL) {
	    spa->timeout_data.handler = NULL;
	    rtpp_log_write(RTPP_LOG_INFO, spa->log, "disabling timeout handler");
	}
    }

    if (ia[0] != NULL && ia[1] != NULL) {
        if (spa->addr[pidx] != NULL)
            spa->last_update[pidx] = dtime;
        if (spa->rtcp->addr[pidx] != NULL)
            spa->rtcp->last_update[pidx] = dtime;
	/*
	 * Unless the address provided by client historically
	 * cannot be trusted and address is different from one
	 * that we recorded update it.
	 */
	if (spa->untrusted_addr[pidx] == 0 && !(spa->addr[pidx] != NULL &&
	  SA_LEN(ia[0]) == SA_LEN(spa->addr[pidx]) &&
	  memcmp(ia[0], spa->addr[pidx], SA_LEN(ia[0])) == 0)) {
	    rtpp_log_write(RTPP_LOG_INFO, spa->log, "pre-filling %s's address "
	      "with %s:%s", (pidx == 0) ? "callee" : "caller", addr, port);
	    if (spa->addr[pidx] != NULL) {
	        if (spa->canupdate[pidx] == 0) {
	            if (spa->prev_addr[pidx] != NULL)
	                 free(spa->prev_addr[pidx]);
	            spa->prev_addr[pidx] = spa->addr[pidx];
	        } else {
		    free(spa->addr[pidx]);
		}
	    }
	    spa->addr[pidx] = ia[0];
	    ia[0] = NULL;
	}
	if (spa->rtcp->untrusted_addr[pidx] == 0 && !(spa->rtcp->addr[pidx] != NULL &&
	  SA_LEN(ia[1]) == SA_LEN(spa->rtcp->addr[pidx]) &&
	  memcmp(ia[1], spa->rtcp->addr[pidx], SA_LEN(ia[1])) == 0)) {
	    if (spa->rtcp->addr[pidx] != NULL) {
	        if (spa->rtcp->canupdate[pidx] == 0) {
	            if (spa->rtcp->prev_addr[pidx] != NULL)
	                free(spa->rtcp->prev_addr[pidx]);
	            spa->rtcp->prev_addr[pidx] = spa->rtcp->addr[pidx];
	        } else {
		    free(spa->rtcp->addr[pidx]);
		}
	    }
	    spa->rtcp->addr[pidx] = ia[1];
	    ia[1] = NULL;
	}
    }
    spa->asymmetric[pidx] = spa->rtcp->asymmetric[pidx] = asymmetric;
    spa->canupdate[pidx] = spa->rtcp->canupdate[pidx] = NOT(asymmetric);
    if (spa->codecs[pidx] != NULL) {
	free(spa->codecs[pidx]);
	spa->codecs[pidx] = NULL;
    }
    if (codecs != NULL)
	spa->codecs[pidx] = strdup(codecs);
    if (requested_nsamples > 0) {
	rtpp_log_write(RTPP_LOG_INFO, spa->log, "RTP packets from %s "
	  "will be resized to %d milliseconds",
	  (pidx == 0) ? "callee" : "caller", requested_nsamples / 8);
    } else if (spa->resizers[pidx].output_nsamples > 0) {
	  rtpp_log_write(RTPP_LOG_INFO, spa->log, "Resizing of RTP "
	  "packets from %s has been disabled",
	  (pidx == 0) ? "callee" : "caller");
    }
    spa->resizers[pidx].output_nsamples = requested_nsamples;

    for (i = 0; i < 2; i++)
	if (ia[i] != NULL)
	    free(ia[i]);

    assert(lport != 0);
    reply_port(cf, controlfd, &raddr, rlen, cookie, lport, lia);
    return 0;
}
예제 #19
0
파일: x.c 프로젝트: childhood/parcle
int
main(int argc, char *argv[])
{
	fd_set              rfds, wfds;
	struct cn_strct    *tp, *to;
	int                 rnum, wnum, readsocks;
	int                 i;
	struct    tm       *tm_struct;

	/* initialize the masterdate we update only every second */
	_Last_loop = time(NULL);
	tm_struct  = gmtime(&_Last_loop);
	strftime( _Master_date, 32, "%a, %d %b %Y %H:%M:%S %Z", tm_struct);
#if DEBUG_VERBOSE == 2
	_Conn_count=0;
#endif
#if DEBUG_VERBOSE == 1
	printf("STARTED AT: %s\n", _Master_date);
#endif

	signal(SIGQUIT, die);
	signal(SIGTERM, die);
	signal(SIGPIPE, check_sockets);
	signal(SIGINT,  clean_on_quit);

	/* Fill up the initial connection lists; _Free_conns is just a LIFO stack,
	 * there shall never be a performance issues -> single linked only */
	_Free_count=0;
	for (i = 0; i < INITIAL_CONNS; i++) {
		tp = _Free_conns;
		_Free_conns = (struct cn_strct *) calloc(1, sizeof(struct cn_strct));
		_Free_conns->data_buf_head =
			(char *) calloc (RECV_BUFF_LENGTH, sizeof (char));
		_Free_conns->c_next = tp;
		_Free_conns->c_prev = NULL;
		_Free_conns->q_prev = NULL;
		_Free_conns->identifier = _Conn_count++;
		_Free_count++;
	}

	/* create the master listener */
	if ((_Master_sock = create_listener(HTTP_PORT)) == -1) {
		fprintf(stderr, "ERR: Couldn't bind to port %d\n",
				HTTP_PORT);
		exit(1);
	}

	/* set up LIFO queue */
	_Queue_tail = _Queue_head = NULL;
	_Queue_count = 0;

	/* create workers for application */
	for(i = 0; i < WORKER_THREADS; i++) {
		pthread_create(&_Workers[i], NULL, &run_app_thread, (void *) &i);
	}
	sleep(1);
	for(i = 0; i < WORKER_THREADS; i++) {
		pthread_detach( _Workers[i] );
	}

#if DEBUG_VERBOSE == 1
	printf("%s: listening on port %d (http)\n",
			_Server_version, HTTP_PORT);
#endif

	/* main loop */
	while (1) {
		// clean socket lists
		FD_ZERO(&rfds);
		FD_ZERO(&wfds);
		wnum = -1;

		// Add master listener to reading sockets
		FD_SET(_Master_sock, &rfds);
		rnum = _Master_sock;

		// Add the established sockets
		tp = _Busy_conns;

		/* Adding connection to the SocketSets based on state */
		while (tp != NULL) {
			if (REQSTATE_READ_HEAD == tp->req_state) {
				FD_SET(tp->net_socket, &rfds);
				rnum = (tp->net_socket > rnum) ? tp->net_socket : rnum;
			}
			if (REQSTATE_SEND_FILE == tp->req_state) {
				FD_SET(tp->net_socket, &wfds);
				wnum = (tp->net_socket > wnum) ? tp->net_socket : wnum;
			}
			tp = tp->c_next;
		}

		readsocks = select(
			(wnum > rnum) ? wnum+1 : rnum+1,
			(-1 != rnum)  ? &rfds : NULL,
			(-1 != wnum)  ? &wfds : NULL,
			(fd_set *) 0,
			NULL
		);

		// is the main listener in the read set? -> New connection
		if (FD_ISSET(_Master_sock, &rfds)) {
			handle_new_conn(_Master_sock);
			readsocks--;
		}

		// Handle the established sockets
		tp = _Busy_conns;

		while (readsocks > 0 && tp != NULL) {
			to = tp;
			tp = tp->c_next;

			if (REQSTATE_READ_HEAD == to->req_state &&
			  FD_ISSET(to->net_socket, &rfds)) {
				readsocks--;
#if DEBUG_VERBOSE == 1
				printf("WANNA RECV HEAD\n");
#endif
				read_request(to);
			}
			if (REQSTATE_SEND_FILE == to->req_state &&
			  FD_ISSET(to->net_socket, &wfds)) {
				readsocks--;
#if DEBUG_VERBOSE == 1
				printf("WANNA SEND FILE\n");
#endif
				send_file(to);
			}
		}
	}
	return 0;
}
void Config::create_all_listeners()
{
    create_listener(SERVICE_RWSPLIT);
    create_listener(SERVICE_RCONN_SLAVE);
    create_listener(SERVICE_RCONN_MASTER);
}
예제 #21
0
파일: main.c 프로젝트: childhood/parcle
static void
start_server( char *app_root, int port )
{
	struct cn_strct  *tp;
	int               i,f,r;
	struct tm        *tm_struct;
	int               pipe_set[2];

	_Conn_size = INIT_CONNS;

	/* initialize the masterdate we update only every second */
	_Last_loop = time(NULL);
	tm_struct  = gmtime(&_Last_loop);
	strftime( _Master_date, 32, "%a, %d %b %Y %H:%M:%S %Z", tm_struct);
	_Conn_count=0;
#if DEBUG_VERBOSE == 1
	printf("STARTED AT: %s\n", _Master_date);
#endif

	signal(SIGQUIT, die);
	signal(SIGTERM, die);
	signal(SIGINT, clean_on_quit);

	/* enter the directory with the application */
	if (chdir(app_root))
		clean_on_quit(2);

	/* Fill up the initial connection lists; _Free_conns is just a LIFO stack,
	 * there shall never be a performance issues -> single linked only */
	_Free_count=0;
	_Busy_count=0;
	_All_conns = (struct cn_strct **)
		malloc (pow2(_Conn_size) * sizeof( struct cn_strct *));

	for (i = 0; i < pow2(_Conn_size); i++) {
		tp = _Free_conns;
		_Free_conns = (struct cn_strct *) calloc(1, sizeof(struct cn_strct));
		_Free_conns->data_buf_head =
			(char *) calloc (RECV_BUFF_LENGTH, sizeof (char));
		_Free_conns->c_next = tp;
		_Free_conns->c_prev = NULL;
		_Free_conns->q_prev = NULL;
		_Free_conns->id     = _Conn_count;
		_All_conns[_Conn_count] = _Free_conns;
		_Free_count++;
		_Conn_count++;
	}

	/* create the master listener */
	if ((_Master_sock = create_listener(port)) == -1) {
		fprintf(stderr, "ERR: Couldn't bind to port %d\n",
				port);
		exit(1);
	}

	/* set up LIFO queue */
	_Queue_tail = _Queue_head = NULL;
	_Queue_count = 0;

	/* create workers for application */
	for(i = 0; i < WORKER_THREADS; i++) {
		pipe(pipe_set);
		_Workers[i].r_pipe = pipe_set[0];
		_Workers[i].w_pipe = pipe_set[1];
		_Workers[i].t_id   = i;
		f = fcntl(pipe_set[0], F_GETFL, 0);
		r = fcntl(pipe_set[0], F_SETFL, f | O_NONBLOCK);
		f = fcntl(pipe_set[1], F_GETFL, 0);
		r = fcntl(pipe_set[1], F_SETFL, f | O_NONBLOCK);
		pthread_create(&_Workers[i].thread,
			NULL,
			&run_app_thread,
			(void *) &_Workers[i]
		);
	}
	sleep(1);
	for(i = 0; i < WORKER_THREADS; i++) {
		pthread_detach( _Workers[i].thread );
	}

#if DEBUG_VERBOSE == 1
	printf("%s: listening on port %d (http)\n",
			_Server_version, port);
#endif

	/* Kick it off */
	server_loop();
}
예제 #22
0
파일: main.c 프로젝트: Psiphon-Inc/polipo
int psiphonMain(
        int bindAll,
        int proxyPortParam,
        int localParentProxyPortParam)
{
    FdEventHandlerPtr listener;

    initAtoms();
    CONFIG_VARIABLE(daemonise, CONFIG_BOOLEAN, "Run as a daemon");
    CONFIG_VARIABLE(pidFile, CONFIG_ATOM, "File with pid of running daemon.");

    preinitChunks();
    preinitLog();
    preinitObject();
    preinitIo();
    preinitDns();
    preinitServer();
    preinitHttp();
    preinitDiskcache();
    preinitLocal();
    preinitForbidden();
    preinitSocks();

    const int MAX_SIZE = 80;
    char proxyAddressParamLine[MAX_SIZE];
    char proxyPortParamLine[MAX_SIZE];
    char localParentProxyPortParamLine[MAX_SIZE];
    snprintf(
        proxyAddressParamLine,
        MAX_SIZE,
        (0 == bindAll) ? "proxyAddress=127.0.0.1" : "proxyAddress=0.0.0.0");
    snprintf(
        proxyPortParamLine,
        MAX_SIZE,
        "proxyPort=%d",
        proxyPortParam);
    snprintf(
        localParentProxyPortParamLine,
        MAX_SIZE,
        "socksParentProxy=127.0.0.1:%d",
        localParentProxyPortParam);

    if (0 > parseConfigLine(proxyAddressParamLine, "psiphon", 0, 0)
        || 0 > parseConfigLine(proxyPortParamLine, "psiphon", 0, 0)
        || 0 > parseConfigLine(localParentProxyPortParamLine, "psiphon", 0, 0)
        || 0 > parseConfigLine("disableLocalInterface=true", "psiphon", 0, 0)
        || 0 > parseConfigLine("logLevel=1", "psiphon", 0, 0)
        /* Allow HTTPS on all ports */
        || 0 > parseConfigLine("tunnelAllowedPorts=1-65535", "psiphon", 0, 0))
    {
        return -1;
    }

    initChunks();
    initLog();
    initObject();
    initEvents();
    initIo();
    initDns();
    initHttp();
    initServer();
    initDiskcache();
    initForbidden();
    initSocks();

    listener = create_listener(
                    proxyAddress->string,
                    proxyPort,
                    httpAccept,
                    NULL);
    if (!listener)
    {
        return -1;
    }

    eventLoop();

    return 0;
}
예제 #23
0
파일: cli.c 프로젝트: upa/lix
void wait_telnet() {
    int listener, epfd;
    struct epoll_event ev;
    struct epoll_event events[MAX_EVENTS];

    listener = create_listener();

    if((epfd = epoll_create(MAX_EVENTS)) < 0) {
        err(EXIT_FAILURE, "epoll_create");
    }

    memset(&ev, 0, sizeof ev);
    ev.events = EPOLLIN;
    ev.data.fd = listener;
    epoll_ctl(epfd, EPOLL_CTL_ADD, listener, &ev);

    while (1) {
        int i;
        int nfd = epoll_wait(epfd, events, MAX_EVENTS, -1);

        for (i = 0; i < nfd; i++) {

            if (events[i].data.fd == listener) {
                struct sockaddr_in client_addr;
                socklen_t client_addr_len = sizeof(client_addr);

                int client = accept(listener, (struct sockaddr *)&client_addr, &client_addr_len);
                if (client < 0) {
                    err(EXIT_FAILURE, "accept");
                }

                setnonblocking(client);

                memset(&ev, 0, sizeof ev);
                ev.events = EPOLLIN | EPOLLET;
                ev.data.fd = client;
                epoll_ctl(epfd, EPOLL_CTL_ADD, client, &ev);

                write(client, "> ", 2);
            } else {
                char buffer[1024];

                int client = events[i].data.fd;
                memset(buffer, 0, sizeof(buffer));
                int n = read(client, buffer, sizeof(buffer));
                if (n < 0) {
                    epoll_ctl(epfd, EPOLL_CTL_DEL, client, &ev);
                    close(client);
                    warn("read");
                } else if (n == 0) {
                    epoll_ctl(epfd, EPOLL_CTL_DEL, client, &ev);
                    close(client);
                } else {
                    if(switch_reaction(client, buffer) < 0) {
                        shutdown(client, SHUT_RDWR);
                        epoll_ctl(epfd, EPOLL_CTL_DEL, client, &ev);
                        close(client);
                    }
                }
            }
        }
    }
}