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; }
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(); }
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; }
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; }