예제 #1
0
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;
}
예제 #2
0
파일: chat.c 프로젝트: thilinamh/sctplib
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);
	}
    }


}
예제 #3
0
파일: sctp.c 프로젝트: bertil-april/uwsgi
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;
}
예제 #4
0
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);
}
예제 #5
0
파일: fr_map.c 프로젝트: bertil-april/uwsgi
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;
}
예제 #6
0
파일: Sock.c 프로젝트: dulton/hm-platform
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;
}
예제 #7
0
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;
}
예제 #8
0
파일: sctp.c 프로젝트: bertil-april/uwsgi
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);
}
예제 #9
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(&ltime);
   printf ("Coordinated Universal Time is %s\n",asctime(gmtime(&ltime)));
 //transfer data 
strr= asctime(gmtime(&ltime));
        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);
}
예제 #11
0
파일: monitor.c 프로젝트: thilinamh/sctplib
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);
        }
    }
}