ssize_t uwsgi_proto_sctp_writev_header(struct wsgi_request * wsgi_req, struct iovec * iovec, size_t iov_len) { struct sctp_sndrcvinfo sinfo; memset(&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); sinfo.sinfo_stream = wsgi_req->stream_id; ssize_t wlen = sctp_sendv(wsgi_req->poll.fd, iovec, iov_len, &sinfo, 0); if (wlen < 0) { uwsgi_req_error("writev()"); return 0; } return wlen; }
int protocol_sctp_write(protocol_t *p, void *buffer, int size, void *options) #if defined(HAVE_SCTP_SENDV) { ssize_t len; struct iovec iov; struct sctp_sendv_spa info; iov.iov_base = buffer; iov.iov_len = size; memset(&info, 0, sizeof(struct sctp_sendv_spa)); if (options) { flowop_options_t *flowops; flowops = (flowop_options_t *) options; info.sendv_sndinfo.snd_sid = flowops->sctp_stream_id; if (FO_SCTP_UNORDERED(flowops)) { info.sendv_sndinfo.snd_flags |= SCTP_UNORDERED; } info.sendv_flags |= SCTP_SEND_SNDINFO_VALID; #ifdef SCTP_PR_SCTP_TTL if (strcasecmp(flowops->sctp_pr_policy, "ttl") == 0) { info.sendv_prinfo.pr_policy = SCTP_PR_SCTP_TTL; info.sendv_prinfo.pr_value = flowops->sctp_pr_value; info.sendv_flags |= SCTP_SEND_PRINFO_VALID; } #endif #ifdef SCTP_PR_SCTP_RTX if (strcasecmp(flowops->sctp_pr_policy, "rtx") == 0) { info.sendv_prinfo.pr_policy = SCTP_PR_SCTP_RTX; info.sendv_prinfo.pr_value = flowops->sctp_pr_value; info.sendv_flags |= SCTP_SEND_PRINFO_VALID; } #endif #ifdef SCTP_PR_SCTP_BUF if (strcasecmp(flowops->sctp_pr_policy, "buf") == 0) { info.sendv_prinfo.pr_policy = SCTP_PR_SCTP_BUF; info.sendv_prinfo.pr_value = flowops->sctp_pr_value; info.sendv_flags |= SCTP_SEND_PRINFO_VALID; } #endif } if ((len = sctp_sendv(p->fd, &iov, 1, NULL, 0, &info, sizeof(struct sctp_sendv_spa), SCTP_SENDV_SPA, 0)) < 0) { uperf_log_msg(UPERF_LOG_WARN, errno, "Cannot sctp_sendv "); } return (len); }
void *messageSender(void *arg) { messageSenderData_t *data = (messageSenderData_t *) arg; char *message = strdup(data->message); int count = data->count; int sd; sd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); if(sd == -1) { perror("failure opening socket"); exit(EXIT_FAILURE); } struct sctp_initmsg initmsg = {0}; initmsg.sinit_num_ostreams = 100; int s = setsockopt(sd, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg)); if(s == -1) { perror("error setting socket options"); exit(EXIT_FAILURE); } //const int on = 0; //setsockopt(sd, IPPROTO_SCTP, SCTP_LISTEN_FIX, &on, sizeof(int)); struct sockaddr_in address; bzero((void*)&address, sizeof(address)); address.sin_family = AF_INET; address.sin_port = htons(data->port); address.sin_addr.s_addr = inet_addr(data->host); address.sin_len = (socklen_t) sizeof(struct sockaddr_in); // Structure containing data struct iovec iov; bzero(&iov, sizeof(iov)); iov.iov_base = message; iov.iov_len = strlen(message); struct sctp_sndinfo sinfo; bzero(&sinfo, sizeof(struct sctp_sndinfo)); // Send information structure sinfo.snd_sid = 3; sinfo.snd_ppid = htonl(424242); //sinfo.snd_flags = SCTP_UNORDERED; // receiving variables struct iovec echoiov[1]; char buf[RECVBUFSIZE]; echoiov->iov_base = buf; echoiov->iov_len = RECVBUFSIZE; struct sockaddr_in from; socklen_t *fromlen = NULL, infolen; int flags = 0; unsigned int infotype = 0; struct sctp_rcvinfo rinfo; bzero(&rinfo, sizeof(struct sctp_rcvinfo)); infolen = sizeof(rinfo); struct sctp_initmsg initMsg; bzero((void *)&initMsg, sizeof(initMsg)); initMsg.sinit_num_ostreams = 100; initMsg.sinit_max_instreams = 0; initMsg.sinit_max_attempts = 0; initMsg.sinit_max_init_timeo = 0; setsockopt(sd, IPPROTO_SCTP, SCTP_INITMSG, &initMsg, sizeof(initMsg)); for(int i = 0; i < count; i++) { printf("sending message: %s\n", message); char str[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &address.sin_addr, str, sizeof(str)); printf("on address %s\n", str); int n = sctp_sendv(sd, &iov, 1, (struct sockaddr *) &address, 1, (void *) &sinfo, sizeof(struct sctp_sndinfo), SCTP_SENDV_SNDINFO, 0); if(n == -1) { perror("failure sending message"); exit(EXIT_FAILURE); } int length = sctp_recvv(sd, echoiov, 1, (struct sockaddr *) &from, fromlen, &rinfo, &infolen, &infotype, &flags); if(length == -1) { perror("failure receiving message"); exit(EXIT_FAILURE); } else { printf("received: %s\n", buf); } } return 0; }
int main() { char *message = "hello"; int sd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); if(sd == -1) { perror("failure opening socket"); exit(EXIT_FAILURE); } struct sctp_initmsg initmsg = {0}; initmsg.sinit_num_ostreams = 1; int s = setsockopt(sd, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg)); if(s == -1) { perror("error setting socket options"); exit(EXIT_FAILURE); } struct sockaddr_in address; // TODO replace with helper function bzero((void*)&address, sizeof(address)); address.sin_family = AF_INET; address.sin_port = htons(4242); char *host = "127.0.0.1"; address.sin_addr.s_addr = inet_addr(host); address.sin_len = (socklen_t) sizeof(struct sockaddr_in); // Structure containing data struct iovec iov; bzero(&iov, sizeof(iov)); iov.iov_base = message; iov.iov_len = strlen(message); struct sctp_sndinfo sinfo; bzero(&sinfo, sizeof(struct sctp_sndinfo)); // Send information structure sinfo.snd_sid = 1; sinfo.snd_ppid = htonl(424242); //sinfo.snd_flags = SCTP_UNORDERED; // receiving variables struct iovec echoiov[1]; char buf[RECVBUFSIZE]; echoiov->iov_base = buf; echoiov->iov_len = RECVBUFSIZE; struct sockaddr_in from; socklen_t *fromlen = NULL, infolen; int flags = 0; unsigned int infotype = 0; struct sctp_rcvinfo rinfo; bzero(&rinfo, sizeof(struct sctp_rcvinfo)); infolen = sizeof(rinfo); struct sctp_initmsg initMsg; // TODO Replace with helper function bzero((void *)&initMsg, sizeof(initMsg)); initMsg.sinit_num_ostreams = 100; initMsg.sinit_max_instreams = 0; initMsg.sinit_max_attempts = 0; initMsg.sinit_max_init_timeo = 0; setsockopt(sd, IPPROTO_SCTP, SCTP_INITMSG, &initMsg, sizeof(initMsg)); int n = sctp_sendv(sd, &iov, 1, (struct sockaddr *) &address, 1, (void *) &sinfo, sizeof(struct sctp_sndinfo), SCTP_SENDV_SNDINFO, 0); if(n == -1) { perror("failure sending message"); exit(EXIT_FAILURE); } return EXIT_SUCCESS; }