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 iscsi_tcp_connect(struct iscsi_context *iscsi, union socket_address *sa, int ai_family) { int socksize; iscsi->fd = socket(ai_family, SOCK_STREAM, 0); if (iscsi->fd == -1) { iscsi_set_error(iscsi, "Failed to open iscsi socket. " "Errno:%s(%d).", strerror(errno), errno); return -1; } if (iscsi->old_iscsi && iscsi->fd != iscsi->old_iscsi->fd) { if (dup2(iscsi->fd, iscsi->old_iscsi->fd) == -1) { return -1; } close(iscsi->fd); iscsi->fd = iscsi->old_iscsi->fd; } set_nonblocking(iscsi->fd); iscsi_set_tcp_keepalive(iscsi, iscsi->tcp_keepidle, iscsi->tcp_keepcnt, iscsi->tcp_keepintvl); if (iscsi->tcp_user_timeout > 0) { set_tcp_user_timeout(iscsi); } if (iscsi->tcp_syncnt > 0) { set_tcp_syncnt(iscsi); } #if __linux if (iscsi->bind_interfaces[0]) { char *pchr = iscsi->bind_interfaces, *pchr2; int iface_n = iface_rr++%iscsi->bind_interfaces_cnt; int iface_c = 0; do { pchr2 = strchr(pchr,','); if (iface_c == iface_n) { if (pchr2) pchr2[0]=0x00; break; } if (pchr2) {pchr=pchr2+1;} iface_c++; } while (pchr2); int res = setsockopt(iscsi->fd, SOL_SOCKET, SO_BINDTODEVICE, pchr, strlen(pchr)); if (res < 0) { ISCSI_LOG(iscsi,1,"failed to bind to interface '%s': %s",pchr,strerror(errno)); } else { ISCSI_LOG(iscsi,3,"successfully bound to interface '%s'",pchr); } if (pchr2) pchr2[0]=','; } #endif if (set_tcp_sockopt(iscsi->fd, TCP_NODELAY, 1) != 0) { ISCSI_LOG(iscsi,1,"failed to set TCP_NODELAY sockopt: %s",strerror(errno)); } else { ISCSI_LOG(iscsi,3,"TCP_NODELAY set to 1"); } socksize = sizeof(struct sockaddr_in); // Work-around for now, need to fix it if (connect(iscsi->fd, &sa->sa, socksize) != 0 && errno != EINPROGRESS) { iscsi_set_error(iscsi, "Connect failed with errno : " "%s(%d)", strerror(errno), errno); close(iscsi->fd); iscsi->fd = -1; return -1; } return 0; }
int iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, iscsi_command_cb cb, void *private_data) { int port = 3260; char *str; char *addr, *host; struct addrinfo *ai = NULL; int socksize; DPRINTF(iscsi,2,"connecting to portal %s",portal); if (iscsi->fd != -1) { iscsi_set_error(iscsi, "Trying to connect but already connected."); return -1; } addr = strdup(portal); if (addr == NULL) { iscsi_set_error(iscsi, "Out-of-memory: " "Failed to strdup portal address."); return -1; } host = addr; /* check if we have a target portal group tag */ str = strrchr(host, ','); if (str != NULL) { str[0] = 0; } str = strrchr(host, ':'); if (str != NULL) { if (strchr(str, ']') == NULL) { if (str != NULL) { port = atoi(str+1); str[0] = 0; } } } /* ipv6 in [...] form ? */ if (host[0] == '[') { host ++; str = strchr(host, ']'); if (str == NULL) { free(addr); iscsi_set_error(iscsi, "Invalid target:%s " "Missing ']' in IPv6 address", portal); return -1; } *str = 0; } /* is it a hostname ? */ if (getaddrinfo(host, NULL, NULL, &ai) != 0) { free(addr); iscsi_set_error(iscsi, "Invalid target:%s " "Can not resolv into IPv4/v6.", portal); return -1; } free(addr); switch (ai->ai_family) { case AF_INET: socksize = sizeof(struct sockaddr_in); ((struct sockaddr_in *)(ai->ai_addr))->sin_port = htons(port); #ifdef HAVE_SOCK_SIN_LEN ((struct sockaddr_in *)(ai->ai_addr))->sin_len = socksize; #endif break; case AF_INET6: socksize = sizeof(struct sockaddr_in6); ((struct sockaddr_in6 *)(ai->ai_addr))->sin6_port = htons(port); #ifdef HAVE_SOCK_SIN_LEN ((struct sockaddr_in6 *)(ai->ai_addr))->sin6_len = socksize; #endif break; default: iscsi_set_error(iscsi, "Unknown address family :%d. " "Only IPv4/IPv6 supported so far.", ai->ai_family); freeaddrinfo(ai); return -1; } iscsi->fd = socket(ai->ai_family, SOCK_STREAM, 0); if (iscsi->fd == -1) { freeaddrinfo(ai); iscsi_set_error(iscsi, "Failed to open iscsi socket. " "Errno:%s(%d).", strerror(errno), errno); return -1; } iscsi->socket_status_cb = cb; iscsi->connect_data = private_data; set_nonblocking(iscsi->fd); iscsi_set_tcp_keepalive(iscsi, iscsi->tcp_keepidle, iscsi->tcp_keepcnt, iscsi->tcp_keepintvl); if (iscsi->tcp_user_timeout > 0) { set_tcp_user_timeout(iscsi); } if (iscsi->tcp_syncnt > 0) { set_tcp_syncnt(iscsi); } if (connect(iscsi->fd, ai->ai_addr, socksize) != 0 && errno != EINPROGRESS) { iscsi_set_error(iscsi, "Connect failed with errno : " "%s(%d)", strerror(errno), errno); close(iscsi->fd); iscsi->fd = -1; freeaddrinfo(ai); return -1; } freeaddrinfo(ai); if (iscsi->connected_portal) free(discard_const(iscsi->connected_portal)); iscsi->connected_portal=strdup(portal); return 0; }