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; }
int create_and_bind(const char *addr, const char *port) { struct addrinfo hints; struct addrinfo *result, *rp; int s, listen_sock; 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 */ result = NULL; s = getaddrinfo(addr, port, &hints, &result); if (s != 0) { LOGI("getaddrinfo: %s", gai_strerror(s)); return -1; } if (result == NULL) { LOGE("Could not bind"); return -1; } for (rp = result; rp != NULL; rp = rp->ai_next) { listen_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (listen_sock == -1) { continue; } int opt = 1; setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); #ifdef SO_NOSIGPIPE setsockopt(listen_sock, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); #endif if (reuse_port) { int err = set_reuseport(listen_sock); if (err == 0) { LOGI("tcp port reuse enabled"); } } s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen); if (s == 0) { /* We managed to bind successfully! */ break; } else { ERROR("bind"); } close(listen_sock); listen_sock = -1; } freeaddrinfo(result); return listen_sock; }
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; }
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); }
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; }
int create_server_socket(const char *host, const char *port) { struct addrinfo hints; struct addrinfo *result, *rp, *ipv4v6bindall; int s, server_sock; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ hints.ai_socktype = SOCK_DGRAM; /* We want a UDP socket */ hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; /* For wildcard IP address */ hints.ai_protocol = IPPROTO_UDP; s = getaddrinfo(host, port, &hints, &result); if (s != 0) { LOGE("[udp] getaddrinfo: %s", gai_strerror(s)); return -1; } if (result == NULL) { LOGE("[udp] cannot bind"); return -1; } rp = result; /* * On Linux, with net.ipv6.bindv6only = 0 (the default), getaddrinfo(NULL) with * AI_PASSIVE returns 0.0.0.0 and :: (in this order). AI_PASSIVE was meant to * return a list of addresses to listen on, but it is impossible to listen on * 0.0.0.0 and :: at the same time, if :: implies dualstack mode. */ if (!host) { ipv4v6bindall = result; /* Loop over all address infos found until a IPV6 address is found. */ while (ipv4v6bindall) { if (ipv4v6bindall->ai_family == AF_INET6) { rp = ipv4v6bindall; /* Take first IPV6 address available */ break; } ipv4v6bindall = ipv4v6bindall->ai_next; /* Get next address info, if any */ } } for (/*rp = result*/; rp != NULL; rp = rp->ai_next) { server_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (server_sock == -1) { continue; } if (rp->ai_family == AF_INET6) { int ipv6only = host ? 1 : 0; setsockopt(server_sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, sizeof(ipv6only)); } int opt = 1; setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); #ifdef SO_NOSIGPIPE set_nosigpipe(server_sock); #endif if (reuse_port) { int err = set_reuseport(server_sock); if (err == 0) { LOGI("udp port reuse enabled"); } } #ifdef IP_TOS // Set QoS flag int tos = 46; setsockopt(server_sock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); #endif #ifdef MODULE_REDIR if (setsockopt(server_sock, SOL_IP, IP_TRANSPARENT, &opt, sizeof(opt))) { ERROR("[udp] setsockopt IP_TRANSPARENT"); exit(EXIT_FAILURE); } if (rp->ai_family == AF_INET) { if (setsockopt(server_sock, SOL_IP, IP_RECVORIGDSTADDR, &opt, sizeof(opt))) { FATAL("[udp] setsockopt IP_RECVORIGDSTADDR"); } } else if (rp->ai_family == AF_INET6) { if (setsockopt(server_sock, SOL_IPV6, IPV6_RECVORIGDSTADDR, &opt, sizeof(opt))) { FATAL("[udp] setsockopt IPV6_RECVORIGDSTADDR"); } } #endif s = bind(server_sock, rp->ai_addr, rp->ai_addrlen); if (s == 0) { /* We managed to bind successfully! */ break; } else { ERROR("[udp] bind"); } close(server_sock); server_sock = -1; } freeaddrinfo(result); return server_sock; }
int create_and_bind(const char *addr, const char *port) { struct addrinfo hints; struct addrinfo *result, *rp; int s, listen_sock; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; s = getaddrinfo(addr, port, &hints, &result); if (0 != s) { printf("getaddrinfo failed"); return -1; } for (rp = result; rp != NULL; rp=rp->ai_next) { listen_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (-1 == listen_sock) { continue; } int opt = 1; setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); #ifdef SO_NOSIGPIPE setsockopt(listen_sock, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); #endif int err = set_reuseport(listen_sock); if (err == 0) { printf("tcp port reuse enabled\n"); } else { printf("tcp port reuse failed\n"); } s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen); if (0 == s){ printf("Bind successfully\n"); break; } else { printf("bind error\n"); } close(listen_sock); } if (NULL == rp) { return -1; } freeaddrinfo(result); return listen_sock; }