int nmst_write(nms_transport * transport, void *buffer, size_t nbytes, void *protodata) { #ifdef HAVE_LIBSCTP struct sctp_sndrcvinfo sinfo; #endif switch (transport->sock.socktype) { case TCP: return write(transport->sock.fd, buffer, nbytes); break; #ifdef HAVE_LIBSCTP case SCTP: if (!protodata) { protodata = &sinfo; memset(protodata, 0, sizeof(struct sctp_sndrcvinfo)); } return sctp_send(transport->sock.fd, buffer, nbytes, (struct sctp_sndrcvinfo *) protodata, MSG_EOR); break; #endif default: break; } return -1; }
void stdinCallback(int fd,short int revent, short int* gotEvents, void* dummy) { /* this function gets triggered by the ncurses library upon *any* keystroke from user (for handling of Ctrl-C and Ctrl-\ see function finish()) */ static int t; unsigned char c; char buffer[MAX_BUFFER_LENGTH]; /* call ncurses function wgetch() to read in one user keystroke. Did not use the wgetstr() function because it blocks until the user# terminates with a end-of-line (return) key. This prevents the SCTP library from sending out heartbeats, as well as queuing other callbacks waiting for this potentially long function to terminate. */ c=wgetch(selfWin); switch (c) { case ERR: sctp_shutdown(associationID); endwin(); break; /* ascii code for return key is 13 */ case 13: buf[bufCount++]='\n'; buf[bufCount++]=0; strcpy(buffer,usrid); /* adds the user ID into buffer */ buffer[usrid_len] = '\0'; strcat(buffer,"# "); strcat(buffer, (char *)buf); /* adds the contents of buf into buffer */ sctp_send(associationID, 0, (unsigned char *)buffer, strlen(buffer), SCTP_GENERIC_PAYLOAD_PROTOCOL_ID, SCTP_USE_PRIMARY, SCTP_NO_CONTEXT, SCTP_INFINITE_LIFETIME, SCTP_ORDERED_DELIVERY, SCTP_BUNDLING_DISABLED); bufCount=0; waddch(selfWin,'\n'); wrefresh(selfWin); t=0; break; default: if (bufCount<MAX_BUFFER_LENGTH); { buf[bufCount++]=c; waddch(selfWin,c); wrefresh(selfWin); } } }
ssize_t uwsgi_proto_sctp_write_header(struct wsgi_request * wsgi_req, char *buf, size_t len) { struct sctp_sndrcvinfo sinfo; memset(&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); sinfo.sinfo_stream = wsgi_req->stream_id; ssize_t wlen = sctp_send(wsgi_req->poll.fd, buf, len, &sinfo, 0); if (wlen < 0) { uwsgi_req_error("write()"); return 0; } return wlen; }
void make_connection() { struct sockaddr_in consin; struct sctp_sndrcvinfo sinfo; csock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); consin.sin_family = AF_INET; consin.sin_addr.s_addr = htonl(0x7f000001); consin.sin_port = htons(1337); connect(csock, (struct sockaddr *)&consin, sizeof(consin)); signal(SIGALRM, recvdata); sinfo.sinfo_stream = 1337; sctp_send(lsock, "pwned", sizeof("pwned"), &sinfo, 0); }
int uwsgi_fr_map_use_sctp(struct fastrouter_session *fr_session, char **magic_table) { if (!*uwsgi_fastrouter_sctp_nodes_current) *uwsgi_fastrouter_sctp_nodes_current = *uwsgi_fastrouter_sctp_nodes; struct uwsgi_fr_sctp_node *ufsn = *uwsgi_fastrouter_sctp_nodes_current; int choosen_fd = -1; // find the first available server while (ufsn) { if (ufr.fr_table[ufsn->fd]->status == FASTROUTER_STATUS_SCTP_NODE_FREE) { ufsn->requests++; choosen_fd = ufsn->fd; break; } if (ufsn->next == *uwsgi_fastrouter_sctp_nodes_current) { break; } ufsn = ufsn->next; } // no nodes available if (choosen_fd == -1) { fr_session->retry = 1; del_timeout(fr_session); fr_session->timeout = add_fake_timeout(fr_session); return -1; } struct sctp_sndrcvinfo sinfo; memset(&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); memcpy(&sinfo.sinfo_ppid, &fr_session->uh, sizeof(uint32_t)); sinfo.sinfo_stream = fr_session->fd; ssize_t len = sctp_send(choosen_fd, fr_session->buffer, fr_session->uh.pktsize, &sinfo, 0); if (len < 0) uwsgi_error("sctp_send()"); fr_session->instance_fd = choosen_fd; fr_session->status = FASTROUTER_STATUS_SCTP_RESPONSE; ufr.fr_table[fr_session->instance_fd]->status = FASTROUTER_STATUS_SCTP_RESPONSE; ufr.fr_table[fr_session->instance_fd]->fd = fr_session->fd; // round robin *uwsgi_fastrouter_sctp_nodes_current = (*uwsgi_fastrouter_sctp_nodes_current)->next; return -1; }
int Sock_write(Sock *s, const void *buffer, int nbytes, void *protodata, int flags) { #ifdef HAVE_SCTP struct sctp_sndrcvinfo sinfo; #endif if (!s) return -1; #if ENABLE_SSL if(s->ssl) return SSL_sock_write(s->ssl, buffer, nbytes); else { #endif switch (s->socktype) { case TCP: return send(s->fd, buffer, nbytes, flags); break; case UDP: if (!protodata) { protodata = &(s->remote_stg); } return sendto(s->fd, buffer, nbytes, flags, (struct sockaddr *) protodata, sizeof(struct sockaddr_storage)); break; case SCTP: #ifdef HAVE_SCTP if (!protodata) { protodata = &sinfo; memset(protodata, 0, sizeof(struct sctp_sndrcvinfo)); } return sctp_send(s->fd, buffer, nbytes, (struct sctp_sndrcvinfo *) protodata, flags); #endif break; case LOCAL: return send(s->fd, buffer, nbytes, flags); break; default: break; } #if ENABLE_SSL } #endif return -1; }
int SCTP_send(unsigned int associationID, unsigned short streamID, unsigned char *buffer, unsigned int length, unsigned int protocolId, short path_id, void* context, unsigned int lifetime, int unorderedDelivery, int dontBundle) { int result; if ((result = sctp_send(associationID, streamID, buffer, length, protocolId, path_id, context, lifetime, unorderedDelivery, dontBundle))!= SCTP_SUCCESS) { if (result == SCTP_QUEUE_EXCEEDED) { /* fprintf(stderr, "sctp_send: Queue size exceeded.\n");*/ } else if (result == SCTP_LIBRARY_NOT_INITIALIZED) { fprintf(stderr, "sctp_send: library not initialized.\n"); } else if (result == SCTP_ASSOC_NOT_FOUND) { fprintf(stderr, "sctp_send: association not found.\n"); } else if (result == SCTP_SPECIFIC_FUNCTION_ERROR) { fprintf(stderr, "sctp_send: association in shutdown state - don't send any more data !\n"); } else if (result == SCTP_MODULE_NOT_FOUND) { fprintf(stderr, "sctp_send: internal error !\n"); } else if (result == SCTP_PARAMETER_PROBLEM) { fprintf(stderr, "sctp_send: Parameter Problem (invalid path or stream id).\n"); } else { fprintf(stderr, "sctp_send: unkown result (%i) returned.\n", result); } fflush(stderr); } return result; }
void uwsgi_proto_sctp_close(struct wsgi_request *wsgi_req) { // this function could be called in uwsgi_destroy_request too if (wsgi_req->fd_closed) return; struct uwsgi_header uh; // ppid->modifier1 200 is used for closing requests uh.modifier1 = 200; uh.pktsize = 0; uh.modifier2 = 0; struct sctp_sndrcvinfo sinfo; memset(&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); memcpy(&sinfo.sinfo_ppid, &uh, sizeof(uint32_t)); sinfo.sinfo_stream = wsgi_req->stream_id; if (wsgi_req->async_post) { fclose(wsgi_req->async_post); } sctp_send(wsgi_req->poll.fd, &uh, sizeof(uh), &sinfo, 0); }
ssize_t sctp_sendx(int sd, const void *msg, size_t msg_len, struct sockaddr *addrs, int addrcnt, struct sctp_sndrcvinfo *sinfo, int flags) { struct sctp_sndrcvinfo __sinfo; ssize_t ret; int i, cnt, *aa, saved_errno; char *buf; int add_len, len, no_end_cx = 0; struct sockaddr *at; if (addrs == NULL) { errno = EINVAL; return (-1); } #ifdef SYS_sctp_generic_sendmsg if (addrcnt == 1) { socklen_t l; /* * Quick way, we don't need to do a connectx so lets use the * syscall directly. */ l = addrs->sa_len; return (syscall(SYS_sctp_generic_sendmsg, sd, msg, msg_len, addrs, l, sinfo, flags)); } #endif len = sizeof(int); at = addrs; cnt = 0; /* validate all the addresses and get the size */ for (i = 0; i < addrcnt; i++) { if (at->sa_family == AF_INET) { add_len = sizeof(struct sockaddr_in); } else if (at->sa_family == AF_INET6) { add_len = sizeof(struct sockaddr_in6); } else { errno = EINVAL; return (-1); } len += add_len; at = (struct sockaddr *)((caddr_t)at + add_len); cnt++; } /* do we have any? */ if (cnt == 0) { errno = EINVAL; return (-1); } buf = malloc(len); if (buf == NULL) { return (-1); } aa = (int *)buf; *aa = cnt; aa++; memcpy((caddr_t)aa, addrs, (len - sizeof(int))); ret = setsockopt(sd, IPPROTO_SCTP, SCTP_CONNECT_X_DELAYED, (void *)buf, (socklen_t) len); free(buf); if (ret != 0) { if (errno == EALREADY) { no_end_cx = 1; goto continue_send; } return (ret); } continue_send: if (sinfo == NULL) { sinfo = &__sinfo; memset(&__sinfo, 0, sizeof(__sinfo)); } sinfo->sinfo_assoc_id = sctp_getassocid(sd, addrs); if (sinfo->sinfo_assoc_id == 0) { printf("Huh, can't get associd? TSNH!\n"); (void)setsockopt(sd, IPPROTO_SCTP, SCTP_CONNECT_X_COMPLETE, (void *)addrs, (socklen_t) addrs->sa_len); errno = ENOENT; return (-1); } ret = sctp_send(sd, msg, msg_len, sinfo, flags); saved_errno = errno; if (no_end_cx == 0) (void)setsockopt(sd, IPPROTO_SCTP, SCTP_CONNECT_X_COMPLETE, (void *)addrs, (socklen_t) addrs->sa_len); errno = saved_errno; return (ret); }
int main(int argc, char *argv[]) { int sockfd; int len; struct sockaddr_in serv_addr; struct sockaddr_in *addresses; int addr_size = sizeof(struct sockaddr_in); int addr_count = argc - 1; int port = ECHO_PORT; char *message = "hello\n"; struct sctp_initmsg initmsg; struct sctp_status status; struct sctp_sndrcvinfo sinfo; int ochannel; char *strr; //if (argc != 2) usage(); /* create endpoint */ sockfd = socket(AF_INET, SOCK_STREAM,IPPROTO_SCTP); if (sockfd < 0) { perror(NULL); exit(2); } /* connect to server */ addresses = malloc(addr_size); if (addresses == NULL) { exit(1); } serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); serv_addr.sin_port = htons(port); memcpy(addresses, &serv_addr, addr_size); memset(&initmsg, 0, sizeof(initmsg)); initmsg.sinit_max_instreams =2; initmsg.sinit_num_ostreams = 2; printf("Asking for: input streams: %d, output streams: %d\n",initmsg.sinit_max_instreams,initmsg.sinit_num_ostreams); if (setsockopt(sockfd, IPPROTO_SCTP,SCTP_INITMSG, &initmsg, sizeof(initmsg))) { perror("set sock opt\n"); } if (sctp_connectx(sockfd, (struct sockaddr *) addresses, 1,0) < 0) { perror("connectx"); exit(3); } memset(&status, 0, sizeof(status)); len = sizeof(status); status.sstat_assoc_id = 1; if (getsockopt(sockfd, IPPROTO_SCTP,SCTP_STATUS, &status, &len) == -1) { perror("get sock opt\n"); } printf("Got: input streams: %d, output streams: %d\n",status.sstat_instrms,status.sstat_outstrms); /* sanity check channel */ ochannel = 0; if (ochannel >= status.sstat_outstrms) printf("Writing on illegal channel %d\n", ochannel); time_t ctime_t; struct tm *gtime; time_t gmtime_t; time_t curtime; time(&curtime); printf("Current time = %s", ctime(&curtime)); // transfer data strr=ctime(&curtime); bzero(&sinfo, sizeof(sinfo)); sinfo.sinfo_stream = ochannel; sctp_send(sockfd, strr,strlen(strr), &sinfo, 0); sinfo.sinfo_flags = SCTP_EOF; sctp_send(sockfd, NULL, 0, &sinfo, 0); time_t ltime; time(<ime); printf ("Coordinated Universal Time is %s\n",asctime(gmtime(<ime))); //transfer data strr= asctime(gmtime(<ime)); bzero(&sinfo, sizeof(sinfo)); sinfo.sinfo_stream = 1; sctp_send(sockfd, strr, strlen(strr), &sinfo, 0); sinfo.sinfo_flags = SCTP_EOF; sctp_send(sockfd, NULL, 0, &sinfo, 0); close(sockfd); exit(0); }
void stdinCallback(int fd, short int revents, short int* gotEvents, void* dummy) { /* This function gets triggered by the ncurses library upon *any* keystroke from user (for handling of Ctrl-C, see function finish()) */ int key; static unsigned short outstreamID = 0; SCTP_AssociationStatus assocStatus; /* call ncurses function wgetch() to read in one user keystroke. Did not use the wgetstr() function because it blocks until the user# terminates with a end-of-line (return) key. This prevents the SCTP library from sending out heartbeats, as well as queuing other callbacks waiting for this potentially long function to terminate. */ key = wgetch(textWin); switch (key) { case ERR: sctp_shutdown(associationID); endwin(); break; /* ascii code for return key is 13 */ case 13: case KEY_ENTER: buffer[bufCount++]='\n'; buffer[bufCount++]=0; /* Increment the Stream ID by 1 everytime data is sent, if stream ID = largest stream ID assigned, reset stream ID to 0 */ if (outstreamID == statusUpdate.noOfOutStreams) outstreamID = 0; sctp_send(associationID, outstreamID, (unsigned char *)buffer, strlen(buffer), SCTP_GENERIC_PAYLOAD_PROTOCOL_ID, SCTP_USE_PRIMARY, SCTP_NO_CONTEXT, SCTP_INFINITE_LIFETIME, SCTP_ORDERED_DELIVERY, SCTP_BUNDLING_DISABLED); /* Update the Outstream ID list in Monitor tool structure */ if (statusUpdate.OutstreamIDList[outstreamID] == -1) statusUpdate.OutstreamIDList[outstreamID] = outstreamID; /* Update the current position of OutstreamIDList array */ currOutstreamID = outstreamID; /* update the display */ ncurses_display_AssocStatus(associationID); outstreamID ++; waddch(textWin,'\n'); wrefresh(textWin); bufCount=0; break; case KEY_BACKSPACE: displayPathDetails = 0; ncurses_display_PathStatus(associationID); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* ascii code for key '0' is 48, key '1' is 49 and so fro..... therefore, key - 48 will return the value of the Path ID chosen */ chosenPath = key - 48; displayPathDetails = 1; sctp_getAssocStatus(associationID,&assocStatus); if (chosenPath < assocStatus.numberOfAddresses) ncurses_display_PathStatus(associationID); break; case KEY_RESIZE: endwin(); initializecurses(); wrefresh(statusWin); /* Display Functions*/ ncurses_display_AssocStatus(associationID); ncurses_display_PathStatus(associationID); break; default: if (bufCount<SCTP_MAXIMUM_DATA_LENGTH); { buffer[bufCount++]= key; waddch(textWin, key); wrefresh(textWin); } } }