예제 #1
0
bool network_t::start_accept(
    const uint16_t port_, 
    handler_t logon_, 
    handler_t logoff_) {

    logon = logon_;
    logoff = logoff_;

    acceptor = socket(AF_INET, SOCK_STREAM, 0);
    if (acceptor < 0) {
	perror("create acceptor");
	return false;
    }
 
    set_nonblock(acceptor);
    set_reuseaddr(acceptor);

    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(9999);
    addr.sin_addr.s_addr = INADDR_ANY;
    bzero(&(addr.sin_zero), 8);
    if (bind(acceptor, (sockaddr*)&addr, sizeof(sockaddr)) < 0) {
	perror("bind");
	return false;
    }
    if (listen(acceptor, 10) < 0) {
	perror("listen");
	return false;
    }

    deal_event(epfd, EPOLL_CTL_ADD, acceptor, EPOLLIN|EPOLLET, new mydata_t);

    return true;
}
예제 #2
0
파일: flow.c 프로젝트: furen62682/neper
struct flow *addflow(int tid, int epfd, int fd, int flow_id, uint32_t events,
                     struct options *opts, struct callbacks *cb)
{
        struct epoll_event ev;
        struct flow *flow;

        if (opts->debug)
                set_debug(fd, 1, cb);
        if (opts->max_pacing_rate) {
                uint32_t m = opts->max_pacing_rate;
                setsockopt(fd, SOL_SOCKET, SO_MAX_PACING_RATE, &m, sizeof(m));
        }
        set_nonblocking(fd, cb);
        if (opts->reuseaddr)
                set_reuseaddr(fd, 1, cb);
        flow = calloc(1, sizeof(struct flow));
        flow->fd = fd;
        flow->id = flow_id;
        flow->latency = numlist_create(cb);
        ev.events = EPOLLRDHUP | events;
        ev.data.ptr = flow;
        epoll_ctl_or_die(epfd, EPOLL_CTL_ADD, fd, &ev, cb);
        LOG_INFO(cb, "tid=%d, flow_id=%d", tid, flow->id);
        return flow;
}
예제 #3
0
static int ctrl_listen(const char *host, const char *port,
                       struct addrinfo **ai, struct options *opts,
                       struct callbacks *cb)
{
        struct addrinfo *result, *rp;
        int flags = AI_PASSIVE;
        int fd_listen = 0;

