📄 sctp_darn.c
字号:
} /* if (bindx_rem_addrs) */ /* Do we want to run in the non-blocking mode? */ if (nonblocking) { error = fcntl(retval, F_SETFL, O_NONBLOCK); if (error != 0) { fprintf(stderr, "%s: error fcntl: %s.\n", argv0, strerror(errno)); exit(1); } } if (opt_space) { sndbuf_func(argv0, retval, opt_space, 1); rcvbuf_func(argv0, retval, opt_space, 1); } return retval;} /* build_endpoint() *//* Convenience structure to determine space needed for cmsg. */typedef union { struct sctp_initmsg init; struct sctp_sndrcvinfo sndrcvinfo;} _sctp_cmsg_data_t;/* Listen on the socket, printing out anything that arrives. */intcommand_listen(char *argv0, int sk){ char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))]; struct iovec iov; struct msghdr inmessage; sockaddr_storage_t msgname; char message[REALLY_BIG]; int done = 0; int error; int c; int recvsk = 0; /* Mark sk as being able to accept new associations */ error = listen(sk, 5); if (error != 0) { printf("\n\n\t\tlisten Failure: %s.\n\n\n", strerror(errno)); exit(1); } if (nonblocking) { if (!interactive_mode) { printf("Use -I for interactive mode with"); printf(" -n nonblocking\n"); exit(1); } } /* Initialize the global value for interactive mode functions. */ if (interactive_mode) { inter_sk = sk; } /* Initialize inmessage with enough space for DATA... */ memset(&inmessage, 0, sizeof(inmessage)); if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) { printf("%s: Can't allocate memory.\n", argv0); exit(1); } iov.iov_len = REALLY_BIG; inmessage.msg_iov = &iov; inmessage.msg_iovlen = 1; /* or a control message. */ inmessage.msg_control = incmsg; inmessage.msg_controllen = sizeof(incmsg); inmessage.msg_name = &msgname; inmessage.msg_namelen = sizeof(msgname); printf("%s listening...\n", argv0); /* Get the messages sent */ done = 0; while (!done) { if (interactive_mode) { /* Read from the user. */ if (remote_host) { printf("%s:%d-%s:%d Interactive mode> ", local_host, local_port, remote_host, remote_port); } else { printf("%s:%d-", local_host, local_port); if (associd) { print_sockaddr(&remote_addr.sa); } else { printf("?:%d", remote_port); } printf(" Interactive mode> "); } fflush(stdout); if (NULL == fgets(message, REALLY_BIG, stdin)) { done = 1; continue; } if (0 <= (c = parse_inter_commands(argv0, message, 0))) { if (INTER_RCV != c) { continue; } } else { continue; } } if (socket_type == SOCK_STREAM) { socklen_t len = 0; if (!recvsk) { if ((recvsk = accept(sk, NULL, &len)) < 0) { fprintf(stderr, "%s: error: %s.\n", argv0, strerror(errno)); exit(1); } } } else { recvsk = sk; } error = recvmsg(recvsk, &inmessage, MSG_WAITALL); if (error < 0) { if (nonblocking && (EAGAIN == errno)) { error = 0; continue; } if (socket_type == SOCK_STREAM) { if (ENOTCONN != errno) break; printf("No association is present now!!\n"); close(recvsk); recvsk = 0; continue; } break; } test_print_message(sk, &inmessage, error); /* Update the associd when a notification is received on a * UDP-style socket. */ if (inmessage.msg_flags & MSG_NOTIFICATION) associd = test_verify_assoc_change(&inmessage); if (echo) { if( !(MSG_NOTIFICATION & inmessage.msg_flags)) { sendto(sk, inmessage.msg_iov->iov_base, error, 0, (struct sockaddr *)&msgname, sizeof(msgname)); } } inmessage.msg_control = incmsg; inmessage.msg_controllen = sizeof(incmsg); inmessage.msg_name = &msgname; inmessage.msg_namelen = sizeof(msgname); iov.iov_len = REALLY_BIG; /* Verify that the association is no longer present. */ if (0 != test_sk_for_assoc(recvsk, associd)) { printf("No association is present now!!\n"); if (socket_type == SOCK_STREAM) { close(recvsk); recvsk = 0; } } } if (error < 0) { fprintf(stderr, "%s: error: %s.\n", argv0, strerror(errno)); exit(1); } return error;} /* command_listen() *//* Read lines from stdin and send them to the socket. */intcommand_send(char *argv0, int *skp){ struct msghdr outmsg; struct iovec iov; int done = 0; char message[REALLY_BIG]; struct hostent *hst; int c; struct sockaddr *addrs; int msglen; int error = 0; int sk = *skp; /* Set up the destination. */ if (remote_host != NULL) { hst = gethostbyname(remote_host); if (hst == NULL) { hst = gethostbyname2(remote_host, AF_INET6); } if (hst == NULL || hst->h_length < 1) { fprintf(stderr, "%s: bad hostname: %s\n", argv0, remote_host); exit(1); } ra_family = hst->h_addrtype; switch (ra_family) { case AF_INET: ra_len = sizeof(remote_addr.v4); ra_raw = &remote_addr.v4.sin_addr; remote_addr.v4.sin_port = htons(remote_port); remote_addr.v4.sin_family = AF_INET; break; case AF_INET6: ra_len = sizeof(remote_addr.v6); ra_raw = &remote_addr.v6.sin6_addr; remote_addr.v6.sin6_port = htons(remote_port); remote_addr.v6.sin6_family = AF_INET6; remote_addr.v6.sin6_scope_id = if_index; break; default: fprintf(stderr, "Invalid address type.\n"); exit(1); break; } memcpy(ra_raw, hst->h_addr_list[0], hst->h_length); } /* Initialize the global value for interactive mode functions. */ if (interactive_mode) { inter_sk = sk; } printf("%s ready to send...\n", argv0); while (!done) { /* Read from the user. */ if (remote_host) { if (interactive_mode) { printf("%s:%d-%s:%d Interactive mode> ", local_host, local_port, remote_host, remote_port); } else { printf("%s:%d-%s:%d> ", local_host, local_port, remote_host, remote_port); } } else { printf("%s:%d-", local_host, local_port); if (associd) { print_sockaddr(&remote_addr.sa); } else { printf("XXXXXX:%d", remote_port); } if (interactive_mode) { printf(" Interactive mode> "); } else { printf("> "); } } fflush(stdout); if (NULL == fgets(message, REALLY_BIG, stdin)) { done = 1; continue; } if (interactive_mode) { /* This is the send only agent. */ if (0 <= (c = parse_inter_commands(argv0, message, 1))) { if (INTER_SND == c) { iov.iov_base = inter_outbuf; msglen = inter_outlen; iov.iov_len = msglen; } else { continue; } } else { continue; } } else { /* Send to our neighbor. */ msglen = strlen(message) + 1; iov.iov_len = msglen; } /* For a UDP-style socket, verify if an existing association * has gone. If so, receive the pending SCTP_ASSOC_CHANGE * notification. */ if ((SOCK_SEQPACKET == socket_type) && associd && (0 != test_sk_for_assoc(sk, associd))) { associd = test_recv_assoc_change(sk); printf("Old association gone, Starting a new one!\n"); new_connection = 1; } if (new_connection && connectx_count != 0) { /* Do a sctp_connectx() to establish a connection. */ error = connectx_func(argv0, sk, connectx_addrs, connectx_count); if (0 != error) { if (error == -2) { printf("Connection refused\n"); if (SOCK_SEQPACKET == socket_type) { associd = test_recv_assoc_change(sk); } continue; } fprintf(stderr, "connectx failed.\n"); exit(1); } if (SOCK_SEQPACKET == socket_type) { associd = test_recv_assoc_change(sk); } else { associd = 1; } int rc = sctp_getpaddrs(sk, associd, &addrs); if (0 >= rc) { if (rc == 0) { fprintf(stderr, "sctp_getpaddrs failed, no peers.\n"); } else { fprintf(stderr, "sctp_getpaddrs failed %s(%d).\n", strerror(errno), errno); } exit(1); } printf("New connection, peer addresses\n"); print_addr_buf(addrs, rc); ra_family = addrs[0].sa_family; switch (ra_family) { case AF_INET: ra_len = sizeof(remote_addr.v4); break; case AF_INET6: ra_len = sizeof(remote_addr.v6); break; default: fprintf(stderr, "Invalid address type.\n"); exit(1); } memcpy(&remote_addr, &addrs[0], ra_len); sctp_freepaddrs(addrs); new_connection = 0; } do { if (SOCK_SEQPACKET == socket_type || (connectx_count == 0 && new_connection)) { /* Initialize the message struct we use to pass * messages to the remote socket. */ if (!interactive_mode) { iov.iov_base = message; iov.iov_len = msglen; } outmsg.msg_iov = &iov; outmsg.msg_iovlen = 1; outmsg.msg_control = NULL; outmsg.msg_controllen = 0; outmsg.msg_name = &remote_addr; outmsg.msg_namelen = ra_len; error = sendmsg(sk, &outmsg, 0); } else { error = send(sk, message, msglen, 0); if (error == -1 && errno == EPIPE) { error = close(sk); if (error != 0) { fprintf(stderr, "close failed %s\n", strerror(errno)); exit(1); } *skp = sk = build_endpoint(argv0, local_port); break; } } if (error != msglen) { fprintf(stderr, "%s: error: %s.\n", argv0, strerror(errno)); if (nonblocking && EAGAIN == errno) { if (interactive_mode) { break; } continue; } exit(1); } else { break; } } while (error != msglen); /* If this is the first message sent over a UDP-style socket, * get the associd from the SCTP_ASSOC_CHANGE notification. */ if ((SOCK_SEQPACKET == socket_type) && (0 == associd)) associd = test_recv_assoc_change(sk); /* Verify there is no association. */ if (0 != test_sk_for_assoc(sk, associd)) { printf("No association is present now!!\n"); new_connection = 1; } else { if (new_connection) { int rc = sctp_getpaddrs(sk, associd, &addrs); if (0 >= rc) { if (rc == 0) { fprintf(stderr, "sctp_getpaddrs failed, no peers.\n"); } else { fprintf(stderr, "sctp_getpaddrs failed %s(%d).\n", strerror(errno), errno); } exit(1); } printf("New connection, peer addresses\n"); print_addr_buf(addrs, rc); sctp_freepaddrs(addrs); new_connection = 0; } } /* Clean up. */ if (interactive_mode) { free(inter_outbuf); inter_outbuf = NULL; } } /* while(!done) */ return error;} /* command_send() *//* Listen on the array of sockets, printing out anything that arrives. */intcommand_poll(char *argv0){ char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))]; struct iovec iov; struct msghdr inmessage; int done = 0; int error = 0; int max_fd, i, ret; int size; fd_set *ibitsp = NULL; fd_set *obitsp = NULL; fd_set *xbitsp = NULL; struct msghdr outmsg; struct hostent *hst; int msglen; int temp_fd, temp_set; /* If a remote host is specified, initialize the destination. */ if (remote_host) { /* Set up the destination. */ hst = gethostbyname(remote_host); if (hst == NULL) { hst = gethostbyname2(remote_host, AF_INET6); } if (hst == NULL || hst->h_length < 1) { fprintf(stderr, "%s: bad hostname: %s\n", argv0, remote_host); exit(1); } ra_family = hst->h_addrtype; switch (ra_family) { case AF_INET: ra_len = sizeof(remote_addr.v4); ra_raw = &remote_addr.v4.sin_addr; remote_addr.v4.sin_port = htons(remote_port); remote_addr.v4.sin_family = AF_INET; break; case AF_INET6: ra_len = sizeof(remote_addr.v6); ra_raw = &remote_addr.v6.sin6_addr; remote_addr.v6.sin6_port = htons(remote_port); remote_addr.v6.sin6_family = AF_INET6; remote_addr.v6.sin6_scope_id = if_index; break; default: fprintf(stderr, "Invalid address type.\n"); exit(1); break; } memcpy(ra_raw, hst->h_addr_list[0], hst->h_length); /* Initialize the message struct we use to pass messages to * the remote socket. */ outmsg.msg_iov = &iov; outmsg.msg_iovlen = 1; outmsg.msg_control = NULL; outmsg.msg_controllen = 0; outmsg.msg_name = &remote_addr; outmsg.msg_namelen = ra_len; } max_fd = -1; /* Set all of the sockets to be ready for listening. */ if (use_poll) { for (i = 0; i < poll_skn; i++) { error = listen(poll_fds[i].fd, 1); if (error != 0) { printf("%s: Listen failed on socket number ", argv0); printf("%d: %s.\n", i, strerror(errno)); exit(1); } } printf("%s listening...\n", argv0); } else { for (i = 0; i < poll_skn; i++) { error = listen(poll_sks[i], 1); if (error != 0) { printf("%s: Listen failed on socket number ", argv0); printf("%d: %s.\n", i, strerror(errno)); exit(1); } if (poll_sks[i] > max_fd) { max_fd = poll_sks[i]; } } printf("%s listening...\n", argv0); size = howmany(max_fd + 1, NFDBITS) * sizeof(fd_mask); if ((ibitsp = (fd_set *)malloc(size)) == NULL) { printf("%s: Can't allocate memory.\n", argv0); exit(1); } if ((obitsp = (fd_set *)malloc(size)) == NULL) { printf("%s: Can't allocate memory.\n", argv0); exit(1); } if ((xbitsp = (fd_set *)malloc(size)) == NULL) { printf("%s: Can't allocate memory.\n", argv0); exit(1); } memset(ibitsp, 0, size); memset(obitsp, 0, size); memset(xbitsp, 0, size); } /* Initialize inmessage with enough space for DATA... */ memset(&inmessage, 0, sizeof(inmessage)); if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) { printf("%s: Can't allocate memory.\n", argv0); exit(1); } iov.iov_len = REALLY_BIG; inmessage.msg_iov = &iov; inmessage.msg_iovlen = 1; /* or a control message. */ inmessage.msg_control = incmsg; inmessage.msg_controllen = sizeof(incmsg); done = 0; /* Set the default send message size. */ if (!poll_snd_size) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -