Ejemplo n.º 1
0
int main(int argc, char const* argv[])
{
	if (argc<2) perr("usage: chat_server [port]");

	struct addrinfo *plist = 
		get_addrinfo_list("localhost",argv[1],SOCK_STREAM);
	int fd = try_bind(plist);
	if (fd==-1) perr("Cannot bind socket to port");

	freeaddrinfo(plist);

	if (listen(fd,BACKLOG)==-1) {
		perror("listen");
		exit(1);
	}

	struct sigaction sa;
	sa.sa_handler = sigchld_handler; 
	sa.sa_flags   = SA_RESTART;
	sigemptyset(&sa.sa_mask);
	if (sigaction(SIGCHLD,&sa,NULL)==-1) {
		perror("sigaction");
		exit(1);
	}

	while(1) {
		struct sockaddr_storage addr;
		socklen_t addr_len;
		int client_fd = accept(fd,(struct sockaddr *)&addr,&addr_len);
		if (fd==-1) {
			perror("accept");
			exit(1);
		}
		fprintf(stderr,"Got connection from\n");
		print_sockaddr((struct sockaddr*)&addr);
		fprintf(stderr,"\n");

		int pid=fork();
		if (pid<0) {
			perror("fork");
			exit(1);
		} else if (pid==0) { 
			// child
			close(fd);
			const char welcome[] = "Welcome!";
			//write(client_fd,welcome,sizeof(welcome));
			struct client_mgr_t args={client_fd,60.0};
			server_recvmgr(&args);

			close(client_fd);
			exit(0);
		}

		// parent
		close(client_fd);
	}

	return 0;
}
Ejemplo n.º 2
0
int main(int argc, char *argv[])
{

	/* FreeBSD has set limits for user login name -- MAXLOGNAME, but
	 * Linux doesn't have that limitation apparently. */
	char *username = NULL;

	if (argc != 2) {
		tst_resm(TINFO, "Defaulting to user nobody");
		username = strdup(nobody_uid);
	} else {
		/* Get test user uid/gid. */
		username = argv[1];
	}

	if ((pw = getpwnam(username)) == NULL) {
		tst_brkm(TBROK, 0, "Username - %s - not found", username);
		tst_exit();
	}

	if ((gr = getgrgid(pw->pw_gid)) == NULL) {
		tst_brkm(TBROK | TERRNO, 0, "getgrgid(%u) failed", pw->pw_gid);
		tst_exit();
	}

	uid = pw->pw_uid;
	gid = gr->gr_gid;

	tst_resm(TINFO, "Socket will try to be bind by user: %s, group: %s",
		 pw->pw_name, gr->gr_name);

	try_bind();
	tst_exit();

	tst_exit();
}
Ejemplo n.º 3
0
static int inet_listen_saddr(InetSocketAddress *saddr,
                             int port_offset,
                             Error **errp)
{
    struct addrinfo ai,*res,*e;
    char port[33];
    char uaddr[INET6_ADDRSTRLEN+1];
    char uport[33];
    int rc, port_min, port_max, p;
    int slisten = -1;
    int saved_errno = 0;
    bool socket_created = false;
    Error *err = NULL;

    memset(&ai,0, sizeof(ai));
    ai.ai_flags = AI_PASSIVE;
    if (saddr->has_numeric && saddr->numeric) {
        ai.ai_flags |= AI_NUMERICHOST | AI_NUMERICSERV;
    }
    ai.ai_family = inet_ai_family_from_address(saddr, &err);
    ai.ai_socktype = SOCK_STREAM;

    if (err) {
        error_propagate(errp, err);
        return -1;
    }

    if (saddr->host == NULL) {
        error_setg(errp, "host not specified");
        return -1;
    }
    if (saddr->port != NULL) {
        pstrcpy(port, sizeof(port), saddr->port);
    } else {
        port[0] = '\0';
    }

    /* lookup */
    if (port_offset) {
        unsigned long long baseport;
        if (strlen(port) == 0) {
            error_setg(errp, "port not specified");
            return -1;
        }
        if (parse_uint_full(port, &baseport, 10) < 0) {
            error_setg(errp, "can't convert to a number: %s", port);
            return -1;
        }
        if (baseport > 65535 ||
            baseport + port_offset > 65535) {
            error_setg(errp, "port %s out of range", port);
            return -1;
        }
        snprintf(port, sizeof(port), "%d", (int)baseport + port_offset);
    }
    rc = getaddrinfo(strlen(saddr->host) ? saddr->host : NULL,
                     strlen(port) ? port : NULL, &ai, &res);
    if (rc != 0) {
        error_setg(errp, "address resolution failed for %s:%s: %s",
                   saddr->host, port, gai_strerror(rc));
        return -1;
    }

    /* create socket + bind/listen */
    for (e = res; e != NULL; e = e->ai_next) {
        getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen,
		        uaddr,INET6_ADDRSTRLEN,uport,32,
		        NI_NUMERICHOST | NI_NUMERICSERV);

        port_min = inet_getport(e);
        port_max = saddr->has_to ? saddr->to + port_offset : port_min;
        for (p = port_min; p <= port_max; p++) {
            inet_setport(e, p);

            slisten = create_fast_reuse_socket(e);
            if (slisten < 0) {
                /* First time we expect we might fail to create the socket
                 * eg if 'e' has AF_INET6 but ipv6 kmod is not loaded.
                 * Later iterations should always succeed if first iteration
                 * worked though, so treat that as fatal.
                 */
                if (p == port_min) {
                    continue;
                } else {
                    error_setg_errno(errp, errno,
                                     "Failed to recreate failed listening socket");
                    goto listen_failed;
                }
            }
            socket_created = true;

            rc = try_bind(slisten, saddr, e);
            if (rc < 0) {
                if (errno != EADDRINUSE) {
                    error_setg_errno(errp, errno, "Failed to bind socket");
                    goto listen_failed;
                }
            } else {
                if (!listen(slisten, 1)) {
                    goto listen_ok;
                }
                if (errno != EADDRINUSE) {
                    error_setg_errno(errp, errno, "Failed to listen on socket");
                    goto listen_failed;
                }
            }
            /* Someone else managed to bind to the same port and beat us
             * to listen on it! Socket semantics does not allow us to
             * recover from this situation, so we need to recreate the
             * socket to allow bind attempts for subsequent ports:
             */
            closesocket(slisten);
            slisten = -1;
        }
    }
    error_setg_errno(errp, errno,
                     socket_created ?
                     "Failed to find an available port" :
                     "Failed to create a socket");
listen_failed:
    saved_errno = errno;
    if (slisten >= 0) {
        closesocket(slisten);
    }
    freeaddrinfo(res);
    errno = saved_errno;
    return -1;

listen_ok:
    freeaddrinfo(res);
    return slisten;
}
Ejemplo n.º 4
0
int main()
{
    sockaddr_storage_t proxy = {0};
    sockaddr_storage_t target = {0};
    sockaddr_storage_t msgname;
    struct sctp_event_subscribe subscribe;
    int pf_class = PF_INET;
    int sk = 0 ; 

    uint32_t ppid;
    uint32_t stream;
    static char *message = "Hello world\n";
    size_t buflen = 0;
    char *big_buffer = NULL;
    socklen_t msgname_len;

    struct sctp_sndrcvinfo sinfo;
    int offset, msg_flags;
    int error = 0;
    int result = 0;

    // v6 也用不着
    // 源地址配置
    proxy.v4.sin_family = AF_INET;
    proxy.v4.sin_port = htons(OUTBOUND_LOCAL_PORT);
    proxy.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
    /*inet_pton(AF_INET, "1.2.3.4",
        &proxy.v4.sin_addr.s_addr);*/
    
    // 目标地址配置
    target.v4.sin_family = AF_INET;
    target.v4.sin_port = htons(OUTBOUND_REMOTE_PORT);
    target.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
     /*inet_pton(AF_INET, "1.2.3.4",
        &target.v4.sin_addr.s_addr);*/



    sk = create_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
    if (sk == -1)
    {
        return -1;
    }
    
    memset(&subscribe, 0, sizeof(subscribe));
    subscribe.sctp_data_io_event = 1;
    subscribe.sctp_association_event = 1;
    subscribe.sctp_send_failure_event = 1;
    set_sock_opt(sk, SCTP_EVENTS, &subscribe, sizeof(subscribe));

    /* Bind these sockets to the test ports.  */
    try_bind(sk, &proxy.sa, sizeof(proxy));
    buflen = REALLY_BIG;
    big_buffer = try_malloc(buflen);
    while (1)
    {
        ppid = rand();
        stream = 1;

        // 发送给目标机
        send_to_target(sk, message, strlen(message) + 1,
            (struct sockaddr *)&target, sizeof(target),
            ppid, 0, stream, 0, 0);

        // 然后接收目标机
        //buflen = REALLY_BIG;
        //big_buffer = try_malloc(buflen);
        msgname_len = sizeof(msgname);
        msg_flags = 0;

        while (1)
        {
            memset(big_buffer, 0, buflen);
            error = recv_from_target(sk, big_buffer, buflen,
                (struct sockaddr *)&msgname, &msgname_len,
                &sinfo, &msg_flags);

            printf("\nbigbuffer(%d): %s \n",  error, big_buffer);
            hexdump(big_buffer, error);

            // 如果是 data 类型,接收并回传 
            result = check_buf_notification(big_buffer, error, msg_flags,
                sizeof(struct sctp_assoc_change),
                SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
            if (result)
            {
                break;
            }

        }
        sleep(2);
    }
    
    


    /*
    // 问题来了,我是想要数据,而不是要 notify 这些东西
    // 第一次接收到的是 notification
    check_buf_notification(big_buffer, error, msg_flags,
        sizeof(struct sctp_assoc_change),
        SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
    
    // 第二次接收到的是 data
    error = recv_from_target(sk, big_buffer, buflen,
        (struct sockaddr *)&msgname, &msgname_len,
        &sinfo, &msg_flags);
    printf("\nbigbuffer(%d): %s \n",  error, big_buffer);
    hexdump(big_buffer, error);
    check_buf_notification(big_buffer, error, msg_flags,
        sizeof(struct sctp_assoc_change),
        SCTP_ASSOC_CHANGE, SCTP_COMM_UP);*/
    /*
    error = recv_from_target(sk, big_buffer, buflen,
    (struct sockaddr *)&msgname, &msgname_len,
    &sinfo, &msg_flags);

    printf("\nbigbuffer(%d): %s \n",  error, big_buffer);
    hexdump(big_buffer, error);
   
    error = recv_from_target(sk, big_buffer, buflen,
    (struct sockaddr *)&msgname, &msgname_len,
    &sinfo, &msg_flags);

    printf("\nbigbuffer(%d): %s \n",  error, big_buffer);
    hexdump(big_buffer, error);*/
    



	return 0;
}