Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}