static void set_options(int rs) { int val; if (buffer_size) { rs_setsockopt(rs, SOL_SOCKET, SO_SNDBUF, (void *) &buffer_size, sizeof buffer_size); rs_setsockopt(rs, SOL_SOCKET, SO_RCVBUF, (void *) &buffer_size, sizeof buffer_size); } else { val = 1 << 19; rs_setsockopt(rs, SOL_SOCKET, SO_SNDBUF, (void *) &val, sizeof val); rs_setsockopt(rs, SOL_SOCKET, SO_RCVBUF, (void *) &val, sizeof val); } val = 1; rs_setsockopt(rs, IPPROTO_TCP, TCP_NODELAY, (void *) &val, sizeof(val)); if (flags & MSG_DONTWAIT) rs_fcntl(rs, F_SETFL, O_NONBLOCK); if (use_rs) { /* Inline size based on experimental data */ if (optimization == opt_latency) { val = 384; rs_setsockopt(rs, SOL_RDMA, RDMA_INLINE, &val, sizeof val); } else if (optimization == opt_bandwidth) { val = 0; rs_setsockopt(rs, SOL_RDMA, RDMA_INLINE, &val, sizeof val); } } if (keepalive) set_keepalive(rs); }
void on_connect(EV_P_ struct ev_io *io, int revents) { while (1) { struct sockaddr_in client_addr; socklen_t len = sizeof (struct sockaddr_in); int client_sock = accept(io->fd, (struct sockaddr *) &client_addr, &len); if (client_sock >= 0) { if (set_nonblock(client_sock) == -1) { shutdown_printerr(client_sock, "can't set the socket mode O_NONBLOCK for client\n"); return; } if (set_linger(client_sock) == -1) { shutdown_printerr(client_sock, "can't set SO_LINGER sock option for client\n"); return; } if (set_keepalive(client_sock) == -1) { shutdown_printerr(client_sock, "can't set SO_KEEPALIVE sock option for client\n"); return; } server_ctx_t *srv_ctx = (server_ctx_t *) ev_userdata(loop); client_ctx_t* cli_ctx = get_client_ctx(srv_ctx); cli_ctx->io.ctx = cli_ctx; cli_ctx->connected_at = time(NULL); uuid_generate(cli_ctx->uuid); memcpy(&cli_ctx->client_addr, &client_addr, sizeof (struct sockaddr_in)); ev_io_init((ev_io *) & cli_ctx->io, client_read_write, client_sock, EV_READ); ev_io_start(loop, (ev_io *) & cli_ctx->io); char time_buff[32]; strftime(time_buff, sizeof (time_buff), "%Y-%m-%d %H:%M:%S %Z", localtime(&cli_ctx->connected_at)); char *addr = inet_ntoa(cli_ctx->client_addr.sin_addr); char uuid_buff[37]; uuid_unparse_lower(cli_ctx->uuid, (char *) &uuid_buff); printf("client accepted %s:%hu %s at %s\n", addr, client_addr.sin_port, &uuid_buff, &time_buff); char *welcome_msg = server_welcome(srv_ctx, cli_ctx); send_message(loop, cli_ctx->uuid, welcome_msg, strlen(welcome_msg)); free(welcome_msg); char *new_client_msg = server_client_connected(cli_ctx); for (ssize_t i = 0; i < srv_ctx->clients_count; i++) { if (uuid_compare(srv_ctx->clients[i]->uuid, cli_ctx->uuid) != 0) { send_message(loop, srv_ctx->clients[i]->uuid, new_client_msg, strlen(new_client_msg)); } } free(new_client_msg); } else { if (errno == EAGAIN) return; if (errno == EMFILE || errno == ENFILE) { fprintf(stderr, "out of file descriptors\n"); return; } else if (errno != EINTR) { fprintf(stderr, "accept connections error\n"); return; } } } }
int socketio_setoption(CONCRETE_IO_HANDLE socket_io, const char* optionName, const void* value) { int result; if (socket_io == NULL || optionName == NULL || value == NULL) { result = __LINE__; } else { SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io; if (strcmp(optionName, "tcp_keepalive") == 0) { struct tcp_keepalive keepAlive = socket_io_instance->keep_alive; keepAlive.onoff = *(int *)value; result = set_keepalive(socket_io_instance, &keepAlive); } else if (strcmp(optionName, "tcp_keepalive_time") == 0) { unsigned long kaTime = *(int *)value * 1000; // convert to ms struct tcp_keepalive keepAlive = socket_io_instance->keep_alive; keepAlive.keepalivetime = kaTime; result = set_keepalive(socket_io_instance, &keepAlive); } else if (strcmp(optionName, "tcp_keepalive_interval") == 0) { unsigned long kaInterval = *(int *)value * 1000; // convert to ms struct tcp_keepalive keepAlive = socket_io_instance->keep_alive; keepAlive.keepaliveinterval = kaInterval; result = set_keepalive(socket_io_instance, &keepAlive); } else { result = __LINE__; } } return result; }
void nap_chat_start(int snum) { GetFile *gf; SocketList *s; if (!(s = get_socket(snum)) || !(gf = (GetFile *)s->info)) { put_it("error get_socket(%d)", snum); nap_finished_file(snum, PREMATURE_FINISH); return; } if (gf->deleted) { if (gf->write != -1) close(gf->write); gf->write = -1; if (gf->deleted++ > 5) close_socketread(snum); return; } if ((gf->flags & NAP_CHAT) == NAP_CHAT) { /* we need to accept the connection here. */ struct sockaddr_in remaddr; int sra = sizeof(struct sockaddr_in); int sock = -1; if ((sock = my_accept(snum, (struct sockaddr *) &remaddr, &sra)) > -1) { set_keepalive(sock); gf->port = ntohs(remaddr.sin_port); add_socketread(sock, gf->port, 0, inet_ntoa(remaddr.sin_addr), nap_chat, NULL); set_socketinfo(sock, gf); s->info = NULL; gf->flags = NAP_CHAT_CONNECTED; gf->socket = sock; malloc_strcpy(&gf->ip, inet_ntoa(remaddr.sin_addr)); say("DCC CHAT to %s [%s:%d] established", gf->nick, gf->ip, gf->port); gf->starttime = now; } close_socketread(snum); return; } }
SOCKET make_tcp_connection(const char *host, unsigned short port, unsigned int *ip) { struct sockaddr_in sin; SOCKET f; memset(&sin, 0, sizeof(sin)); sin.sin_port = htons(port); sin.sin_family = AF_INET; if((sin.sin_addr.s_addr = lookup_ip(host)) == 0) return INVALID_SOCKET; if(ip) *ip = sin.sin_addr.s_addr; if((f = new_tcp_socket(ON_NONBLOCKING)) == INVALID_SOCKET) return INVALID_SOCKET; /* if an interface was specify, bind to it before connecting */ if(global.iface) bind_interface(f, global.iface, 0); /* turn on TCP/IP keepalive messages */ set_keepalive(f, 1); log_message_level(LOG_LEVEL_DEBUG, "make_tcp_connection: connecting to %s:%hu", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); if(connect(f, (struct sockaddr *) &sin, sizeof(sin)) < 0) { if(N_ERRNO != EINPROGRESS #ifdef WIN32 /* winsock returns EWOULDBLOCK even in nonblocking mode! ugh!!! */ && N_ERRNO != EWOULDBLOCK #endif ) { nlogerr("make_tcp_connection", "connect"); CLOSE(f); return INVALID_SOCKET; } log_message_level(LOG_LEVEL_SERVER, "make_tcp_connection: connection to %s in progress", host); } else log_message_level(LOG_LEVEL_SERVER, "make_tcp_connection: connection established to %s", host); return f; }
void orte_oob_tcp_set_socket_options(int sd) { #if defined(TCP_NODELAY) int optval; optval = 1; if (setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof(optval)) < 0) { opal_backtrace_print(stderr, NULL, 1); opal_output_verbose(5, orte_oob_base_framework.framework_output, "[%s:%d] setsockopt(TCP_NODELAY) failed: %s (%d)", __FILE__, __LINE__, strerror(opal_socket_errno), opal_socket_errno); } #endif #if defined(SO_SNDBUF) if (mca_oob_tcp_component.tcp_sndbuf > 0 && setsockopt(sd, SOL_SOCKET, SO_SNDBUF, (char *)&mca_oob_tcp_component.tcp_sndbuf, sizeof(int)) < 0) { opal_output_verbose(5, orte_oob_base_framework.framework_output, "[%s:%d] setsockopt(SO_SNDBUF) failed: %s (%d)", __FILE__, __LINE__, strerror(opal_socket_errno), opal_socket_errno); } #endif #if defined(SO_RCVBUF) if (mca_oob_tcp_component.tcp_rcvbuf > 0 && setsockopt(sd, SOL_SOCKET, SO_RCVBUF, (char *)&mca_oob_tcp_component.tcp_rcvbuf, sizeof(int)) < 0) { opal_output_verbose(5, orte_oob_base_framework.framework_output, "[%s:%d] setsockopt(SO_RCVBUF) failed: %s (%d)", __FILE__, __LINE__, strerror(opal_socket_errno), opal_socket_errno); } #endif if (0 < mca_oob_tcp_component.keepalive_time) { set_keepalive(sd); } }
static void *keepalive_thread(void *arg) { int sock; int print_errmsg = 1; while (1) { sock = tcpconn(server_ip, server_port, 5); if (sock == -1) { if (print_errmsg == 1) { syslog(LOG_ERR, "connect app server failed."); print_errmsg = 0; } sleep(5); continue; } syslog(LOG_INFO, "connect app server success."); set_keepalive(sock, KEEPALIVE_IDEL, KEEPALIVE_CNT, KEEPALIVE_INTV); LOCK(mtx); server_sock = sock; UNLOCK(mtx); dummy_recv_loop(server_sock); LOCK(mtx); close(server_sock); server_sock = INVALID_SOCKET; UNLOCK(mtx); syslog(LOG_INFO, "disconnect from app server."); print_errmsg = 1; sleep(5); } return NULL; }
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; }
void reap_info_slave(void) { struct response_dgram resp; ssize_t len; char hostname[BUFFER_LEN], *hp; int n, count; conn_source source; if (info_slave_state != INFO_SLAVE_PENDING) { if (info_slave_state == INFO_SLAVE_DOWN) make_info_slave(); return; } len = recv(info_slave, &resp, sizeof resp, 0); if (len < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) return; else if (len < 0 || len != (int) sizeof resp) { penn_perror("reading info_slave response"); return; } /* okay, now we have some info! */ if (!FD_ISSET(resp.fd, &info_pending)) { /* Duplicate or spoof. Ignore. */ return; } FD_CLR(resp.fd, &info_pending); /* See if we have any other pending queries and change state if not. */ for (n = 0, count = 0; n < pending_max; n++) if (FD_ISSET(n, &info_pending)) count++; if (count == 0) { info_slave_state = INFO_SLAVE_READY; pending_max = 0; } hp = hostname; if (resp.hostname[0]) safe_str(resp.hostname, hostname, &hp); else safe_str(resp.ipaddr, hostname, &hp); *hp = '\0'; if (Forbidden_Site(resp.ipaddr) || Forbidden_Site(hostname)) { if (!Deny_Silent_Site(resp.ipaddr, AMBIGUOUS) || !Deny_Silent_Site(hostname, AMBIGUOUS)) { do_log(LT_CONN, 0, 0, "[%d/%s/%s] Refused connection.", resp.fd, hostname, resp.ipaddr); } shutdown(resp.fd, 2); closesocket(resp.fd); return; } if (resp.connected_to == TINYPORT) source = CS_IP_SOCKET; else if (resp.connected_to == SSLPORT) source = CS_OPENSSL_SOCKET; else source = CS_UNKNOWN; do_log(LT_CONN, 0, 0, "[%d/%s/%s] Connection opened from %s.", resp.fd, hostname, resp.ipaddr, source_to_s(source)); set_keepalive(resp.fd, options.keepalive_timeout); initializesock(resp.fd, hostname, resp.ipaddr, source); }
/* Output endpoint. Gets pointer to endpoint config in args */ void * write_endpt(void * args) { struct endpt_cfg * cfg; cfg = (struct endpt_cfg *)args; // Mask signals sigset_t sigset; if (sigfillset(&sigset) == -1) { tdprint(args, WARN, "Error in signal setup\n"); exit_thread(cfg, -1); } if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) { tdprint(args, WARN, "Error in signal setup\n"); exit_thread(cfg, -1); } int writefd = -1; do { tdprint(args, INFO, "Start writing\n", args); // For use in sendto struct sockaddr * addr = NULL; socklen_t addrlen = 0; if (cfg->type == T_FILE) { writefd = open(cfg->name, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (writefd == -1) { warn("Opening file %s to write failed\n", cfg->name); cfg->exit_status = -1; goto write_repeat; } if (cfg->test_only) { close(writefd); exit_thread(cfg, 0); } } else if (cfg->type == T_SOCKET) { struct addrinfo hints; memset(&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_UNSPEC; if (cfg->protocol == IPPROTO_TCP) hints.ai_socktype = SOCK_STREAM; else if (cfg->protocol == IPPROTO_UDP) hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = 0; hints.ai_protocol = 0; int res; struct addrinfo * addrinfo; res = getaddrinfo(cfg->name, cfg->port, &hints, &addrinfo); if (res) { tdprint(args, ERR, "Error when resolving %s: %s\n", cfg->name, gai_strerror(res)); cfg->exit_status = -1; goto write_repeat; } for (struct addrinfo * aiptr = addrinfo; aiptr != NULL; aiptr = aiptr->ai_next) { addr = aiptr->ai_addr; addrlen = aiptr->ai_addrlen; writefd = socket(aiptr->ai_family, aiptr->ai_socktype, aiptr->ai_protocol); if (writefd == -1) continue; if (cfg->protocol == IPPROTO_UDP) break; if (cfg->keepalive != 0) { set_keepalive(writefd, args, cfg->keepalive); } if (connect(writefd, addr, addrlen) != -1) break; close(writefd); writefd = -1; } freeaddrinfo(addrinfo); if (writefd == -1) { tdprint(args, ERR, "Could not connect to %s\n", cfg->name); cfg->exit_status = -1; goto write_repeat; } if (cfg->test_only) { close(writefd); exit_thread(cfg, 0); } } else if (cfg->type == T_STD) { writefd = 1; if (cfg->test_only) { exit_thread(cfg, 0); } } char * writebuf; while (1) { size_t towrite; towrite = buffer_after_delete(cfg->buf); if (towrite == BUF_END_DATA) { cfg->exit_status = 0; tdprint(args, INFO, "End of data\n", args); close(writefd); exit_thread(cfg, cfg->exit_status); } if (towrite == BUF_KILL) { cfg->exit_status = -2; tdprint(args, INFO, "End required by signal\n", args); close(writefd); exit_thread(cfg, cfg->exit_status); } writebuf = buffer_cons_data_pointer(cfg->buf); if (cfg->type == T_SOCKET && cfg->protocol == IPPROTO_UDP) { ssize_t res; res = sendto(writefd, writebuf, towrite, 0, addr, addrlen); if (res == -1) warn("Error in sending data\n"); } else { int nwritten; nwritten = 0; while (nwritten < towrite) { ssize_t res; res = write(writefd, (void *)(writebuf+nwritten), towrite-nwritten); if (res < 0) { warn("Error in sending data"); cfg->exit_status = -1; close(writefd); goto write_repeat; } nwritten += res; } } } write_repeat: switch (cfg->retry) { case YES: tdprint(args, INFO, "Retrying\n", args); break; case NO: tdprint(args, INFO, "Terminating\n", args); exit_thread(cfg, cfg->exit_status); case IGNORE: case KILL: tdprint(args, INFO, "Terminating\n", args); exit_thread(cfg, 0); } sleep(RETRY_DELAY); } while (1); // Unreachable exit_thread(cfg, cfg->exit_status); }
/* Endpoint for input. Gets pointer to I/O config in args */ void * read_endpt(void * args) { struct io_cfg * cfg; cfg = (struct io_cfg *) args; struct endpt_cfg * read_cfg; read_cfg = cfg->input; read_cfg->exit_status = 0; // Mask signals sigset_t sigset; if (sigfillset(&sigset) == -1) { tdprint((void *)read_cfg, WARN, "Error in signal setup\n"); exit_thread(read_cfg, -1); } if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) { tdprint((void *)read_cfg, WARN, "Error in signal setup\n"); exit_thread(read_cfg, -1); } int listenfd; listenfd = -1; int readfd; readfd = -1; do { tdprint((void *)read_cfg, INFO, "Start reading\n"); if (read_cfg->type == T_FILE) { tdprint((void *)read_cfg, DEBUG, "File\n"); readfd = open(read_cfg->name, O_RDONLY); if (readfd == -1) { warn("Error while opening %s for reading: ", read_cfg->name); read_cfg->exit_status = -1; goto read_repeat; } else if (read_cfg->test_only) { close(readfd); exit_thread(read_cfg, 0); } } else if (read_cfg->type == T_SOCKET && read_cfg->protocol == IPPROTO_TCP) { tdprint((void *)read_cfg, DEBUG, "Socket\n"); if (listenfd == -1) { struct addrinfo hints; memset(&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; hints.ai_protocol = 0; int res; struct addrinfo * addrinfo; res = getaddrinfo(NULL, read_cfg->port, &hints, &addrinfo); if (res) { tdprint((void *)read_cfg, ERR, "Error when resolving %s: %s\n", read_cfg->name, gai_strerror(res)); read_cfg->exit_status = -1; goto read_repeat; } for (struct addrinfo * aiptr = addrinfo; aiptr != NULL; aiptr = aiptr->ai_next) { listenfd = socket(aiptr->ai_family, aiptr->ai_socktype, aiptr->ai_protocol); if (listenfd == -1) continue; tdprint((void *)read_cfg, DEBUG, "Binding\n"); if (bind(listenfd, aiptr->ai_addr, aiptr->ai_addrlen) == 0) break; close(listenfd); listenfd = -1; } freeaddrinfo(addrinfo); if (listenfd == -1) { tdprint((void *)read_cfg, ERR, "Could not bind to port %s\n", read_cfg->port); read_cfg->exit_status = -1; goto read_repeat; } tdprint((void *)read_cfg, DEBUG, "Listening\n"); if (listen(listenfd, 1)) { warn("Could not listen on port %s\n", read_cfg->port); read_cfg->exit_status = -1; goto read_repeat; } } if (read_cfg->test_only) { close(listenfd); exit_thread(read_cfg, 0); } tdprint((void *)read_cfg, DEBUG, "Accepting\n"); int res = wait_for_event((void *) read_cfg, "accept", listenfd, signal_fds[0]); switch (res) { case WFE_POLL_ERR: close(listenfd); listenfd = -1; read_cfg->exit_status = -1; goto read_repeat; break; case WFE_SIG_TERM: read_cfg->retry = KILL; goto read_repeat; break; case WFE_EVT: break; } readfd = accept(listenfd, NULL, NULL); if (readfd == -1) { warn("Could not accept on port %s:", read_cfg->port); read_cfg->exit_status = -1; goto read_repeat; } if (read_cfg->keepalive != 0) { set_keepalive(readfd, read_cfg, read_cfg->keepalive); } tdprint((void *)read_cfg, DEBUG, "Reading\n"); } else if (read_cfg->type == T_SOCKET && read_cfg->protocol == IPPROTO_UDP) { tdprint((void *)read_cfg, DEBUG, "Socket\n"); struct addrinfo hints; memset(&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; hints.ai_protocol = 0; int res; struct addrinfo * addrinfo; res = getaddrinfo(NULL, read_cfg->port, &hints, &addrinfo); if (res) { tdprint((void *)read_cfg, ERR, "Error when resolving %s: %s\n", read_cfg->name, gai_strerror(res)); read_cfg->exit_status = -1; goto read_repeat; } for (struct addrinfo * aiptr = addrinfo; aiptr != NULL; aiptr = aiptr->ai_next) { readfd = socket(aiptr->ai_family, aiptr->ai_socktype, aiptr->ai_protocol); if (readfd == -1) continue; tdprint((void *)read_cfg, DEBUG, "Binding\n"); if (bind(readfd, aiptr->ai_addr, aiptr->ai_addrlen) == 0) break; close(readfd); } freeaddrinfo(addrinfo); if (readfd == -1) { tdprint((void *)read_cfg, ERR, "Could not bind to port %s\n", read_cfg->port); read_cfg->exit_status = -1; goto read_repeat; } tdprint((void *)read_cfg, DEBUG, "Reading\n"); if (read_cfg->test_only) { close(readfd); exit_thread(read_cfg, 0); } } else if (read_cfg->type == T_STD) { tdprint((void *)read_cfg, DEBUG, "Stdin\n"); readfd = 0; if (read_cfg->test_only) { exit_thread(read_cfg, 0); } } char * readbuf; readbuf = malloc(sizeof (char)*READ_BUFFER_BLOCK_SIZE); while (1) { tdprint((void *)read_cfg, DEBUG, "Rereading\n"); size_t toread; size_t nread; toread = READ_BUFFER_BLOCK_SIZE; nread = 0; while (nread < toread) { int res = wait_for_event((void *) read_cfg, "read", readfd, signal_fds[0]); switch (res) { case WFE_POLL_ERR: close(readfd); free(readbuf); read_cfg->exit_status = -1; goto read_repeat; break; case WFE_SIG_TERM: read_cfg->retry = KILL; goto read_repeat; break; case WFE_EVT: break; } if (read_cfg->type == T_SOCKET && read_cfg->protocol == IPPROTO_UDP) { struct sockaddr from_addr; socklen_t from_addrlen; // From sys/socket.h, does // exist more correct system? from_addrlen = 14; res = recvfrom(readfd, (void *)readbuf, READ_BUFFER_BLOCK_SIZE, 0, &from_addr, &from_addrlen); tdprint((void *)read_cfg, INFO, "Got message from socket\n"); } else { res = read(readfd, (void *)(readbuf+nread), (toread-nread)); } if (res == 0) { // EOF close(readfd); for (int i = 0; i < cfg->n_outs; i++) { buffer_insert(cfg->outs[i].buf, readbuf, nread); } free(readbuf); read_cfg->exit_status = 0; goto read_repeat; } else if (res == -1) { // Error warn("Error while reading from %s", read_cfg->name); close(readfd); free(readbuf); read_cfg->exit_status = -1; goto read_repeat; } nread += res; if (read_cfg->type == T_SOCKET && read_cfg->protocol == IPPROTO_UDP) { break; } } for (int i = 0; i < cfg->n_outs; i++) { buffer_insert(cfg->outs[i].buf, readbuf, nread); } } read_repeat: if (read_cfg->test_only) { exit_thread(read_cfg, read_cfg->exit_status); } switch (read_cfg->retry) { case YES: tdprint((void *)read_cfg, INFO, "Retrying read\n"); break; case KILL: close(listenfd); tdprint((void *)read_cfg, INFO, "Ending read\n"); for (int i = 0; i < cfg->n_outs; i++) { buffer_insert(cfg->outs[i].buf, NULL, BUF_KILL); } exit_thread(read_cfg, -2); case NO: case IGNORE: close(listenfd); tdprint((void *)read_cfg, INFO, "Ending read\n"); for (int i = 0; i < cfg->n_outs; i++) { buffer_insert(cfg->outs[i].buf, NULL, BUF_END_DATA); } exit_thread(read_cfg, read_cfg->exit_status); } sleep(RETRY_DELAY); } while (1); // Should be unreachable exit_thread(read_cfg, read_cfg->exit_status); }
int main(int argc, char **argv) { if(argc<2) { fprintf(stderr,"Usage:\n %s <port>\n",argv[0]); return 1; } int serverPort =atoi(argv[1]); if(serverPort<1) { fprintf(stderr,"serverPort{%d} error\n",serverPort); return 1; } struct epoll_event ev; struct epoll_event events[MAXEPOLLSIZE]; int listenerfd = socket(PF_INET, SOCK_STREAM, 0); if (-1==listenerfd) { printf("ERROR socket ,errno=%d,rt=%d,%s \n",errno,listenerfd,strerror(errno)); return 0; } int opt=SO_REUSEADDR; setsockopt(listenerfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); setnonblocking(listenerfd); struct sockaddr_in my_addr; bzero(&my_addr, sizeof(my_addr)); my_addr.sin_family = PF_INET; my_addr.sin_port = htons(serverPort); my_addr.sin_addr.s_addr = INADDR_ANY; if (bind(listenerfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1) { printf("ERROR bind ,errno=%d,%s \n",errno,strerror(errno)); return 0; } if (listen(listenerfd, 128) == -1) { printf("ERROR listen ,errno=%d,%s \n",errno,strerror(errno)); return 0; } int efd = epoll_create(MAXEPOLLSIZE); socklen_t len = sizeof(struct sockaddr_in); ev.events = EPOLLIN | EPOLLET; ev.data.fd = listenerfd; if (epoll_ctl(efd, EPOLL_CTL_ADD, listenerfd, &ev) < 0) { printf("ERROR epoll_ctl ,errno=%d,%s \n",errno,strerror(errno)); return 0; } int maxevents = 1; while (maxevents>0) { int n = epoll_wait(efd, events, maxevents, -1); printf(" epoll_wait returned %d \n",n); if (n == -1) { printf("ERROR epoll_wait ,errno=%d,%s \n",errno,strerror(errno)); return 0; } for (int i = 0; i < n; ++i) { if (events[i].data.fd == listenerfd) { struct sockaddr_in their_addr; int clientfd = accept(listenerfd, (struct sockaddr *) &their_addr,&len); if (clientfd < 0) { printf("ERROR accept ,errno=%d,%s \n",errno,strerror(errno)); continue; } else { printf(" Connected from %s:%d, client socket:%d\n", inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port), clientfd); } setnonblocking(clientfd); if(0!=set_keepalive(clientfd)) { printf("ERROR set_keepalive ,errno=%d,%s \n",errno,strerror(errno)); continue; } if(0!=set_tcp_user_timeout(clientfd)) { printf("ERROR set_tcp_user_timeout ,errno=%d,%s \n",errno,strerror(errno)); continue; } ev.events = EPOLLIN | EPOLLET; ev.data.fd = clientfd; if (epoll_ctl(efd, EPOLL_CTL_ADD, clientfd, &ev) < 0) { printf("ERROR epoll_ctl ,errno=%d,%s \n",errno,strerror(errno)); return -1; } maxevents++; } else { int rt = handle_message(events[i].data.fd); if (rt < 1 && errno != 11) { epoll_ctl(efd, EPOLL_CTL_DEL, events[i].data.fd,&ev); maxevents--; } } } } close(listenerfd); return 0; }
static int init_listen_socket(const char *address, const char *port, int *fds) { int i; int gai_ret; struct addrinfo hints; struct addrinfo *rp=NULL; struct addrinfo *info=NULL; close_fds(fds); memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family=AF_UNSPEC; hints.ai_socktype=SOCK_STREAM; hints.ai_protocol=IPPROTO_TCP; hints.ai_flags=AI_NUMERICHOST; hints.ai_flags|=AI_PASSIVE; if((gai_ret=getaddrinfo(address, port, &hints, &info))) { logp("unable to getaddrinfo on port %s: %s\n", port, gai_strerror(gai_ret)); return -1; } i=0; for(rp=info; rp && i<LISTEN_SOCKETS; rp=rp->ai_next) { fds[i]=socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if(fds[i]<0) { logp("unable to create socket on port %s: %s\n", port, strerror(errno)); continue; } set_keepalive(fds[i], 1); #ifdef HAVE_IPV6 if(rp->ai_family==AF_INET6) { // Attempt to say that it should not listen on IPv6 // only. int optval=0; setsockopt(fds[i], IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)); } #endif reuseaddr(fds[i]); if(bind(fds[i], rp->ai_addr, rp->ai_addrlen)) { logp("unable to bind socket on port %s: %s\n", port, strerror(errno)); close(fds[i]); fds[i]=-1; continue; } // Say that we are happy to accept connections. if(listen(fds[i], 5)<0) { close_fd(&(fds[i])); logp("could not listen on main socket %s\n", port); return -1; } #ifdef HAVE_WIN32 { u_long ioctlArg=0; ioctlsocket(fds[i], FIONBIO, &ioctlArg); } #endif i++; } freeaddrinfo(info); if(!i) { logp("could not listen on address: %s\n", address); #ifdef HAVE_IPV6 if(strchr(address, ':')) logp("maybe check whether your OS has IPv6 enabled.\n"); #endif return -1; } return 0; }