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; }
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; }
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; }
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(); }
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; }
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; }
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); }
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; }
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; }
//绑定且开始监听 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; }
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); }
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; } }
/* 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; }
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; }
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; }
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(); }
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(); }
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; }
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); }
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(); }
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; }
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; }
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(); }
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(); }
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(); }
bool socket_setopt_for_listen (net_socket sockfd) { return socket_set_nonblock(sockfd) && set_reuseaddr(sockfd); }
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; }
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(); }