        result = do_getaddrinfo(host, port, flags, opts, cb);
        for (rp = result; rp != NULL; rp = rp->ai_next) {
                fd_listen = socket(rp->ai_family, rp->ai_socktype,
                                   rp->ai_protocol);
                if (fd_listen == -1) {
                        PLOG_ERROR(cb, "socket");
                        continue;
                }
                set_reuseport(fd_listen, cb);
                set_reuseaddr(fd_listen, 1, cb);
                if (bind(fd_listen, rp->ai_addr, rp->ai_addrlen) == 0)
                        break;
                PLOG_ERROR(cb, "bind");
                do_close(fd_listen);
        }
        if (rp == NULL)
                LOG_FATAL(cb, "Could not bind");
        *ai = copy_addrinfo(rp);
        freeaddrinfo(result);
        if (listen(fd_listen, opts->listen_backlog))
                PLOG_FATAL(cb, "listen");
        return fd_listen;
}
예제 #4
0
파일: test_recv.c 프로젝트: LucidOne/Rovio
void test_recv_client(cyg_addrword_t pnetdata)
{
	int s, readlen;
	struct sockaddr_in sa, r_sa;
	struct hostent *hp;
	
	int threadid;
		
	int port = ((TEST_RECV_DATA_T*)pnetdata)->iport;
	char *pbuf = ((TEST_RECV_DATA_T*)pnetdata)->pbuf;
	char *precvbuf = ((TEST_RECV_DATA_T*)pnetdata)->precvbuf;
	
	threadid = cyg_thread_self();
	
	if((hp = gethostbyname(TEST_REMOTEFUNC_HOSTNAME, pbuf, RNT_BUFFER_LEN)) == NULL)
	{
		test_printf_error("test_recv_client");
		cyg_thread_exit();
	}
	
	memcpy(&(r_sa.sin_addr), hp->h_addr_list0, hp->h_length);
	r_sa.sin_family = AF_INET;
	r_sa.sin_port = htons(IPPORT_USERRESERVED + port);
	
	memcpy(&(sa.sin_addr), hp->h_addr_list0, hp->h_length);
	sa.sin_family = AF_INET;
	sa.sin_port = htons(IPPORT_USERRESERVED + port - TEST_RECV_SERVER_NUM);
	
	if((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC, pbuf, RNT_BUFFER_LEN)) == -1)
	{
		test_printf_error("test_recv_client");
		cyg_thread_exit();
	}
	
	if(set_reuseaddr(s, pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_recv_client");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(bind(s, (struct sockaddr*)&r_sa, sizeof(r_sa), pbuf, RNT_BUFFER_LEN) == -1)
	{
		netclose(s, pbuf, RNT_BUFFER_LEN);
		test_printf_error("test_recv_client");
		cyg_thread_exit();
	}

	if(connect(s, (struct sockaddr*)&sa, sizeof(sa), pbuf, RNT_BUFFER_LEN) == -1)
	{
		netclose(s, pbuf, RNT_BUFFER_LEN);
		test_printf_error("test_recv_client");
		cyg_thread_exit();
	}
	
	readlen = recv(s, precvbuf, TEST_RECV_MSG_LEN, 0, pbuf, RNT_BUFFER_LEN);
	netclose(s, pbuf, RNT_BUFFER_LEN);
	cyg_thread_exit();
}
예제 #5
0
void *test_netread_client(void *parg)
{
    int s, i, len;
    struct sockaddr_in sa = {0}, r_sa = {0};
    int port = *(int*)parg;
    char msg[TEST_REMOTEFUNC_MSG_LEN];
    
    if(inet_aton(TEST_NETREAD_SERVER_ADDR, &r_sa.sin_addr) == 0)
    {
        printf("inet_aton error\n");
        return NULL;
    }
    r_sa.sin_family = AF_INET;
    r_sa.sin_port = htons(IPPORT_USERRESERVED + port);
    //printf("sending to %s : %d\n", inet_ntoa(*((struct in_addr*)hp->h_addr)), r_sa.sin_port);
    
    sa.sin_addr.s_addr = INADDR_ANY;
    sa.sin_family = AF_INET;
    sa.sin_port = htons(IPPORT_USERRESERVED + port);
    
    if((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) == -1)
    {
        printf("socket error\n");
        return NULL;
    }
    printf("socket success...\n");
    
    set_reuseaddr(s);
    if(bind(s, (struct sockaddr*)&sa, sizeof(sa)) == -1)
    {
        printf("bind error\n");
        return NULL;
    }
    printf("bind success...\n");
    
    if(connect(s, (struct sockaddr*)&r_sa, sizeof(sa)) == -1)
    {
        printf("connect error\n");
        return NULL;
    }
    printf("connect success...\n");
    
    for(i = 0; i < TEST_NETREAD_WRITE_TIMES; i++)
    {
        len = sprintf(msg, "%s", MYREQUEST);
        len++;
        if((len = write(s, msg, len)) == -1)
        {
            printf("write error\n");
            break;
        }
    }
    printf("write all ok\n");
    
    close(s);
    return NULL;
 }
예제 #6
0
int
listen_to (char *port) {
  struct addrinfo *addr = get_my_addr(port);
  int sock = get_socket(addr);
  set_reuseaddr(sock);
  bind_socket(sock, addr);
  listen_socket(sock, MAX_BACKLOG);
  freeaddrinfo(addr);
  return sock;
}
예제 #7
0
파일: sock_util.c 프로젝트: noitojp/nio
int init_listen(int port,int af)
{
	int sock = -1;
	struct addrinfo hints;
	struct addrinfo *base_res = NULL;
	struct addrinfo *res_ptr = NULL;
	char portstr[32];
	int ret;

	if( port <= 0 ){
		return(-1);
	}
	sprintf(portstr,"%d",port);

	memset(&hints,'\0',sizeof(hints));
	hints.ai_family = af;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;
	ret = getaddrinfo(NULL,portstr,&hints,&base_res);
	if( ret != 0 ){
		fprintf(stderr,"ERROR: getaddrinfo: %s\n",gai_strerror(ret));
		return(-1);
	}

	for( res_ptr = base_res; res_ptr != NULL; res_ptr = res_ptr->ai_next ){
		sock = socket(res_ptr->ai_family,res_ptr->ai_socktype,res_ptr->ai_protocol);
		if( sock < 0 ){
			continue;
		}

		set_reuseaddr(sock);
		set_sndbuf(sock,65535);
		set_rcvbuf(sock,65535);
		if( bind(sock,res_ptr->ai_addr,res_ptr->ai_addrlen) < 0 ){
			fprintf(stderr,"WARN: bind: %s\n",strerror(errno));
			close(sock); sock = -1;
			continue;
		}

		if( listen(sock,BACKLOG_NUMBER) < 0 ){
			fprintf(stderr,"WARN: listen: %s\n",strerror(errno));
			close(sock); sock = -1;
			continue;
		}

		break;
	}

	freeaddrinfo(base_res); base_res = NULL;
	return(sock);
}
예제 #8
0
int create_server(int port)
{
	struct addrinfo hints;
	struct addrinfo *result, *rp;
	int s, sfd;
	char port_str[12] = {'\0'};
	
	sprintf(port_str, "%d", port);

	memset(&hints, 0, sizeof (struct addrinfo));
	hints.ai_family		= AF_UNSPEC;	/* Return IPv4 and IPv6 choices */
	hints.ai_socktype	= SOCK_STREAM;	/* We want a TCP socket */
	hints.ai_flags		= AI_PASSIVE;	/* All interfaces */

	if((s = getaddrinfo(NULL, port_str, &hints, &result)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror (s));
		return -1;
	}

	for(rp = result; rp != NULL; rp = rp->ai_next) {
		if ((sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1)
			continue;

		if(set_reuseaddr(sfd) == -1)
			abort();

		if((s = bind(sfd, rp->ai_addr, rp->ai_addrlen)) == 0)
			break;

		close(sfd);
	}

	if(rp == NULL) {
		fprintf(stderr, "Could not bind\n");
		return -1;
	}

	if ((s = make_socket_non_blocking(sfd)) == -1)
		return -1;

	if((s = listen(sfd, SOMAXCONN)) == -1) {
		perror("listen");
		return -1;
	}
	
	freeaddrinfo(result);
	printf("Server started on port %d using fd %d\n", port, sfd);
	return sfd;
}
예제 #9
0
파일: socket.c 프로젝트: BBGIP/corvus
int socket_create_server(char *bindaddr, int port)
{
    int s = -1;
    struct addrinfo *p, *servinfo;

    if (cv_getaddrinfo(bindaddr, port, &servinfo, SOCK_STREAM) == CORVUS_ERR) {
        LOG(ERROR, "socket_create_server: fail to get address info");
        return CORVUS_ERR;
    }

    for (p = servinfo; p != NULL; p = p->ai_next) {
        if ((s = cv_socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
            continue;
        }
        break;
    }

    if (p == NULL || s == -1) {
        freeaddrinfo(servinfo);
        return CORVUS_ERR;
    }

    if (socket_set_nonblocking(s) == -1) {
        close(s);
        freeaddrinfo(servinfo);
        return CORVUS_ERR;
    }

    if (set_reuseaddr(s) == -1) {
        close(s);
        freeaddrinfo(servinfo);
        return CORVUS_ERR;
    }

    if (set_reuseport(s) == -1) {
        close(s);
        freeaddrinfo(servinfo);
        return CORVUS_ERR;
    }

    if (cv_listen(s, p->ai_addr, p->ai_addrlen, 1024) == -1) {
        close(s);
        freeaddrinfo(servinfo);
        return CORVUS_ERR;
    }
    freeaddrinfo(servinfo);

    return s;
}
예제 #10
0
//绑定且开始监听
sh::int32 start_tcp_service(sockaddr_in* addr)
{
	if (addr == NULL) 
        return -1;
	sh::int32 sockfd = socket(AF_INET,SOCK_STREAM,0);
	if (sockfd < 0 ) 
        return -1;
	set_sock_noblock(sockfd,false);
	set_reuseaddr(sockfd,true);
	if (bind(sockfd,(sockaddr*)addr,sizeof(sockaddr))!=0) {
		close(sockfd);
		return -2;
	}
	if (listen(sockfd,1024)!=0) {
		close(sockfd);
		return -3;
	}
	return sockfd;
}
예제 #11
0
파일: tcp_rr.c 프로젝트: furen62682/neper
static void run_server(struct thread *t)
{
        struct options *opts = t->opts;
        struct callbacks *cb = t->cb;
        struct addrinfo *ai = t->ai;
        struct epoll_event *events;
        int fd_listen, epfd;
        char *buf;

        fd_listen = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
        if (fd_listen == -1)
                PLOG_FATAL(cb, "socket");
        set_reuseport(fd_listen, cb);
        set_reuseaddr(fd_listen, 1, cb);
        if (bind(fd_listen, ai->ai_addr, ai->ai_addrlen))
                PLOG_FATAL(cb, "bind");
        if (opts->min_rto)
                set_min_rto(fd_listen, opts->min_rto, cb);
        if (listen(fd_listen, opts->listen_backlog))
                PLOG_FATAL(cb, "listen");
        epfd = epoll_create1(0);
        if (epfd == -1)
                PLOG_FATAL(cb, "epoll_create1");
        epoll_add_or_die(epfd, t->stop_efd, EPOLLIN, cb);
        epoll_add_or_die(epfd, fd_listen, EPOLLIN, cb);
        events = calloc(opts->maxevents, sizeof(struct epoll_event));
        buf = buf_alloc(opts);
        pthread_barrier_wait(t->ready);
        while (!t->stop) {
                int ms = opts->nonblocking ? 10 /* milliseconds */ : -1;
                int nfds = epoll_wait(epfd, events, opts->maxevents, ms);
                if (nfds == -1) {
                        if (errno == EINTR)
                                continue;
                        PLOG_FATAL(cb, "epoll_wait");
                }
                server_events(t, epfd, events, nfds, fd_listen, buf);
        }
        free(buf);
        free(events);
        do_close(epfd);
}
예제 #12
0
SOCK Tcp_Listen(const char *ip,uint16_t port,int32_t backlog)
{
    struct sockaddr_in servaddr;
	SOCK sock;
	sock = OpenSocket(INET,STREAM,TCP);
	if(sock == INVALID_SOCK)
		return INVALID_SOCK;

	memset((void*)&servaddr,0,sizeof(servaddr));
	servaddr.sin_family = INET;
	if(ip)
	{
		if(inet_pton(INET,ip,&servaddr.sin_addr) < 0)
		{

			printf("%s\n",strerror(errno));
			return INVALID_SOCK;
		}
	}
	else
		servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(port);
	
	if (set_reuseaddr(sock) != 0){
		CloseSocket(sock);
		return INVALID_SOCK;
	}

	if(Bind(sock,(struct sockaddr*)&servaddr,sizeof(servaddr)) == INVALID_SOCK)
	{
		CloseSocket(sock);
		return INVALID_SOCK;
	}

	if(Listen(sock,backlog) != INVALID_SOCK)
		return sock;
	else
	{
		CloseSocket(sock);
		return INVALID_SOCK;
	}
}
예제 #13
0
/* Prepare a server socket  
 * @return -1 for error, or configured socket otherwise.  
 */
int config_socket() {

    int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock == -1) {
        fprintf(stderr, "failed to create socket\n");
        return -1;
    }

    if (set_reuseaddr(sock) == -1) {
        fprintf(stderr, "can't set SO_REUSEADDR sock option\n");
        close(sock);
        return -1;
    }

    if (set_nonblock(sock) == -1) {
        fprintf(stderr, "can't set O_NONBLOCK socket access mode\n");
        close(sock);
        return -1;
    }

    const short port = 9000;
    struct sockaddr_in sa;
    memset(&sa, 0, sizeof (sa));
    sa.sin_addr.s_addr = htonl(INADDR_ANY);
    sa.sin_family = AF_INET;
    sa.sin_port = htons(port);
    if (bind(sock, (struct sockaddr *) &sa, sizeof (struct sockaddr_in)) == -1) {
        fprintf(stderr, "bind failed\n");
        close(sock);
        return -1;
    }

    if (listen(sock, 10) == -1) {
        close(sock);
        fprintf(stderr, "listen failed\n");
        return -1;
    }

    return sock;
}
예제 #14
0
int tcp_server(const char *host, uint16_t port)
{
	//处理PIPE信号
	handle_sigpipe();

	int listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if (listenfd == -1)
		ERR_EXIT("socket");

	set_reuseaddr(listenfd, 1);
	set_reuseport(listenfd, 1);
	set_keepalive(listenfd, 0);
	set_tcpnodelay(listenfd, 0);

	SAI addr;
	memset(&addr, 0, sizeof addr);
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	if (host == NULL) {
		addr.sin_addr.s_addr = INADDR_ANY;
	} 
	else if (inet_aton(host, &addr.sin_addr) == 0) {
		struct hostent *hp = gethostbyname(host);
		if (hp == NULL)
			ERR_EXIT("gethostbyname");
		addr.sin_addr = *(struct in_addr *)hp->h_addr;
	}

	if (bind(listenfd, (SA *)&addr, sizeof addr) == -1)
		ERR_EXIT("bind");

	if (listen(listenfd, SOMAXCONN) == -1)
		ERR_EXIT("listen");

	return listenfd;
}
예제 #15
0
	bool UdpSocket::init(unsigned short local_port)
	{
		int sockfd = socket(PF_INET, SOCK_DGRAM, 0);
		if (sockfd == -1)
		{
			m_eError = ERR::INVALID_SOCKFD;
			closeSocket();
			return false;
		}

		m_sockfd = sockfd;

		int r;
		r = set_reuseaddr(m_sockfd);
		if (r)
		{
			m_eError = ERR::SETSOCKOPT_ERROR;
			closeSocket();
			return false;
		}

		struct sockaddr_in addr;
		addr.sin_family = AF_INET;
		inet_aton("0.0.0.0", &addr.sin_addr);
		addr.sin_port = htons(local_port);

		r = bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
		if (r)
		{
			m_eError = ERR::BIND_ERROR;
			closeSocket();
			return false;
		}

		return true;
	}
예제 #16
0
파일: test_recv.c 프로젝트: LucidOne/Rovio
void test_recv_server(cyg_addrword_t pnetdata)
{
	int s, new_s;
	struct sockaddr_in sa, r_sa;
	int r_sa_l = sizeof(r_sa);
	struct hostent *hp;
	
	int threadid;
		
	int port = ((TEST_RECV_DATA_T*)pnetdata)->iport;
	char *pbuf = ((TEST_RECV_DATA_T*)pnetdata)->pbuf;
	char *precvbuf = ((TEST_RECV_DATA_T*)pnetdata)->precvbuf;
	
	threadid = cyg_thread_self();
	
	if((hp = gethostbyname(TEST_REMOTEFUNC_HOSTNAME, pbuf, RNT_BUFFER_LEN)) == NULL)
	{
		test_printf_error("test_recv_server");
		cyg_thread_exit();
	}
	
	memcpy(&(r_sa.sin_addr), hp->h_addr_list0, hp->h_length);
	r_sa.sin_family = AF_INET;
	r_sa.sin_port = htons(IPPORT_USERRESERVED + port);
	
	if((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC, pbuf, RNT_BUFFER_LEN)) == -1)
	{
		test_printf_error("test_recv_server");
		cyg_thread_exit();
	}
	
	if(set_reuseaddr(s, pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_recv_server");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(bind(s, (struct sockaddr*)&r_sa, sizeof(r_sa), pbuf, RNT_BUFFER_LEN) == -1)
	{
		netclose(s, pbuf, RNT_BUFFER_LEN);
		test_printf_error("test_recv_server");
		cyg_thread_exit();
	}

	if(listen(s, 10, pbuf, RNT_BUFFER_LEN) == -1)
	{
		netclose(s, pbuf, RNT_BUFFER_LEN);
		test_printf_error("test_recv_server");
		cyg_thread_exit();
	}
	
	if((new_s = accept(s, (struct sockaddr*)&sa, (size_t*)&r_sa_l, pbuf, RNT_BUFFER_LEN)) == -1)
	{
		netclose(s, pbuf, RNT_BUFFER_LEN);
		test_printf_error("test_recv_server");
		cyg_thread_exit();
	}
	
	if(recv(-1, precvbuf, TEST_RECV_MSG_LEN, 0, pbuf, RNT_BUFFER_LEN) != -1)
	{
		test_printf_error("test_recv_server");
		goto fail;
	}
	
	if(recv(new_s, NULL, TEST_RECV_MSG_LEN, 0, pbuf, RNT_BUFFER_LEN) != -1)
	{
		test_printf_error("test_recv_server");
		goto fail;
	}
	
	// recv 0 will block and wait for client's write. (But netread wouldn't)
	/*
	if(recv(new_s, precvbuf, 0, 0, pbuf, RNT_BUFFER_LEN) != 0)
	{
		test_printf_error("test_recv_server");
		goto fail;
	}
	*/
	
	if(recv(new_s, precvbuf, -1, 0, pbuf, RNT_BUFFER_LEN) != -1)
	{
		test_printf_error("test_recv_server");
		goto fail;
	}
	
	if(recv(new_s, precvbuf, TEST_RECV_MSG_LEN, -1, pbuf, RNT_BUFFER_LEN) != -1)
	{
		test_printf_error("test_recv_server");
		goto fail;
	}
	
	if(recv(new_s, precvbuf, TEST_RECV_MSG_LEN, 0, NULL, RNT_BUFFER_LEN) != -1)
	{
		test_printf_error("test_recv_server");
		goto fail;
	}
	
	if(recv(new_s, precvbuf, TEST_RECV_MSG_LEN, 0, pbuf, 0) != -1)
	{
		test_printf_error("test_recv_server");
		goto fail;
	}
	
	test_printf_success("test_recv_server");
	
fail:
	netclose(new_s, pbuf, RNT_BUFFER_LEN);
	netclose(s, pbuf, RNT_BUFFER_LEN);
	cyg_thread_exit();
}
예제 #17
0
void test_getsockname_server(cyg_addrword_t pnetdata)
{
	int s, new_s;
	struct sockaddr_in sa, r_sa;
	int r_sa_l = sizeof(r_sa);
	struct hostent *hp;
	
	int port = ((TEST_GETSOCKNAME_DATA_T*)pnetdata)->iport;
	char *pbuf = ((TEST_GETSOCKNAME_DATA_T*)pnetdata)->pbuf;
	
	if((hp = gethostbyname(TEST_REMOTEFUNC_HOSTNAME, pbuf, RNT_BUFFER_LEN)) == NULL)
	{
		test_printf_error("test_getsockname_entry");
		cyg_thread_exit();
	}
	
	memcpy(&(r_sa.sin_addr), hp->h_addr_list0, hp->h_length);
	r_sa.sin_family = AF_INET;
	r_sa.sin_port = htons(IPPORT_USERRESERVED + port);
	
	if((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC, pbuf, RNT_BUFFER_LEN)) == -1)
	{
		test_printf_error("test_getsockname_entry");
		cyg_thread_exit();
	}
	
	if(set_reuseaddr(s, pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_getsockname_entry");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(bind(s, (struct sockaddr*)&r_sa, sizeof(r_sa), pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_getsockname_entry");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(getsockname(-1, (struct sockaddr*)&sa, &r_sa_l, pbuf, RNT_BUFFER_LEN) != -1)
	{
		test_printf_error("getsockname");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(getsockname(s, NULL, &r_sa_l, pbuf, RNT_BUFFER_LEN) != -1)
	{
		test_printf_error("getsockname");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(getsockname(s, (struct sockaddr*)&sa, NULL, pbuf, RNT_BUFFER_LEN) != -1)
	{
		test_printf_error("getsockname");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	r_sa_l = 0;
	if(getsockname(s, (struct sockaddr*)&sa, &r_sa_l, pbuf, RNT_BUFFER_LEN) != 0)
	{
		test_printf_error("getsockname");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	r_sa_l = sizeof(r_sa);
	
	if(getsockname(s, (struct sockaddr*)&sa, &r_sa_l, NULL, RNT_BUFFER_LEN) != -1)
	{
		test_printf_error("getsockname");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(getsockname(s, (struct sockaddr*)&sa, &r_sa_l, pbuf, 0) != -1)
	{
		test_printf_error("getsockname");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(listen(s, 10, pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_getsockname_entry");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if((new_s = accept(s, (struct sockaddr*)&sa, (size_t*)&r_sa_l, pbuf, RNT_BUFFER_LEN)) == -1)
	{
		test_printf_error("test_getsockname_entry");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(getpeername(-1, (struct sockaddr*)&sa, &r_sa_l, pbuf, RNT_BUFFER_LEN) != -1)
	{
		test_printf_error("getpeername");
		netclose(new_s, pbuf, RNT_BUFFER_LEN);
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(getpeername(new_s, NULL, &r_sa_l, pbuf, RNT_BUFFER_LEN) != -1)
	{
		test_printf_error("getpeername");
		netclose(new_s, pbuf, RNT_BUFFER_LEN);
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(getpeername(new_s, (struct sockaddr*)&sa, NULL, pbuf, RNT_BUFFER_LEN) != -1)
	{
		test_printf_error("getpeername");
		netclose(new_s, pbuf, RNT_BUFFER_LEN);
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	r_sa_l = 0;
	if(getpeername(new_s, (struct sockaddr*)&sa, &r_sa_l, pbuf, RNT_BUFFER_LEN) != 0)
	{
		test_printf_error("getpeername");
		netclose(new_s, pbuf, RNT_BUFFER_LEN);
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	r_sa_l = sizeof(r_sa);
	
	if(getpeername(new_s, (struct sockaddr*)&sa, &r_sa_l, NULL, RNT_BUFFER_LEN) != -1)
	{
		test_printf_error("getpeername");
		netclose(new_s, pbuf, RNT_BUFFER_LEN);
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(getpeername(new_s, (struct sockaddr*)&sa, &r_sa_l, pbuf, 0) != -1)
	{
		test_printf_error("getpeername");
		netclose(new_s, pbuf, RNT_BUFFER_LEN);
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	
	test_printf_success("test_getsockname_entry");
	netclose(new_s, pbuf, RNT_BUFFER_LEN);
	netclose(s, pbuf, RNT_BUFFER_LEN);
	cyg_thread_exit();
}
예제 #18
0
int server_main(char *home, char *dev, char *port, int udp, int ipv4, int log)
{
	int lfd = -1, kdpfd, nfds, nfd, curfds, efd[2], refd[2], tunfd, i;
	unsigned int cpus = 0, threads, udp_cpu = 0;
	ssize_t ret;
	struct epoll_event *events;
	struct addrinfo hints, *ahead, *ai;

	auth_log = !!log;
	openlog("curvetun", LOG_PID | LOG_CONS | LOG_NDELAY, LOG_DAEMON);

	syslog(LOG_INFO, "curvetun server booting!\n");
	syslog_maybe(!auth_log, LOG_INFO, "curvetun user logging disabled!\n");

	parse_userfile_and_generate_user_store_or_die(home);

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM;
	hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP;
	hints.ai_flags = AI_PASSIVE;

	ret = getaddrinfo(NULL, port, &hints, &ahead);
	if (ret < 0)
		syslog_panic("Cannot get address info!\n");

	for (ai = ahead; ai != NULL && lfd < 0; ai = ai->ai_next) {
		lfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
		if (lfd < 0)
			continue;
		if (ai->ai_family == AF_INET6) {
#ifdef IPV6_V6ONLY
			ret = set_ipv6_only(lfd);
			if (ret < 0) {
				close(lfd);
				lfd = -1;
				continue;
			}
#else
			close(lfd);
			lfd = -1;
			continue;
#endif /* IPV6_V6ONLY */
		}

		set_reuseaddr(lfd);
		set_mtu_disc_dont(lfd);

		ret = bind(lfd, ai->ai_addr, ai->ai_addrlen);
		if (ret < 0) {
			close(lfd);
			lfd = -1;
			continue;
		}

		if (!udp) {
			ret = listen(lfd, 5);
			if (ret < 0) {
				close(lfd);
				lfd = -1;
				continue;
			}
		}

		if (ipv4 == -1) {
			ipv4 = (ai->ai_family == AF_INET6 ? 0 :
				(ai->ai_family == AF_INET ? 1 : -1));
		}

		syslog_maybe(auth_log, LOG_INFO, "curvetun on IPv%d via %s "
			     "on port %s!\n", ai->ai_family == AF_INET ? 4 : 6,
			     udp ? "UDP" : "TCP", port);
		syslog_maybe(auth_log, LOG_INFO, "Allowed overlay proto is "
			     "IPv%d!\n", ipv4 ? 4 : 6);
	}

	freeaddrinfo(ahead);

	if (lfd < 0 || ipv4 < 0)
		syslog_panic("Cannot create socket!\n");

	tunfd = tun_open_or_die(dev ? dev : DEVNAME_SERVER, IFF_TUN | IFF_NO_PI);

	pipe_or_die(efd, O_NONBLOCK);
	pipe_or_die(refd, O_NONBLOCK);

	set_nonblocking(lfd);

	events = xzmalloc(MAX_EPOLL_SIZE * sizeof(*events));
	for (i = 0; i < MAX_EPOLL_SIZE; ++i)
		events[i].data.fd = -1;

	kdpfd = epoll_create(MAX_EPOLL_SIZE);
	if (kdpfd < 0)
		syslog_panic("Cannot create socket!\n");

	set_epoll_descriptor(kdpfd, EPOLL_CTL_ADD, lfd,
			     udp ? EPOLLIN | EPOLLET | EPOLLONESHOT : EPOLLIN);
	set_epoll_descriptor(kdpfd, EPOLL_CTL_ADD, efd[0], EPOLLIN);
	set_epoll_descriptor(kdpfd, EPOLL_CTL_ADD, refd[0], EPOLLIN);
	set_epoll_descriptor(kdpfd, EPOLL_CTL_ADD, tunfd,
			     EPOLLIN | EPOLLET | EPOLLONESHOT);
	curfds = 4;

	trie_init();

	cpus = get_number_cpus_online();
	threads = cpus * THREADS_PER_CPU;
	if (!ispow2(threads))
		syslog_panic("Thread number not power of two!\n");

	threadpool = xzmalloc(sizeof(*threadpool) * threads);
	thread_spawn_or_panic(cpus, efd[1], refd[1], tunfd, ipv4, udp);

	init_cpusched(threads);

	register_socket(tunfd);
	register_socket(lfd);

	syslog(LOG_INFO, "curvetun up and running!\n");

	while (likely(!sigint)) {
		nfds = epoll_wait(kdpfd, events, curfds, -1);
		if (nfds < 0) {
			syslog(LOG_ERR, "epoll_wait error: %s\n",
			       strerror(errno));
			break;
		}

		for (i = 0; i < nfds; ++i) {
			if (unlikely(events[i].data.fd < 0))
				continue;

			if (events[i].data.fd == lfd && !udp) {
				int ncpu;
				char hbuff[256], sbuff[256];
				struct sockaddr_storage taddr;
				socklen_t tlen;

				tlen = sizeof(taddr);
				nfd = accept(lfd, (struct sockaddr *) &taddr,
					     &tlen);
				if (nfd < 0) {
					syslog(LOG_ERR, "accept error: %s\n",
					       strerror(errno));
					continue;
				}

				if (curfds + 1 > MAX_EPOLL_SIZE) {
					close(nfd);
					continue;
				}

				curfds++;

				ncpu = register_socket(nfd);

				memset(hbuff, 0, sizeof(hbuff));
				memset(sbuff, 0, sizeof(sbuff));
				getnameinfo((struct sockaddr *) &taddr, tlen,
					    hbuff, sizeof(hbuff),
					    sbuff, sizeof(sbuff),
					    NI_NUMERICHOST | NI_NUMERICSERV);

				syslog_maybe(auth_log, LOG_INFO, "New connection "
					     "from %s:%s (%d active client connections) -  id %d on CPU%d",
					     hbuff, sbuff, curfds-4, nfd, ncpu);

				set_nonblocking(nfd);
				set_socket_keepalive(nfd);
				set_tcp_nodelay(nfd);
				ret = set_epoll_descriptor2(kdpfd, EPOLL_CTL_ADD,
						nfd, EPOLLIN | EPOLLET | EPOLLONESHOT);
				if (ret < 0) {
					close(nfd);
					curfds--;
					continue;
				}
			} else if (events[i].data.fd == refd[0]) {
				int fd_one;

				ret = read_exact(refd[0], &fd_one,
						 sizeof(fd_one), 1);
				if (ret != sizeof(fd_one) || fd_one <= 0)
					continue;

				ret = set_epoll_descriptor2(kdpfd, EPOLL_CTL_MOD,
						fd_one, EPOLLIN | EPOLLET | EPOLLONESHOT);
				if (ret < 0) {
					close(fd_one);
					continue;
				}
			} else if (events[i].data.fd == efd[0]) {
				int fd_del, test;

				ret = read_exact(efd[0], &fd_del,
						 sizeof(fd_del), 1);
				if (ret != sizeof(fd_del) || fd_del <= 0)
					continue;

				ret = read(fd_del, &test, sizeof(test));
				if (ret < 0 && errno == EBADF)
					continue;

				ret = set_epoll_descriptor2(kdpfd, EPOLL_CTL_DEL,
						fd_del, 0);
				if (ret < 0) {
					close(fd_del);
					continue;
				}

				close(fd_del);
				curfds--;
				unregister_socket(fd_del);

				syslog_maybe(auth_log, LOG_INFO, "Closed connection "
					     "with id %d (%d active client connections remain)\n", fd_del,
					     curfds-4);
			} else {
				int cpu, fd_work = events[i].data.fd;

				if (!udp)
					cpu = socket_to_cpu(fd_work);
				else
					udp_cpu = (udp_cpu + 1) & (threads - 1);

				write_exact(threadpool[udp ? udp_cpu : cpu].efd[1],
					    &fd_work, sizeof(fd_work), 1);
			}
		}
	}

	syslog(LOG_INFO, "curvetun prepare shut down!\n");

	close(lfd);
	close(efd[0]);
	close(efd[1]);
	close(refd[0]);
	close(refd[1]);
	close(tunfd);

	thread_finish(cpus);

	xfree(threadpool);
	xfree(events);

	unregister_socket(lfd);
	unregister_socket(tunfd);

	destroy_cpusched();

	trie_cleanup();

	destroy_user_store();

	syslog(LOG_INFO, "curvetun shut down!\n");
	closelog();

	return 0;
}
예제 #19
0
void test_recvfrom_entry(char *pBuf, int iBufLen)
{
	int s, recvfromlen;
	struct sockaddr_in sa, r_sa;
	int r_sa_l = sizeof(r_sa);
	
	int port = TEST_RECVFROM_SERVER_BEGIN_PORT;
	char *precvfrombuf = msg;
	
	r_sa.sin_addr.s_addr = htonl(INADDR_ANY);
	r_sa.sin_family = AF_INET;
	r_sa.sin_port = htons(IPPORT_USERRESERVED + port);
	
	if((s = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC, pBuf, iBufLen)) == -1)
	{
		test_printf_error("test_recvfrom_entry");
		return;
	}
	
	if(set_reuseaddr(s, pBuf, iBufLen) == -1)
	{
		test_printf_error("test_recvfrom_entry");
		netclose(s, pBuf, iBufLen);
		return;
	}
	
	if(bind(s, (struct sockaddr*)&r_sa, sizeof(r_sa), pBuf, iBufLen) == -1)
	{
		test_printf_error("test_recvfrom_entry");
		netclose(s, pBuf, iBufLen);
		return;
	}

	recvfromlen = recvfrom(-1, precvfrombuf, TEST_RECVFROM_MSG_LEN, 0, 
							(struct sockaddr*)&sa, &r_sa_l, pBuf, iBufLen);
	if(recvfromlen >= 0)
	{
		test_printf_error("test_recvfrom_entry");
		netclose(s, pBuf, iBufLen);
		return;
	}
	
	recvfromlen = recvfrom(s, NULL, TEST_RECVFROM_MSG_LEN, 0, 
							(struct sockaddr*)&sa, &r_sa_l, pBuf, iBufLen);
	if(recvfromlen >= 0)
	{
		test_printf_error("test_recvfrom_entry");
		netclose(s, pBuf, iBufLen);
		return;
	}
	
	recvfromlen = recvfrom(s, precvfrombuf, -1, 0, 
							(struct sockaddr*)&sa, &r_sa_l, pBuf, iBufLen);
	if(recvfromlen >= 0)
	{
		test_printf_error("test_recvfrom_entry");
		netclose(s, pBuf, iBufLen);
		return;
	}
	
	recvfromlen = recvfrom(s, precvfrombuf, TEST_RECVFROM_MSG_LEN, 0, 
							(struct sockaddr*)&sa, &r_sa_l, NULL, iBufLen);
	if(recvfromlen >= 0)
	{
		test_printf_error("test_recvfrom_entry");
		netclose(s, pBuf, iBufLen);
		return;
	}
	
	recvfromlen = recvfrom(s, precvfrombuf, TEST_RECVFROM_MSG_LEN, 0, 
							(struct sockaddr*)&sa, &r_sa_l, pBuf, 0);
	if(recvfromlen >= 0)
	{
		test_printf_error("test_recvfrom_entry");
		netclose(s, pBuf, iBufLen);
		return;
	}
	
	test_printf_success("test_recvfrom_entry");
	netclose(s, pBuf, iBufLen);
}
예제 #20
0
void test_sendmsg_server(cyg_addrword_t pnetdata)
{
	int s, i, sendmsglen;
	struct sockaddr_in sa, r_sa;
	struct hostent *hp;
	struct msghdr msghdr_msg;
	struct iovec *piov;
	int j;
	int perIov_len;
	char tmp[TEST_SENDMSG_MSG_LEN];
	
	int threadid;
		
	int port = ((TEST_SENDMSG_DATA_T*)pnetdata)->iport;
	char *pbuf = ((TEST_SENDMSG_DATA_T*)pnetdata)->pbuf;
	
	threadid = port;
	
    if(inet_aton(TEST_SENDMSG_SERVER_ADDR, &sa.sin_addr, pbuf, RNT_BUFFER_LEN) == 0)
    {
		test_printf_error("test_sendmsg_server");
		cyg_thread_exit();
    }
    sa.sin_family = AF_INET;
    sa.sin_port = htons(IPPORT_USERRESERVED + port);
    
	if((hp = gethostbyname(TEST_REMOTEFUNC_HOSTNAME, pbuf, RNT_BUFFER_LEN)) == NULL)
	{
		test_printf_error("test_sendmsg_server");
		cyg_thread_exit();
	}
	
	memcpy(&(r_sa.sin_addr), hp->h_addr_list0, hp->h_length);
	r_sa.sin_family = AF_INET;
	r_sa.sin_port = htons(IPPORT_USERRESERVED + port);
	
	if((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC, pbuf, RNT_BUFFER_LEN)) == -1)
	{
		test_printf_error("test_sendmsg_server");
		cyg_thread_exit();
	}
	
	if(set_reuseaddr(s, pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_sendmsg_server");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(bind(s, (struct sockaddr*)&r_sa, sizeof(r_sa), pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_sendmsg_server");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}

    if(connect(s, (struct sockaddr*)&sa, sizeof(sa), pbuf, RNT_BUFFER_LEN) == -1)
    {
		test_printf_error("test_sendmsg_server");
		cyg_thread_exit();
    }
	
    for(i = 0; i < TEST_SENDMSG_WRITE_TIMES; i++)
	{
		strcpy(tmp, TEST_SENDMSG_MSG);
		
		perIov_len = TEST_SENDMSG_MSG_PART_LEN;
		piov = malloc(TEST_SENDMSG_MSG_PARTS*sizeof(struct iovec));
		if(piov == NULL)
		{
			test_printf_error("test_sendmsg_server");
			goto fail;
		}
		memset(piov, 0, TEST_SENDMSG_MSG_PARTS*sizeof(struct iovec));
		
		for(j = 0; j < TEST_SENDMSG_MSG_PARTS; j++)
		{
			piov[j].iov_base = malloc(perIov_len);
			if(piov[j].iov_base == NULL)
			{
				test_printf_error("test_sendmsg_server");
				for(i = 0; i < j; i++) free(piov[j].iov_base);
				if(piov != NULL) free(piov);
				goto fail;
			}
			piov[j].iov_len = perIov_len;
			memcpy(piov[j].iov_base, tmp + j * TEST_SENDMSG_MSG_PART_LEN, TEST_SENDMSG_MSG_PART_LEN);
		}
		
		msghdr_msg.msg_name = NULL;
		msghdr_msg.msg_namelen = 0;
		msghdr_msg.msg_iov = piov;
		msghdr_msg.msg_iovlen = TEST_SENDMSG_MSG_PARTS;
		msghdr_msg.msg_control = NULL;
		msghdr_msg.msg_controllen = 0;
		msghdr_msg.msg_flags = 0;
		
		sendmsglen = sendmsg(s, &msghdr_msg, 0, pbuf, RNT_BUFFER_LEN);
		if(sendmsglen < 0)
		{
			test_printf_error("test_sendmsg_server");
			for(j = 0; j < TEST_SENDMSG_MSG_PARTS; j++)
			{
				if(piov[j].iov_base != NULL) free(piov[j].iov_base);
			}
			if(piov != NULL) free(piov);
			break;
		}
		
		for(j = 0; j < TEST_SENDMSG_MSG_PARTS; j++)
		{
			if(piov[j].iov_base != NULL) free(piov[j].iov_base);
		}
		if(piov != NULL) free(piov);
	}
	
	test_printf_success("test_sendmsg_server");
	
fail:	
	netclose(s, pbuf, RNT_BUFFER_LEN);
	cyg_thread_exit();
}
예제 #21
0
파일: titus.cpp 프로젝트: AGWA/titus
int main (int argc, char** argv)
try {
	init_signals();

	// Initialize OpenSSL
	ERR_load_crypto_strings();
	SSL_library_init();
	SSL_load_error_strings();

	// This cipher list is the "Intermediate compatibility" list from https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29 as of 2014-12-09
	vhost_defaults.ciphers = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
	vhost_defaults.dhgroup = make_dh(dh_group14_prime, dh_group14_generator); // 2048 bit group
	vhost_defaults.ecdhcurve = get_ecdhcurve("prime256v1"); // a.k.a. secp256r1

	// Set default SSL options, which can be overridden by config file
	vhost_defaults.ssl_options[SSL_OP_NO_COMPRESSION] = true;
	vhost_defaults.ssl_options[SSL_OP_NO_SSLv3] = true;
	vhost_defaults.ssl_options[SSL_OP_NO_TLSv1] = false;
	vhost_defaults.ssl_options[SSL_OP_NO_TLSv1_1] = false;
	vhost_defaults.ssl_options[SSL_OP_NO_TLSv1_2] = false;
	vhost_defaults.ssl_options[SSL_OP_CIPHER_SERVER_PREFERENCE] = true;

	// These can't be overriden by config file:
	vhost_defaults.ssl_options[SSL_OP_SINGLE_DH_USE] = true;
	vhost_defaults.ssl_options[SSL_OP_SINGLE_ECDH_USE] = true;
	vhost_defaults.ssl_options[SSL_OP_NO_SSLv2] = true;

	// Command line arguments come in pairs of the form "--name value" and correspond
	// directly to the name/value option pairs in the config file (a la OpenVPN).
	for (int i = 1; i < argc; ) {
		if (std::strncmp(argv[i], "--", 2) == 0 && i + 1 < argc) {
			process_config_param(argv[i] + 2, argv[i+1]);
			i += 2;
		} else {
			std::clog << argv[0] << ": Bad arguments" << std::endl;
			return 2;
		}
	}

	if (vhost_configs.empty()) {
		// No vhosts specified, so add one implicitly that matches all local addresses / SNI names.
		// It will use the options from vhost_defaults.
		vhost_configs.emplace_back();
	}

	for (size_t i = 0; i < vhost_configs.size(); ++i) {
		vhosts.emplace_back();
		Vhost&		vhost(vhosts.back());
		Vhost_config&	config(vhost_configs[i]);

		vhost.id = i;
		vhost.servername_set = config.servername_set;
		vhost.servername = config.servername;
		init_ssl_ctx(vhost, config);
		resolve_addresses(vhost, config);
	}
	// Free up some memory that's no longer needed:
	vhost_configs.clear();
	vhost_defaults = Basic_vhost_config();

	// Listen
	listening_sock = socket(AF_INET6, SOCK_STREAM, 0);
	if (listening_sock == -1) {
		throw System_error("socket", "", errno);
	}
	set_reuseaddr(listening_sock);
	set_not_v6only(listening_sock);
	if (transparent == TRANSPARENT_ON) {
		set_transparent(listening_sock);
	}

	// TODO: support binding to specific IP addresses
	struct sockaddr_in6	listening_address;
	std::memset(&listening_address, '\0', sizeof(listening_address));
	listening_address.sin6_family = AF_INET6;
	listening_address.sin6_addr = in6addr_any;
	listening_address.sin6_port = htons(listening_port);
	if (bind(listening_sock, reinterpret_cast<const struct sockaddr*>(&listening_address), sizeof(listening_address)) == -1) {
		throw System_error("bind", "", errno);
	}

	if (listen(listening_sock, SOMAXCONN) == -1) {
		throw System_error("listen", "", errno);
	}

	// Set up UNIX domain socket for communicating with the key server.
	// Put it in a temporary directory with restrictive permissions so
	// other users can't traverse its path.  We have to use a named
	// socket as opposed to a socketpair because we need every child process
	// to communicate with the key server using its own socket.  (Duping one
	// end of a socketpair wouldn't work because then every child would
	// be referring to the same underlying socket, which provides
	// insufficient isolation.)
	temp_directory = make_temp_directory();
	filedesc keyserver_sock(make_unix_socket(temp_directory + "/server.sock", &keyserver_sockaddr, &keyserver_sockaddr_len));
	if (listen(keyserver_sock, SOMAXCONN) == -1) {
		throw System_error("listen", "", errno);
	}

	// Write PID file, daemonize, etc.
	std::ofstream		pid_file_out;
	if (!pid_file.empty()) {
		// Open PID file before forking so we can report errors
		pid_file_out.open(pid_file.c_str(), std::ofstream::out | std::ofstream::trunc);
		if (!pid_file_out) {
			throw Configuration_error("Unable to open PID file " + pid_file + " for writing.");
		}
		pid_file_created = true;
	}
	if (run_as_daemon) {
		daemonize();
	}
	if (pid_file_out) {
		pid_file_out << getpid() << '\n';
		pid_file_out.close();
	}

	// Spawn the master key server process
	keyserver_pid = spawn(keyserver_main, std::move(keyserver_sock));

	// Spawn spare children to accept() and service connections
	if (pipe(children_pipe) == -1) {
		throw System_error("pipe", "", errno);
	}
	set_nonblocking(children_pipe[0], true);

	spawn_children();

	// Wait for signals and readability on children_pipe
	sigset_t		empty_sigset;
	sigemptyset(&empty_sigset);
	fd_set			readfds;
	FD_ZERO(&readfds);
	FD_SET(children_pipe[0], &readfds);

	is_running = 1;
	struct timespec		timeout = { 2, 0 };
	int			select_res = 0;
	while (is_running && ((select_res = pselect(children_pipe[0] + 1, &readfds, NULL, NULL, failed_children ? &timeout : NULL, &empty_sigset)) >= 0 || errno == EINTR)) {
		if (failed_children && std::time(NULL) >= last_failed_child_time + 2) {
			failed_children = 0;
		}
		if (pending_sigchld) {
			on_sigchld();
			pending_sigchld = 0;
		}
		if (select_res > 0) {
			read_children_pipe();
		}
		FD_SET(children_pipe[0], &readfds);
	}

	if (is_running && select_res == -1) {
		throw System_error("pselect", "", errno);
	}


	cleanup();
	return 0;
} catch (const System_error& error) {
	std::clog << "titus: System error: " << error.syscall;
	if (!error.target.empty()) {
		std::clog << ": " << error.target;
	}
	std::clog << ": " << std::strerror(error.number) << std::endl;
	cleanup();
	return 3;
} catch (const Openssl_error& error) {
	std::clog << "titus: OpenSSL error: " << error.message() << std::endl;
	cleanup();
	return 4;
} catch (const Configuration_error& error) {
	std::clog << "titus: Configuration error: " << error.message << std::endl;
	cleanup();
	return 5;
} catch (const Too_many_failed_children& error) {
	// TODO: better error reporting when this happens
	std::clog << "titus: Too many child processes failed." << std::endl;
	cleanup();
	return 7;
} catch (const Keyserver_died& error) {
	// TODO: better error reporting when this happens
	std::clog << "titus: Key server died." << std::endl;
	cleanup();
	return 8;
}
예제 #22
0
파일: stun.c 프로젝트: 0x0mar/netsniff-ng
static int stun_test(const char *server_ip, int server_port,
		     int tun_port)
{
	int ret, sock;
	uint8_t pkt[256];
	uint8_t rpkt[256];
	size_t len, off, max;
	struct in_addr in;
	struct timeval timeout;
	struct stun_header *hdr, *rhdr;
	struct stun_attrib *attr;
	struct stun_mapped_addr *addr;
	struct sockaddr_in saddr, daddr;
	fd_set fdset;

	if (!server_ip)
		return -EINVAL;

	sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (sock < 0)
		panic("Cannot obtain socket!\n");

	set_reuseaddr(sock);

	memset(&saddr, 0, sizeof(saddr));
	saddr.sin_family = PF_INET;
	saddr.sin_port = htons(tun_port);
	saddr.sin_addr.s_addr = INADDR_ANY;

	ret = bind(sock, (struct sockaddr *) &saddr, sizeof(saddr));
	if (ret)
		panic("Cannot bind udp socket!\n");

	len = REQUEST_LEN;
	hdr = (struct stun_header *) pkt;
	hdr->type = htons(BINDING_REQUEST);
	hdr->len = 0;
	hdr->magic_cookie = ID_COOKIE_FIELD;
	hdr->transid[0] = htonl(rand());
	hdr->transid[1] = htonl(rand());
	hdr->transid[2] = htonl(rand());

	daddr.sin_family = PF_INET;
	daddr.sin_port = htons(server_port);
	daddr.sin_addr.s_addr = inet_addr(server_ip);

	ret = sendto(sock, pkt, len, 0, (struct sockaddr *) &daddr,
		     sizeof(daddr));
	if (ret != len) {
		printf("Error sending request (%s)!\n", strerror(errno));
		goto close_error;
	}

	timeout.tv_sec = TIMEOUT / 1000;
	timeout.tv_usec = (TIMEOUT % 1000) * 1000;

	FD_ZERO(&fdset);
	FD_SET(sock, &fdset);

	ret = select(sock + 1, &fdset, NULL, NULL, &timeout);
	if (ret <= 0) {
		printf("STUN server timeout!\n");
		goto close_error;
	}

	memset(rpkt, 0, sizeof(rpkt));
	len = read(sock, rpkt, sizeof(rpkt));

	close(sock);

	if (len < REQUEST_LEN) {
		printf("Bad STUN response (%s)!\n", strerror(errno));
		return -EIO;
	}

	rhdr = (struct stun_header *) rpkt;
	if (ntohs(rhdr->type) != BINDING_RESPONSE) {
		printf("Wrong STUN response type!\n");
		return -EIO;
	}

	if (rhdr->len == 0) {
		printf("No attributes in STUN response!\n");
		return -EIO;
	}

	if (rhdr->magic_cookie != hdr->magic_cookie ||
	    rhdr->transid[0] != hdr->transid[0] ||
	    rhdr->transid[1] != hdr->transid[1] ||
	    rhdr->transid[2] != hdr->transid[2]) {
		printf("Got wrong STUN transaction id!\n");
		return -EIO;
	}

	off = REQUEST_LEN;
	max = ntohs(rhdr->len) + REQUEST_LEN;

	while (off + 8 < max) {
		attr = (struct stun_attrib *) (rpkt + off);
		if (ntohs(attr->type) != MAPPED_ADDRESS)
			goto next;

		addr = (struct stun_mapped_addr *) (rpkt + off + 4);
		if (addr->family != 0x1)
			break;

		in.s_addr = addr->ip;
		printf("Public mapping %s:%u!\n",
		       inet_ntoa(in), ntohs(addr->port));
		break;
next:
		off += 4;
		off += ntohs(attr->len);
	}

	return 0;
close_error:
	close(sock);
	return -EIO;
}
예제 #23
0
void test_tcp_socket_client(cyg_addrword_t pnetdata)
{
	int s, i, len;
	char msg;
	struct sockaddr_in sa, r_sa;
	struct hostent *hp;
	
	int threadid;
		
	int port = ((TEST_TCP_SOCKET_DATA_T*)pnetdata)->iport;
	char *pbuf = ((TEST_TCP_SOCKET_DATA_T*)pnetdata)->pbuf;
	
	threadid = cyg_thread_self();
	
	if((hp = gethostbyname(TEST_REMOTEFUNC_HOSTNAME, pbuf, RNT_BUFFER_LEN)) == NULL)
	{
		test_printf_error("test_tcp_socket_client");
		cyg_thread_exit();
	}
	
	memcpy(&(r_sa.sin_addr), hp->h_addr_list0, hp->h_length);
	r_sa.sin_family = AF_INET;
	r_sa.sin_port = htons(IPPORT_USERRESERVED + port);
	
	memcpy(&(sa.sin_addr), hp->h_addr_list0, hp->h_length);
    sa.sin_family = AF_INET;
    sa.sin_port = htons(IPPORT_USERRESERVED + port - TEST_TCP_SOCKET_SERVER_NUM);
    
    for(i = 0; i < TEST_TCP_ACCEPT_SOCKET_TIMES; i++)
    {
		if((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC, pbuf, RNT_BUFFER_LEN)) == -1)
		{
			test_printf_error("test_tcp_socket_client");
			cyg_thread_exit();
		}
		
		if(set_reuseaddr(s, pbuf, RNT_BUFFER_LEN) == -1)
		{
			test_printf_error("test_tcp_socket_client");
			netclose(s, pbuf, RNT_BUFFER_LEN);
			cyg_thread_exit();
		}
		
		if(bind(s, (struct sockaddr*)&r_sa, sizeof(r_sa), pbuf, RNT_BUFFER_LEN) == -1)
		{
			test_printf_error("test_tcp_socket_client");
			netclose(s, pbuf, RNT_BUFFER_LEN);
			cyg_thread_exit();
		}
    
	    while(connect(s, (struct sockaddr*)&sa, sizeof(sa), pbuf, RNT_BUFFER_LEN) == -1) NULL;
	    
		if((len = netread(s, &msg, sizeof(msg), pbuf, RNT_BUFFER_LEN)) == -1)
		{
			test_printf_error("test_tcp_socket_client");
			break;
		}
		if(len == 0)
		{
			netclose(s, pbuf, RNT_BUFFER_LEN);
			continue;
		}
    }
    
	test_printf_success("test_tcp_socket_client");
	cyg_thread_exit();
}
예제 #24
0
파일: test_send.c 프로젝트: LucidOne/Rovio
void test_send_server(cyg_addrword_t pnetdata)
{
	int s, i, len, sendlen;
	struct sockaddr_in sa, r_sa;
	struct hostent *hp;
	
	int threadid;
		
	int port = ((TEST_SEND_DATA_T*)pnetdata)->iport;
	char *pbuf = ((TEST_SEND_DATA_T*)pnetdata)->pbuf;
	char *psendbuf = ((TEST_SEND_DATA_T*)pnetdata)->psendbuf;
	
	threadid = port;
	
    if(inet_aton(TEST_SEND_SERVER_ADDR, &sa.sin_addr, pbuf, RNT_BUFFER_LEN) == 0)
    {
		test_printf_error("test_send_server");
		cyg_thread_exit();
    }
    sa.sin_family = AF_INET;
    sa.sin_port = htons(IPPORT_USERRESERVED + port);
    
	if((hp = gethostbyname(TEST_REMOTEFUNC_HOSTNAME, pbuf, RNT_BUFFER_LEN)) == NULL)
	{
		test_printf_error("test_send_server");
		cyg_thread_exit();
	}
	
	memcpy(&(r_sa.sin_addr), hp->h_addr_list0, hp->h_length);
	r_sa.sin_family = AF_INET;
	r_sa.sin_port = htons(IPPORT_USERRESERVED + port);
	
	if((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC, pbuf, RNT_BUFFER_LEN)) == -1)
	{
		test_printf_error("test_send_server");
		cyg_thread_exit();
	}
	
	if(set_reuseaddr(s, pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_send_server");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(set_reuseaddr(s, pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_send_server");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(bind(s, (struct sockaddr*)&r_sa, sizeof(r_sa), pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_send_server");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}

    if(connect(s, (struct sockaddr*)&sa, sizeof(sa), pbuf, RNT_BUFFER_LEN) == -1)
    {
		test_printf_error("test_send_server");
		cyg_thread_exit();
    }
	
    for(i = 0; i < TEST_SEND_WRITE_TIMES; i++)
	{
		len = sprintf(psendbuf, "%s", TEST_SEND_MSG);
		len++;
		sendlen = send(s, psendbuf, len, 0, pbuf, RNT_BUFFER_LEN);
		if(sendlen < 0)
		{
			test_printf_error("test_send_server");
			break;
		}
	}
	
	if(i == TEST_SEND_WRITE_TIMES)
		test_printf_success("test_send_server");
	
	netclose(s, pbuf, RNT_BUFFER_LEN);
	cyg_thread_exit();
}
예제 #25
0
void test_tcp_socket_server(cyg_addrword_t pnetdata)
{
	int s, new_s, i;
	struct sockaddr_in sa, r_sa;
	int r_sa_l = sizeof(r_sa);
	struct hostent *hp;
	
	int threadid;
		
	int port = ((TEST_TCP_SOCKET_DATA_T*)pnetdata)->iport;
	char *pbuf = ((TEST_TCP_SOCKET_DATA_T*)pnetdata)->pbuf;
	
	threadid = cyg_thread_self();
	
	if((hp = gethostbyname(TEST_REMOTEFUNC_HOSTNAME, pbuf, RNT_BUFFER_LEN)) == NULL)
	{
		test_printf_error("test_tcp_socket_server");
		cyg_thread_exit();
	}
	
	memcpy(&(r_sa.sin_addr), hp->h_addr_list0, hp->h_length);
	r_sa.sin_family = AF_INET;
	r_sa.sin_port = htons(IPPORT_USERRESERVED + port);
	
	if((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC, pbuf, RNT_BUFFER_LEN)) == -1)
	{
		test_printf_error("test_tcp_socket_server");
		cyg_thread_exit();
	}
	
	if(set_reuseaddr(s, pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_tcp_socket_server");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(bind(s, (struct sockaddr*)&r_sa, sizeof(r_sa), pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_tcp_socket_server");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}

	if(listen(s, 10, pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_tcp_socket_server");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	for(i = 0; i < TEST_TCP_ACCEPT_SOCKET_TIMES; i++)
	{
		if((new_s = accept(s, (struct sockaddr*)&sa, (size_t*)&r_sa_l, pbuf, RNT_BUFFER_LEN)) == -1)
		{
			test_printf_error("test_tcp_socket_server");
			netclose(s, pbuf, RNT_BUFFER_LEN);
			cyg_thread_exit();
		}
		netclose(new_s, pbuf, RNT_BUFFER_LEN);
	}
	test_printf_success("test_tcp_socket_server");
	
	netclose(s, pbuf, RNT_BUFFER_LEN);
	cyg_thread_exit();
}
예제 #26
0
파일: net_common.c 프로젝트: ljhjason/ldb
bool socket_setopt_for_listen (net_socket sockfd)
{
	return socket_set_nonblock(sockfd) && set_reuseaddr(sockfd);
}
예제 #27
0
void test_tcp_bind_socket(char *pcBuf, int iBufLen)
{
	struct sockaddr_in r_sa;
	struct hostent *hp;
	int i;
	
	int iPortBegin = TEST_TCP_SOCKET_PORT_BEGIN;
	int iPortEnd = TEST_TCP_SOCKET_PORT_END;
	int port;
	int sockfd[TEST_TCP_SOCKET_PORT_END];
	
	char hname[256];
	
	memset(hname, 0, 256);
	if(gethostname(hname, 256, pcBuf, iBufLen) == -1)
	{
		test_printf_error("test_tcp_bind_socket");
		return;
	}
	
	port = iPortBegin;
	while(port <= iPortEnd)
	{
		if((hp = gethostbyname(hname, pcBuf, iBufLen)) == NULL)
		{
			test_printf_error("test_tcp_bind_socket");
			goto fail;
		}
		
		memcpy(&(r_sa.sin_addr), hp->h_addr_list0, hp->h_length);
		r_sa.sin_family = AF_INET;
		r_sa.sin_port = htons(IPPORT_USERRESERVED + port);
		
		if((sockfd[port-1] = socket(AF_INET, SOCK_STREAM, PF_UNSPEC, pcBuf, iBufLen)) == -1)
		{
			test_printf_error("test_tcp_bind_socket");
			goto fail;
		}
		
		if(set_reuseaddr(sockfd[port-1], pcBuf, iBufLen) == -1)
		{
			test_printf_error("test_tcp_bind_socket");
			goto fail;
		}
	
		if(bind(sockfd[port-1], (struct sockaddr*)&r_sa, sizeof(r_sa), pcBuf, iBufLen) == -1)
		{
			test_printf_error("test_tcp_bind_socket");
			goto fail;
		}
		port++;
	}
	
fail:
	if(port > iPortEnd)
		test_printf_success("test_tcp_bind_socket");
	for(i = iPortBegin; i <= port; i++)
	{
		netclose(sockfd[i-1], pcBuf, iBufLen);
	}
	return;
}
예제 #28
0
void test_netselect_server(cyg_addrword_t pnetdata)
{
	int s, new_s, readlen;
	struct sockaddr_in sa, r_sa;
	int r_sa_l = sizeof(r_sa);
	struct hostent *hp;
	int ierr = 0;
	
	fd_set readset;
	
	int threadid;
		
	int port = ((TEST_NETSELECT_DATA_T*)pnetdata)->iport;
	char *pbuf = ((TEST_NETSELECT_DATA_T*)pnetdata)->pbuf;
	char *preadbuf = ((TEST_NETSELECT_DATA_T*)pnetdata)->pnetselectbuf;
	
	threadid = cyg_thread_self();
	
	if((hp = gethostbyname(TEST_REMOTEFUNC_HOSTNAME, pbuf, RNT_BUFFER_LEN)) == NULL)
	{
		test_printf_error("test_netselect_server");
		cyg_thread_exit();
	}
	
	memcpy(&(r_sa.sin_addr), hp->h_addr_list0, hp->h_length);
	r_sa.sin_family = AF_INET;
	r_sa.sin_port = htons(IPPORT_USERRESERVED + port);
	
	if((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC, pbuf, RNT_BUFFER_LEN)) == -1)
	{
		test_printf_error("test_netselect_server");
		cyg_thread_exit();
	}
	
	if(set_reuseaddr(s, pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_netselect_server");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if(bind(s, (struct sockaddr*)&r_sa, sizeof(r_sa), pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_netselect_server");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}

	if(listen(s, 10, pbuf, RNT_BUFFER_LEN) == -1)
	{
		test_printf_error("test_netselect_server");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	if((new_s = accept(s, (struct sockaddr*)&sa, (size_t*)&r_sa_l, pbuf, RNT_BUFFER_LEN)) == -1)
	{
		test_printf_error("test_netselect_server");
		netclose(s, pbuf, RNT_BUFFER_LEN);
		cyg_thread_exit();
	}
	
	while(1)
	{
		FD_ZERO(&readset);
		FD_SET(new_s, &readset);
		
		if(netselect(new_s + 1, &readset, NULL, NULL, NULL, pbuf, RNT_BUFFER_LEN) == -1)
		{
			test_printf_error("test_netselect_server");
			ierr = 1;
			break;
		}
		
		if(FD_ISSET(new_s, &readset))
		{
			readlen = netread(new_s, preadbuf, TEST_NETSELECT_MSG_LEN, pbuf, RNT_BUFFER_LEN);
			if(readlen < 0)
			{
				test_printf_error("test_netselect_server");
				ierr = 1;
				break;
			}
			if(readlen == 0)
			{
				break;
			}
			if(readlen > 0)
			{
				if(strcmp(preadbuf, TEST_NETSELECT_MSG) != 0)
				{
					ierr = 1;
					test_printf_error("test_netselect_server");
					break;
				}
			}
		}
	}
	
	if(ierr == 0)
		test_printf_success("test_netselect_server");
	
	netclose(new_s, pbuf, RNT_BUFFER_LEN);
	netclose(s, pbuf, RNT_BUFFER_LEN);
	cyg_thread_exit();
}