Example #1
1
int main(int argc,char **argv)
{
	int sock_fd;
	int msg_flags;	// 記錄要傳送訊息時的相關設定,包括association...
	char readbuf[BUFFERSIZE];
	struct sockaddr_in cliaddr, servaddr;
	struct sctp_sndrcvinfo sri;
	struct sctp_event_subscribe evnts;
	socklen_t len;
	size_t rd_sz;	// size_t指的就是unsigned long
	int ret_value=0;
	struct sockaddr *laddrs;	// 用來記錄local addresses
	struct sockaddr *paddrs;
	union sctp_notification *snp;		// 用來轉換傳送過來的訊息
	struct sctp_shutdown_event *sse;	// 當傳送過來的是shutdown event,則可以用這一個指標指到傳送過來的資料
	struct sctp_assoc_change *sac;
	struct sctp_paddr_change *spc;
	struct sctp_remote_error *sre;
	struct sctp_send_failed *ssf;
#ifdef UN_MOD
	struct sctp_adaptation_event *ae;
#else
	struct sctp_adaption_event *ae;
#endif
	struct sctp_pdapi_event *pdapi;
	int close_time = 30;
	const char *str;

	if (argc < 2) {
		printf("Error, use %s [list of addresses to bind]\n",argv[0]);
		exit(-1);
	}
	// 建立socket的型態為SCTP的one-to-many的型態
	sock_fd = Socket(AF_INET,SOCK_SEQPACKET, IPPROTO_SCTP);
	if (sock_fd == -1) {
		printf("socket error\n");
		exit(-1);
	}

	// 初始化要bind的server資料,連續加入多個要綁的ip address
	int i;
	for (i=1;i<argc;i++) {
		memset(&servaddr,0,sizeof(servaddr));
		servaddr.sin_family = AF_INET;
		inet_pton(AF_INET,argv[i],&servaddr.sin_addr);	// 把socket與此ip綁在一起
		servaddr.sin_port = htons(SERV_PORT);

		// 把這一個ip與socket綁在一起
		if ((ret_value=sctp_bindx(sock_fd,(struct sockaddr*) &servaddr,1,SCTP_BINDX_ADD_ADDR))==-1) {
			printf("Can't bind the address %s\n",argv[i]);
			exit(-1);
		}
		else
		{
			// 無論如何一定會bind成功,因為,若給錯的ip,則會bind此host端的所有ip
			printf("Bind %s success!!\n",argv[i]);
		}
	}

	// 設定事件
	bzero(&evnts,sizeof(evnts));
	evnts.sctp_data_io_event=1;	// Enable sctp_sndrcvinfo to come with each recvmsg,否則就接收不到對方的資訊了
	evnts.sctp_shutdown_event=1;	// 喔耶!當client端shutdown時,會通知server
	evnts.sctp_association_event=1;	// 監測
	evnts.sctp_address_event = 1;
	evnts.sctp_send_failure_event = 1;
	evnts.sctp_peer_error_event = 1;
	evnts.sctp_partial_delivery_event = 1;
#ifdef UN_MOD
	evnts.sctp_adaptation_layer_event = 1;
#else
	evnts.sctp_adaption_layer_event = 1;
#endif
	ret_value = setsockopt(sock_fd,IPPROTO_SCTP,SCTP_EVENTS,&evnts,sizeof(evnts));
	if (ret_value == -1) {
		printf("setsockopt error\n");
		exit(-1);
	}
	ret_value = setsockopt(sock_fd,IPPROTO_SCTP,SCTP_AUTOCLOSE,&close_time,sizeof(close_time));
	if (ret_value == -1) {
		printf("setsockopt error\n");
		exit(-1);
	}

	// 設定多少個client可以連線
	ret_value = listen(sock_fd,LISTENQ);
	if (ret_value == -1) {
		printf("listen error\n");
		exit(-1);
	}

	printf("start wait...\n");
	for (;;) {
		memset(readbuf,0,sizeof(readbuf));
		len = sizeof(struct sockaddr_in);
		rd_sz = sctp_recvmsg(sock_fd,readbuf,sizeof(readbuf),(struct sockaddr *) &cliaddr,&len,&sri,&msg_flags);
		//========================================================================
		// test the sctp_getladdrs function - start
		ret_value = sctp_getladdrs(sock_fd,sri.sinfo_assoc_id,&laddrs);
		printf("The sctp_getladdrs return value is %d\n",ret_value);
		// test the sctp_getladdrs function - end
		// test the sctp_getpaddrs function - start
		ret_value = sctp_getpaddrs(sock_fd,sri.sinfo_assoc_id,&paddrs);
		printf("The sctp_getpaddrs return value is %d\n",ret_value);
		// test the sctp_getpaddrs function - end
		//========================================================================
		if (msg_flags & MSG_NOTIFICATION) {	// 表示收到一個事件通告,而非一個資料
			snp = (union sctp_notification *) readbuf;
			switch (snp->sn_header.sn_type) {
				case SCTP_SHUTDOWN_EVENT:
					sse = &snp->sn_shutdown_event;
					printf("SCTP_SHUTDOWN_EVENT: assoc=0x%x\n",(uint32_t) sse->sse_assoc_id);
					break;
				case SCTP_ASSOC_CHANGE:
					sac = &snp->sn_assoc_change;
					switch (sac->sac_state) {
						case SCTP_COMM_UP:
							printf("COMMUNICATION UP\n");
							break;
						case SCTP_COMM_LOST:
							printf("COMMUNICATION LOST\n");
							break;
						case SCTP_RESTART:
							printf("RESTART\n");
							break;
						case SCTP_SHUTDOWN_COMP:
							printf("SHUTDOWN COMPLETE\n");
							break;
						case SCTP_CANT_STR_ASSOC:
							printf("CAN'T START ASSOC\n");
							break;
						default:
							printf("UNKNOW\n");
							break;
					}
					break;
				case SCTP_PEER_ADDR_CHANGE:
					spc = &snp->sn_paddr_change;
					switch(spc->spc_state) {
						case SCTP_ADDR_AVAILABLE:
							str = "ADDRESS AVAILABLE";
							break;
						case SCTP_ADDR_UNREACHABLE:
							str = "ADDRESS UNREACHABLE";
							break;
						case SCTP_ADDR_REMOVED:
							str = "ADDRESS REMOVED";
							break;
						case SCTP_ADDR_ADDED:
							str = "ADDRESS ADDED";
							break;
						case SCTP_ADDR_MADE_PRIM:
							str = "ADDRESS MADE PRIMARY";
							break;
						case SCTP_ADDR_CONFIRMED:
							str = "ADDRESS MADE CONFIRMED";
							break;
						default:
							str = "UNKNOW";
							break;
					}
					printf("SCTP_PEER_ADDR_CHANGE: %s\n",str);
					break;
				case SCTP_REMOTE_ERROR:
					sre = &snp->sn_remote_error;
					printf("SCTP_REMOTE_ERROR\n");
					break;
				case SCTP_SEND_FAILED:
					ssf = &snp->sn_send_failed;
					printf("SCTP_SEND_FAILED\n");
					break;
#ifdef UN_MOD
				case SCTP_ADAPTATION_INDICATION:
					ae = &snp->sn_adaptation_event;
					printf("SCTP_ADAPTION_INDICATION\n");
					break;
#else
				case SCTP_ADAPTION_INDICATION:
					ae = &snp->sn_adaption_event;
					printf("SCTP_ADAPTION_INDICATION\n");
					break;
#endif
				case SCTP_PARTIAL_DELIVERY_EVENT:
					pdapi = &snp->sn_pdapi_event;
					if (pdapi->pdapi_indication == SCTP_PARTIAL_DELIVERY_ABORTED)
						printf("SCTP_PARTIAL_DELIEVERY_ABORTED\n");
					else
						printf("Unknown SCTP_PARTIAL_DELIVERY_EVENT\n");
					break;
				default:
					printf("UNKNOWN notification\n");
					break;
			}
			continue;
		}
		printf("%s",readbuf);
		ret_value = sctp_sendmsg(sock_fd,readbuf,rd_sz,(struct sockaddr *) &cliaddr,len,sri.sinfo_ppid,sri.sinfo_flags,sri.sinfo_stream,0,0);
		if (ret_value == -1) {
			printf("sctp_sendmsg error\n");
			exit(-1);
		}

	}

	return 0;
}
Example #2
0
void message::printsys()
{
	len = sizeof(struct sockaddr_in);
	rd_sz = sctp_recvmsg(sock_fd,readbuf,sizeof(readbuf),(struct sockaddr *) &cliaddr,&len,&sri,&msg_flags);
	ret_value = sctp_sendmsg(sock_fd,readbuf,rd_sz,(struct sockaddr *) &cliaddr,len,sri.sinfo_ppid,sri.sinfo_flags,sri.sinfo_stream,0,0);
	if (ret_value == -1)
	{
		qWarning("sctp_sendmsg error");
		exit(-1);
	}
}
Example #3
0
int Sctp_sendmsg(int s, void* data, size_t len, struct sockaddr* to,
                 socklen_t tolen, uint32_t ppid, uint32_t flags,
                 uint16_t stream_no, uint32_t timetolive, uint32_t context)
{
    int ret;
    ret = sctp_sendmsg(s, data, len, to, tolen, ppid, flags, stream_no,
                       timetolive, context);
    if (ret < 0) {
        err_sys("sctp_sendmsg error");
    }
    return (ret);
}
Example #4
0
int
main(int argc, char **argv)
{
	int sock_fd,msg_flags;
	char readbuf[BUFFSIZE];
	struct sockaddr_in6 servaddr, cliaddr;
	struct sctp_sndrcvinfo sri;
	struct sctp_event_subscribe evnts;
	int stream_increment=1;
	socklen_t len;
	size_t rd_sz;

	if (argc == 2)
		stream_increment = atoi(argv[1]);
        sock_fd = socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP);
	if (sock_fd < 0)
  	{
    		perror("socket()");
    		exit(errno);
  	}

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin6_family = AF_INET;
//	servaddr.sin6_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin6_port = htons(SERV_PORT);

	bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));
	
	bzero(&evnts, sizeof(evnts));
	evnts.sctp_data_io_event = 1;
	setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS,
		   &evnts, sizeof(evnts));

	listen(sock_fd, LISTENQ);
	for ( ; ; ) {
		len = sizeof(struct sockaddr_in6);
		rd_sz = sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),
			     (SA *)&cliaddr, &len,
			     &sri,&msg_flags);
		if(stream_increment) {
			sri.sinfo_stream++;
			if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) 
				sri.sinfo_stream = 0;
		}
		sctp_sendmsg(sock_fd, readbuf, rd_sz, 
			     (SA *)&cliaddr, len,
			     sri.sinfo_ppid,
			     sri.sinfo_flags,
			     sri.sinfo_stream,
			     0, 0);
	}
}
Example #5
0
static void echo(int fd, int socketModeUDP)
{
   struct  sctp_sndrcvinfo  sri;
   char                     buf[BUFLEN];
   size_t                   buflen;
   ssize_t                  received;
   int                      flags;
   unsigned int             outgoing = 1;
   union sctp_notification *snp;

   /* Wait for something to echo */
   buflen = sizeof(buf);
   flags  = 0;
   received = sctp_recvmsg(fd, buf, buflen, NULL, 0, &sri, &flags);
   while(received > 0) {
      /* Intercept notifications here */
      if(flags & MSG_NOTIFICATION) {
         snp = (union sctp_notification *)buf;
         if(snp->sn_header.sn_type == SCTP_ASSOC_CHANGE) {
            /* incoming = snp->sn_assoc_change.sac_inbound_streams; */
            outgoing = snp->sn_assoc_change.sac_outbound_streams;
         }
         handle_event(buf);
      }
      else {
         printf("got %u bytes on stream %hu:\n", (unsigned int)received, sri.sinfo_stream);
         fflush(stdout);
         write(0, buf, received);

         /* Echo it back */
         if(sctp_sendmsg(fd, buf, received, NULL, 0,
                         0x29091976, 0,
                         sri.sinfo_stream % outgoing,
                         0, 0) < 0) {
            perror("sendmsg");
            exit(1);
         }
      }

      buflen = sizeof(buf);
      flags  = 0;
      received = sctp_recvmsg(fd, buf, buflen, NULL, 0, &sri, &flags);
   }

   if(received < 0) {
      perror("sctp_recvmsg");
   }
   if(socketModeUDP == 0) {
      ext_close(fd);
   }
}
Example #6
0
static PyObject* sctp_send_msg(PyObject* dummy, PyObject* args)
{
	int fd, msg_len, size_sent, ppid, flags, stream, ttl, context;
	const char *msg;
	char *to;
	int port;

	struct sockaddr_storage sto;
	struct sockaddr_storage *psto = &sto;
	int sto_len;

	PyObject *ret = 0;

	if (! PyArg_ParseTuple(args, "is#(si)iiiii", &fd, &msg, &msg_len, &to, &port, 
					&ppid, &flags, &stream, &ttl, &context)) {
		return ret;
	}

	if (msg_len <= 0 && (! (flags & MSG_EOF))) {
		PyErr_SetString(PyExc_ValueError, "Empty messages are not allowed, except if coupled with the MSG_EOF flag.");
		return ret;
	}

	// TODO: "to" can contain and assoc_id. For this to be possible, we will need to 
	//       use bare sendmsg() instead of sctp_sendmsg().

	if (strlen(to) == 0) {
		// special case: should pass NULL 
		sto_len = 0;
		psto = 0;
	} else {
		if (! to_sockaddr(to, port, (struct sockaddr*) psto, &sto_len)) {
			PyErr_SetString(PyExc_ValueError, "Invalid Address");
			return ret;
		}
	}

	size_sent = sctp_sendmsg(fd, msg, msg_len, (struct sockaddr*) psto, sto_len, ppid, 
					flags, stream, ttl, context);

	if (size_sent < 0) {
		PyErr_SetFromErrno(PyExc_IOError);
		return ret;
	}

	ret = PyInt_FromLong(size_sent);
	return ret;
}
Example #7
0
/***************************************************************************
** Used by M3UA to send messages on the specified assoc/stream combination.
****************************************************************************/
m3_s32	m3ua_sendmsg(m3_u32		assoc_id,
                     m3_u32		stream_id,
                     m3_u32             msglen,
                     m3_u8              *pmsg)
{
    iu_log_debug("%s  %d: %s\n",__FILE__, __LINE__, __func__);
    
    int			ret;
    int			tid = assoc_table[assoc_id].to; //msc 0 sgsn 1
    int			fid = assoc_table[assoc_id].from;//msc 0 , sgsn 1
    iu_log_debug("assoc_id = %d, from = %d, to = %d\n",assoc_id, assoc_table[assoc_id].from, assoc_table[assoc_id].to);
	struct sockaddr_in* paddr = NULL;
	if(0 == to[tid].issecondary)
	{
	    paddr = (struct sockaddr_in*)&to[tid].addr[0];
	}
	else
	{
	    paddr = (struct sockaddr_in*)&to[tid].addr[1];
	}
	int			sock_fd = from[fid].sockid;
    iu_log_debug("sock_fd = %d\n", sock_fd);
    unsigned int  ppid = 3;

#ifdef __M3UA_PRINT_OUTGOING_MESSAGE__
    int                 m_idx, byte;
    iu_log_debug("\n<------ Outgoing Message ------>\n");
    iu_log_debug("\n    Number of Bytes in Message = %d\n", msglen);
    for (m_idx = 0; m_idx < msglen; ) {
        byte = pmsg[m_idx++];
        iu_log_debug("%02x ", byte);
        if (0 == m_idx%4) {
            iu_log_debug("\n");
        }
    }
#endif
    iu_log_debug("msglen = %d, stream_id = %d\n",msglen,stream_id);
    ppid = htonl(ppid);
    iu_log_debug("assoc_id = %d, tid = %d, fid = %d, addr = %s, port = %d &&&&&&&&\n", assoc_id, tid, fid, inet_ntoa(paddr->sin_addr), paddr->sin_port);
    ret = sctp_sendmsg (sock_fd, pmsg, msglen, (struct sockaddr *)paddr, sizeof(struct sockaddr), ppid, 0,
					stream_id, 0, 0);

    if (0 >= ret) {
        iu_log_debug("ERRNO:%d\n", errno);
        perror("E_sctp_sendmsg_Fail");
    }
    return 0;
}
Example #8
0
void zmq::sctp_engine_t::out_event (handle_t handle_)
{
    message_t msg;
    if (!mux.read (&msg)) {

        //  If there are no messages to send, stop polling for output.
        poller->reset_pollout (handle);
        return;
    }

    //  Send the data over the wire.
    ssize_t nbytes = sctp_sendmsg (s, msg.data (), msg.size (),
        NULL, 0, 0, 0, 0, 0, 0);
    errno_assert (nbytes != -1);
    assert (nbytes == (ssize_t) msg.size ());
}
int main(int argc,char **argv)
{
	int sock_fd,msg_flags;
	char readbuf[1024];
	struct sockaddr_in servaddr,cliaddr;
	struct sctp_sndrcvinfo sri;
	struct sctp_event_subscribe evnts;
	socklen_t len;
	size_t rd_sz;

	if ((sock_fd = socket(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP)) < 0) {
		perror("socket");
	}

	bzero(&servaddr,sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(9877);
	if (bind(sock_fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
		perror("bind");
	}

	bzero(&evnts, sizeof(evnts));
	evnts.sctp_data_io_event = 1;
	if (setsockopt(sock_fd,IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)) < 0) {
		perror("setsockopt");
	}

	if (listen(sock_fd,5) < 0) {
		perror("listen");
	}

	for (;;) {
		len = sizeof(struct sockaddr_in);
		printf("start wait...\n");
		rd_sz = sctp_recvmsg(sock_fd,readbuf, sizeof(readbuf), (struct sockaddr *)&cliaddr, &len, &sri, &msg_flags);
		printf("sctp_recvmsg() received %d bytes from %s:%d.\n", (int)rd_sz, inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
		if (rd_sz > 0) {
			if (sctp_sendmsg(sock_fd, readbuf, rd_sz, (struct sockaddr *)&cliaddr, len, sri.sinfo_ppid, sri.sinfo_flags, sri.sinfo_stream, 0, 0) < 0) {
				perror("sctp_sendmsg");
			}
		}
	}
	return 0;
}
Example #10
0
/** 
 * @brief Send data using SEQPKT socket. 
 *
 * The data is sent and PPID and Stream ID are set as requested.
 * 
 * @param sock The socket to use when sending.
 * @param ppid  PPID for the SCTP chunk
 * @param streamno The stream no for the stream where the data is to be written.
 * @param dst Destination host
 * @param dst_len Length of the sockaddr structure.
 * @param chunk The data to send.
 * @param chunk_size  Number of bytes to send.
 * 
 * @return Number of bytes sent on success <0 on error.
 */
int sendit( int sock, uint32_t ppid, uint16_t streamno,
                struct sockaddr *dst, size_t dst_len,
                uint8_t *chunk, int chunk_size )
{
        int ret;

        TRACE("Sending with ppid %d and stream no %d\n", ppid, streamno);

        ret = sctp_sendmsg( sock, chunk, chunk_size, 
                        dst, dst_len,
                        ppid, /* ppid */
                        0, /* flags */
                        streamno, /* stream no */
                        0, /* ttl */
                        0xF00F /* context */
                        );
        TRACE( "Sent %d / %d bytes \n", ret, chunk_size );
        return ret;
}
Example #11
0
int main()
{
  int connSock, in, i, ret, flags;
  struct sockaddr_in servaddr;
  struct sctp_status status;
  char buffer[MAX_BUFFER+1];

  connSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP );

  if(connSock == -1)
    die("socket()");

  bzero( (void *)&servaddr, sizeof(servaddr) );
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(MY_PORT_NUM);
  // servaddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
  servaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

  ret = connect( connSock, (struct sockaddr *)&servaddr, sizeof(servaddr) );
  
  if(ret == -1)
    die("connect()");

  printf("Enter data to send : ");
  gets(buffer);
  // scanf("%s", buffer);
  //getchar();
  
  ret = sctp_sendmsg( connSock, (void *)buffer, (size_t)strlen(buffer), NULL, 0, 0, 0, 0, 0, 0 );
  memset(buffer, '\0', sizeof(buffer));
  // printf("ret = %d\n", ret);
  in = sctp_recvmsg( connSock, (void *)buffer, sizeof(buffer), (struct sockaddr *)NULL, 0, 0, 0 );
  // printf("in = %d\n", in);
  printf("response = %s\n", buffer);
  memset(buffer, '\0', sizeof(buffer));

  close(connSock);

  return 0;
}
static gssize
sctp_socket_send_with_blocking (GSocket * socket, guint streamid,
    guint32 timetolive, const gchar * buffer, gsize size, gboolean blocking,
    GCancellable * cancellable, GError ** error)
{
  gssize ret;

  if (g_socket_is_closed (socket)) {
    g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
        "Socket is already closed");
    return -1;
  }

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return -1;

  while (TRUE) {
    if (blocking &&
        !g_socket_condition_wait (socket, G_IO_OUT, cancellable, error))
      return -1;

    if ((ret = sctp_sendmsg (g_socket_get_fd (socket), buffer, size, NULL, 0,
                0, 0, streamid, timetolive, 0)) < 0) {
      if (errno == EINTR)
        continue;

      if (blocking) {
        if (errno == EWOULDBLOCK || errno == EAGAIN)
          continue;
      }

      g_set_error (error, G_IO_ERROR, errno, "Error sending data: %s",
          strerror (errno));
      return -1;
    }
    break;
  }

  return ret;
}
Example #13
0
static int sctp_send_msg(int32_t sctp_assoc_id, uint16_t stream,
                         const uint8_t *buffer, const uint32_t length)
{
    struct sctp_association_s *assoc_desc = NULL;

    DevAssert(buffer != NULL);

    if ((assoc_desc = sctp_is_assoc_in_list(sctp_assoc_id)) == NULL) {
        SCTP_DEBUG("This assoc id has not been fount in list (%d)\n",
                   sctp_assoc_id);
        return -1;
    }

    if (assoc_desc->sd == -1) {
        /* The socket is invalid may be closed.
         */
        return -1;
    }

    SCTP_DEBUG("[%d][%d] Sending buffer %p of %d bytes on stream %d with ppid %d\n",
               assoc_desc->sd, sctp_assoc_id, buffer,
               length, stream, assoc_desc->ppid);

    /* Send message_p on specified stream of the sd association */
    if (sctp_sendmsg(assoc_desc->sd,
                     (const void *)buffer,
                     length,
                     NULL,
                     0,
                     assoc_desc->ppid, 0, stream, 0, 0) < 0) {
        SCTP_ERROR("send: %s:%d", strerror(errno), errno);
        return -1;
    }

    assoc_desc->messages_sent++;

    SCTP_DEBUG("Successfully sent %d bytes on stream %d\n", length, stream);

    return 0;
}
int
send_bframe()
{
	int ret;
	buffer[0] = 'B';
	if ((ret = sctp_sendmsg(fd,
			 (const void *)buffer, SIZE_OF_P_FRAME,
			 (struct sockaddr *)&addr, sizeof(struct sockaddr_in),
			 htonl(66),       /* PPID */
			 0, /* flags */
			 1,                /* stream identifier */
			 0,                /* Max number of rtx */
			 0                 /* context */
		     )) < 0) {
		perror("sctp_sendmsg - B");
	} else {
		bcount++;
	}
	printf("I:%d P:%d B:%d\r", icount, pcount, bcount);
	fflush(stdout);
	return(ret);
}
Example #15
0
void sctpstr_cli_echoall(FILE *fp,int sock_fd,struct sockaddr *to,socklen_t tolen)
{
    struct sockaddr_in peeraddr;
    struct sctp_sndrcvinfo sri;
    char sendline[SCTP_MAXLINE], recvline[SCTP_MAXLINE];
    socklen_t len;
    int rd_sz,i,strsz;
    int msg_flags;
    int ret_value=0;

    // the client initializes the sri structure used to set up the stream it will be sending and receiving from
    bzero(sendline,sizeof(sendline));
    bzero(&sri,sizeof(sri));
    while(fgets(sendline,SCTP_MAXLINE-9,fp) != NULL) {
        strsz = strlen(sendline);
        // delete the newline character that is at the end of the buffer
        if (sendline[strsz-1] == '\n') {
            sendline[strsz-1]='\0';
            strsz--;
        }
        // 傳送SERV_MAX_SCTP_STRM筆資料給server
        for (i=0; i<SERV_MAX_SCTP_STRM; i++) {
            snprintf(sendline+strsz,sizeof(sendline)-strsz,".msg.%d",i);
            ret_value = sctp_sendmsg(sock_fd,sendline,sizeof(sendline),to,tolen,0,0,i,0,0);
            if (ret_value == -1) {
                printf("sctp_sendmsg error\n");
                exit(-1);
            }
        }
        // 由server接收SERV_MAX_SCTP_STRM筆資料
        for (i=0; i<SERV_MAX_SCTP_STRM; i++) {
            len = sizeof(peeraddr);
            rd_sz = sctp_recvmsg(sock_fd,recvline,sizeof(recvline),(struct sockaddr *) &peeraddr,&len,&sri,&msg_flags);
            printf("From str:%d seq:%d (assoc:0x%x):",sri.sinfo_stream,sri.sinfo_ssn,(u_int) sri.sinfo_assoc_id);
            printf("%.*s\n",rd_sz,recvline);
        }
    }
}
Example #16
0
int send_to_target(int s, 
                                    const void *msg, 
                                    size_t len,
                                    struct sockaddr *to, 
                                    socklen_t tolen,
                                    uint32_t ppid, 
                                    uint32_t flags,
                                    uint16_t stream_no, 
                                    uint32_t timetolive,
                                    uint32_t context)
{
	int status = -1;
	do 
	{
		int error = sctp_sendmsg(s, msg, len, to, tolen, ppid, flags, stream_no, timetolive, context);
		if (len != error)
		{
			perror("sctp_sendmsg");
			break;
		}
		status = 0;
	} while (0);
	return status;
}
int main(int argc, char** argv)
{
	int sock;//, msg_flags;
	char readbuf[2000];

	struct sockaddr_in servaddr;
	struct sctp_sndrcvinfo sri;
	struct sctp_event_subscribe evnts;

	struct hostent *addr;
	struct sctp_initmsg initmsg;
	char inFile[2048];//NULL;
	FILE* file = NULL;

	int sz,sent = 0;
	socklen_t len;
	size_t rd_sz;


	if(argc < 3)
	{
		printf("Missing argument - use '%s peer file'\n",argv[0]);
		exit(-1);
	}
	strcpy(inFile,argv[2]);

	bzero(&servaddr,sizeof(servaddr));


	if(atoi(argv[1]) > 0)
	{
		servaddr.sin_family = AF_INET;
		servaddr.sin_addr.s_addr = inet_addr(argv[1]);
	}
	else
	{
		if ((addr=gethostbyname(argv[1])) == NULL)
		{ //Adress not found
			perror("bad hostname");
			exit(-1);
		}
		//Set address family
		servaddr.sin_family = addr->h_addrtype;

		//Copy and set adress
		bcopy(addr->h_addr_list[0],(char*)&servaddr.sin_addr.s_addr,  sizeof(struct in_addr));
	}

	if((file = fopen(argv[2],"r")) == NULL)
	{
		printf("file not found: %s\n", argv[2]);
		exit(-1);
	}

	servaddr.sin_port = htons(2960);

	sock = socket(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP);

	bzero(&evnts,sizeof(evnts));
	evnts.sctp_data_io_event = 1;
	if(setsockopt(sock,IPPROTO_SCTP,SCTP_EVENTS,&evnts,sizeof(evnts))<0)
		perror("setsockopt evnts");

	bzero(&initmsg,sizeof(initmsg));
	initmsg.sinit_num_ostreams = 2;
    initmsg.sinit_max_instreams = 2;
    initmsg.sinit_max_attempts = 0;
    initmsg.sinit_max_init_timeo  = 0;

    len = sizeof(initmsg);
   	if (setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg)) < 0) {
      perror("setsockopt SCTP_INITMSG");
      close(sock);
      exit(-1);
    }

	sri.sinfo_stream = 0;
	printf("SENDING FILENAME: %s\n",inFile);

	len = sizeof(servaddr);
	if((sz = sctp_sendmsg(sock,inFile,strlen(inFile),(struct sockaddr*)&servaddr,len,sri.sinfo_ppid,sri.sinfo_flags,sri.sinfo_stream,0,0))
			< strlen(argv[2]))
	{
		printf("could not send file name\n");
		close(sock);
		exit(-1);
	}
	else
	{
		printf("filename sent\n");
	}
	sri.sinfo_ppid = 0;
	while(!feof(file) && !ferror(file))
	{
		sri.sinfo_ppid++;
		sri.sinfo_ppid = sri.sinfo_ppid % 10;
		printf("using ppid %d\n", sri.sinfo_ppid);

		if((rd_sz = fread(readbuf,sizeof(char),512,file))>=0)
		{
			if((sz = sctp_sendmsg(sock,readbuf,rd_sz,(struct sockaddr*)&servaddr,len,sri.sinfo_ppid,sri.sinfo_flags,sri.sinfo_stream,0,0))<0)
				perror("send error\n");
			else
				sent += sz;
		}
		else{
			perror("file read error\n");
		}
	}
	if(ferror(file))
	{
		perror("file error\n");
	}
	bzero(readbuf,sizeof(readbuf));
	sri.sinfo_flags = MSG_EOF;
	if(sctp_sendmsg(sock,readbuf,0,(struct sockaddr*)&servaddr,len,sri.sinfo_ppid,sri.sinfo_flags,sri.sinfo_stream,0,0) < 0)
		perror("sending EOF\n");

	printf("%d bytes sent successfully\n",sent);
	fclose(file);
	shutdown(sock,SHUT_RDWR);

	return 0;
}
int main(int argc, char **argv) {
    int i, j;
    int size, align_size;
    char *s_buf, *r_buf;
    double t_start = 0.0, t_end = 0.0, t = 0.0;


    struct sockaddr_in *dest = malloc(sizeof(struct sockaddr_in));
    struct sctp_sndrcvinfo sri;
    struct sockaddr_in cli;
    socklen_t s = sizeof(struct sockaddr_in);
    int msg_flags = 0;
    int n=-1;
    char mode[15];


    struct timeval start, end;
    struct dp datapoints[DATAPOINTS];
    int num_dp = 0;
    FILE *file;
    char filename[PRINTARRAY];
    char ascii_size[PRINTARRAY];
    int name[] = {CTL_KERN, KERN_OSTYPE};
    int namelen = 2;
    char oldval[15];
    size_t len = sizeof(oldval);
    int  error;    


    if (argc < 3) {
	printf("Usage: %s dst-ip dest-port\n", argv[0]);
	exit(1);
    }
    
#if defined(SCTP_USERMODE)
    uint32_t optval=1;
    struct socket *psock = NULL;
    strcpy(mode, "Userspace");
#else //kernel mode
    int sock_fd;
    strcpy(mode, "Kernel");
#endif


    align_size = getpagesize();
    assert(align_size <= MAX_ALIGNMENT);

    s_buf =
        (char *) (((unsigned long) s_buf1 + (align_size - 1)) /
                  align_size * align_size);
    r_buf =
        (char *) (((unsigned long) r_buf1 + (align_size - 1)) /
                  align_size * align_size);

    
    error = sysctl (name, namelen,
                    (void *)oldval, &len, NULL
                    /* newval */, 0 /* newlen */);
    if (error) {
        printf("sysctl() error\n");
        exit(1);
    }

    strcpy(filename, "BWbenchmark");
    sprintf(ascii_size,"%s%smode",oldval,mode);
    strcat(filename, ascii_size);
    strcat(filename,".txt");

    
#if defined(SCTP_USERMODE)
    sctp_init(); 
    SCTP_BASE_SYSCTL(sctp_udp_tunneling_for_client_enable)=1; 
    
    if( !(psock = userspace_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) ){
        printf("user_socket() returned NULL\n");
        exit(1);
    }
#else //Kernel mode
    if((sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1) {
        printf("socket error\n");
        exit(1);
    }
#endif
    
    /* prepare destination adddress */
    bzero(dest, sizeof(struct sockaddr_in));
    dest->sin_family = AF_INET;
    dest->sin_addr.s_addr = inet_addr(argv[1]);
    dest->sin_port = htons((unsigned short) atoi(argv[2]));
#if defined(__Userspace_os_FreeBSD)
    dest->sin_len = sizeof(struct sockaddr);
#endif

#if defined(SCTP_USERMODE)
    /* call userspace_connect which eventually calls sctp_send_initiate */
    if( userspace_connect(psock, (struct sockaddr *) dest, sizeof(struct sockaddr_in)) == -1 ) {
        printf("userspace_connect failed.  exiting...\n");
        exit(1);        
    }

    sctp_setopt(psock, SCTP_NODELAY, &optval, sizeof(uint32_t), NULL);

#else //Kernel mode
    if((connect(sock_fd, (struct sockaddr *) dest, sizeof(struct sockaddr_in))) == -1) {
        perror("connect error\n");
        exit(1);
    }
    /* Setting the send and receive socket buffer sizes */
    const int maxbufsize = 65536 * 3;
    int sndrcvbufsize = maxbufsize;
    int sndrcvbufsize_len;
    int rc;
    sndrcvbufsize_len = sizeof(sndrcvbufsize);
    rc = setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &sndrcvbufsize, sndrcvbufsize_len);
    
    if (rc == -1) {
        perror("can't set the socket send size to requested one");
        exit(1);
    }
    
    rc = setsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &sndrcvbufsize, sndrcvbufsize_len);
    
    if (rc == -1) {
        perror("can't set the socket receive size to requested one");
        exit(1);
    }
    
    /* turning nagle off */
    int no_nagle = 1;
    if (setsockopt(sock_fd, IPPROTO_SCTP,
                   SCTP_NODELAY, (char *) &no_nagle, sizeof(no_nagle)) < 0){
        perror("can't setsockopt to no_nagle\n");
        exit(1);
    }
#endif



    num_dp = 0;
    int retval = 0;

    printf("\nRunning in %s mode\nStoring results in file %s\n\n", mode, filename);

    fprintf(stdout, "# %s %s\n", mode, "Mode: Bandwidth Benchmark Similar to OSU");
    fprintf(stdout, "%-*s%*s\n", 10, "# Size", FIELD_WIDTH,
            "Bandwidth (MB/s)");
    fflush(stdout);


    /* Bandwidth test */
    for(size = 1; size <= MAX_MSG_SIZE; size *= 2) {
        /* touch the data */
        for(i = 0; i < size; i++) {
            s_buf[i] = 'a';
            r_buf[i] = 'b';
        }
        
        if(size > large_message_size) {
            loop = loop_large;
            skip = skip_large;
            window_size = window_size_large;
        }
        

        for(i = 0; i < loop + skip; i++) {
            if(i == skip) {
                gettimeofday(&start, NULL);
                t_start = (double) start.tv_sec + .000001 * (double) start.tv_usec;
            }
            
            for(j = 0; j < window_size; j++) {
#if defined(SCTP_USERMODE)
                if((retval = userspace_sctp_sendmsg(psock /* struct socket *so */,
                                                    s_buf /* const void *data */,
                                                    size /* size_t len */,
                                                    (struct sockaddr *)dest /* const struct sockaddr *to */,
                                                    sizeof(struct sockaddr_in) /* socklen_t tolen */,
                                                    0 /* u_int32_t ppid */,
                                                    0 /* u_int32_t flags */,
                                                    3 /* u_int16_t stream_no */,
                                                    0 /* u_int32_t timetolive */,
                                                    0 /* u_int32_t context */))<=0)
                    {
                        printf("userspace_sctp_sendmsg returned retval=%d errno=%d\n", retval, errno);
                        exit(1);
                        
                    }
#else //Kernel mode
                
                if ((retval = sctp_sendmsg(sock_fd, (void *)s_buf, (size_t)size, NULL, 0, 0, 0, 3, 0, 0)) <=0 )
                    {
                        printf("sctp_sendmsg returned retval=%d errno=%d\n", retval, errno);
                        exit(1);
                    }
#endif        
                
                
            }


#if defined(SCTP_USERMODE)
            if ((n = userspace_sctp_recvmsg(psock, r_buf, 4, (struct sockaddr *) &cli, &s, &sri, &msg_flags)) <=0 )
                {
                    printf(".....userspace_sctp_recvmsg returned n=%d errno=%d\n", n, errno);
                    break;
                }
#else  //Kernel mode
            if ((n = sctp_recvmsg(sock_fd, r_buf, 4, (struct sockaddr *) &cli, &s, &sri, &msg_flags)) <=0 )
                {
                    printf("sctp_recvmsg returned n=%d errno=%d\n", n, errno);
                    break;
                }
#endif
            
        }
        
        gettimeofday(&end, NULL);
        t_end = (double) end.tv_sec + .000001 * (double) end.tv_usec;
        
        t = t_end - t_start;
        
        double tmp = size / 1e6 * loop * window_size;
        
        fprintf(stdout, "%-*d%*.*f\n", 10, size, FIELD_WIDTH,
                FLOAT_PRECISION, tmp / t);
        fflush(stdout);
        datapoints[num_dp].msg_size = size;
        datapoints[num_dp].tottime = t;
        datapoints[num_dp].bw = tmp/t;
        num_dp++;
        
    }
    
    
    printf("Client closing socket...errno=%d\n", errno);
    free(dest);
#if defined(SCTP_USERMODE)
    userspace_close(psock);
#else
    close(sock_fd);
#endif
    
    printf("Sleeping for 60 secs\n");
    sleep(60);
    
    file = fopen(filename, "w+");
    if(file == NULL) {
        perror("could not open results file");
    } else {        
        for (j=0; j<num_dp; j++)
        {
            fprintf(file,"%d , %.2f , %.2f\n",datapoints[j].msg_size, datapoints[j].tottime, datapoints[j].bw); /*write datapoints to file*/
        }
        fclose(file);
    }


#if defined(SCTP_USERMODE)
    sctp_finish();
    //    pthread_exit(NULL);
#endif

    return 0;
        
}
Example #19
0
void client_mode() {

	int i, error, stream, max_socket = 0;
	uint32_t ppid = 0;
	int client_socket[assoc_num];
	char *message = "Awake";
	fd_set rfds;
	struct timeval tv;

        stream = 1;

	printf("Running in Client Mode...\n");

        /* Create the sockets */
	for (i = 0; i < assoc_num; i++) {
		client_socket[i] = socket(PF_INET, SOCK_SEQPACKET,
					IPPROTO_SCTP);
		if (client_socket[i] < 0 ){
			printf("Socket Failure: %s.\n", strerror(errno));
			DUMP_CORE;
		}

		if (local_port) {
			error = bind(client_socket[i], &client_loop.sa,
				sizeof(client_loop));
			if (error < 0) {
				printf("Bind Failure: %s\n", strerror(errno));
				DUMP_CORE;
			}
		}

		printf("Create Socket #: %d\n", client_socket[i]);

		/* Connect to server and send initial message */
		error = connect(client_socket[i], &server_loop.sa,
						    sizeof(server_loop));
		if (error < 0){
			printf("Connect Failure: %s.\n", strerror(errno));
			DUMP_CORE;
		}

		max_socket = client_socket[i];

                ppid++;

		/* Send initial message */
		error = sctp_sendmsg(client_socket[i],
				message,
				strlen(message) + 1,
				(struct sockaddr *)&server_loop,
				sizeof(server_loop),
				ppid,
				0,
				stream,
				0, 0);
		if (error < 0 ) {
			printf("Send Failure: %s.\n", strerror(errno));
			DUMP_CORE;
		}
	}

	while (TRUE){

		/* Clear the set for select() */
		FD_ZERO(&rfds);

		/* Set time out values for select() */
		tv.tv_sec = 5;
		tv.tv_usec = 0;

		/* Add the sockets select() will examine */
		for (i = 0; i < assoc_num; i++) {
			FD_SET(client_socket[i], &rfds);
		}

		/* Wait until there is data to be read from one of the
		 * sockets, or until the timer expires
		 */
		error = select(max_socket + 1, &rfds, NULL, NULL, &tv);

		if (error < 0) {
			printf("Select Failure: %s.\n", strerror(errno));
			DUMP_CORE;
		} else if (error) {
			/* Loop through the array of sockets to find the ones
			 *that have information to be read
			 */
			process_ready_sockets(client_socket, assoc_num, &rfds);
		}
	}
}
Example #20
0
int main()
{
  int listenSock, connSock, ret, in , flags, i;
  struct sockaddr_in servaddr;
  struct sctp_initmsg initmsg;
  struct sctp_event_subscribe events;
  struct sctp_sndrcvinfo sndrcvinfo;
  //char buffer[MAX_BUFFER+1];

  listenSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP );

  bzero( (void *)&servaddr, sizeof(servaddr) );
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
  servaddr.sin_port = htons(MY_PORT_NUM);

  ret = bind( listenSock, (struct sockaddr *)&servaddr, sizeof(servaddr) );

  /* Specify that a maximum of 5 streams will be available per socket */
  memset( &initmsg, 0, sizeof(initmsg) );
  initmsg.sinit_num_ostreams = 5;
  initmsg.sinit_max_instreams = 5;
  initmsg.sinit_max_attempts = 4;
  ret = setsockopt( listenSock, IPPROTO_SCTP, SCTP_INITMSG, 
                     &initmsg, sizeof(initmsg) );

  listen( listenSock, 5 );

  while( 1 ) {

    char buffer[MAX_BUFFER + 1];
    int len ;  
    printf("Awaiting a new connection\n");

    connSock = accept( listenSock, (struct sockaddr *)NULL, NULL );
    if(connSock == -1)
      die("accept()");
    else 
      printf("New client connected....\n");

    in = sctp_recvmsg( connSock, (void *)buffer, sizeof(buffer),
                      (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags );
    printf("%d\n", in);
    if (in <= 0) break;

    for (int i = 0; i < in; i++) {
      printf("%c", buffer[i]);
    }
    printf("\n");

    char * out = new char[MAX_BUFFER + 1];
    reverse_each(buffer, in, out);
    printf("%s\n", out);
    ret = sctp_sendmsg( connSock, (void *)out, (size_t)in, NULL, 0, 0, 0, 0, 0, 0 );
    // printf("ret = %d\n", ret);
    delete(out);

    memset(buffer, '\0', sizeof(buffer));
    close( connSock );
  }

  return 0;
}
Example #21
0
int main(int argc, char **argv)
{
	int opt, sock, newsock, result, flags, if_index = 0, on = 1;
	socklen_t sinlen, opt_len;
	struct sockaddr_storage sin;
	struct addrinfo hints, *res;
	struct sctp_sndrcvinfo sinfo;
	struct pollfd poll_fd;
	char getsockopt_peerlabel[1024];
	char byte, *peerlabel, msglabel[1024], if_name[30];
	bool nopeer = false,  verbose = false,  ipv4 = false, snd_opt = false;
	char *context, *host_addr = NULL, *bindx_addr = NULL;
	struct sockaddr_in ipv4_addr;
	unsigned short port;

	while ((opt = getopt(argc, argv, "4b:h:inv")) != -1) {
		switch (opt) {
		case '4':
			ipv4 = true;
			break;
		case 'b':
			bindx_addr = optarg;
			break;
		case 'h':
			host_addr = optarg;
			break;
		case 'i':
			snd_opt = true;
			break;
		case 'n':
			nopeer = true;
			break;
		case 'v':
			verbose = true;
			break;
		default:
			usage(argv[0]);
		}
	}

	if ((argc - optind) != 2)
		usage(argv[0]);

	port = atoi(argv[optind + 1]);
	if (!port)
		usage(argv[0]);

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_flags = AI_PASSIVE;
	hints.ai_protocol = IPPROTO_SCTP;

	if (ipv4)
		hints.ai_family = AF_INET;
	else
		hints.ai_family = AF_INET6;

	if (!strcmp(argv[optind], "stream"))
		hints.ai_socktype = SOCK_STREAM;
	else if (!strcmp(argv[optind], "seq"))
		hints.ai_socktype = SOCK_SEQPACKET;
	else
		usage(argv[0]);

	if (verbose) {
		if (getcon(&context) < 0)
			context = strdup("unavailable");
		printf("Server process context: %s\n", context);
		free(context);
	}

	if (host_addr) {
		char *ptr;

		ptr = strpbrk(host_addr, "%");
		if (ptr)
			strcpy(if_name, ptr + 1);

		if_index = if_nametoindex(if_name);
		if (!if_index) {
			perror("Server if_nametoindex");
			exit(1);
		}

		result = getaddrinfo(host_addr, argv[optind + 1],
				     &hints, &res);

	} else {
		result = getaddrinfo(NULL, argv[optind + 1], &hints, &res);
	}

	if (result < 0) {
		fprintf(stderr, "Server getaddrinfo: %s\n",
			gai_strerror(result));
		exit(1);
	}

	sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
	if (sock < 0) {
		perror("Server socket");
		exit(1);
	}

	result = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	if (result < 0) {
		perror("Server setsockopt: SO_REUSEADDR");
		close(sock);
		exit(1);
	}

	/* Enables sctp_data_io_events for sctp_recvmsg(3) for assoc_id. */
	result = setsockopt(sock, SOL_SCTP, SCTP_EVENTS, &on, sizeof(on));
	if (result < 0) {
		perror("Server setsockopt: SCTP_EVENTS");
		close(sock);
		exit(1);
	}

	if (bindx_addr) {
		memset(&ipv4_addr, 0, sizeof(struct sockaddr_in));
		ipv4_addr.sin_family = AF_INET;
		ipv4_addr.sin_port = htons(port);
		ipv4_addr.sin_addr.s_addr = inet_addr(bindx_addr);

		result = sctp_bindx(sock, (struct sockaddr *)&ipv4_addr, 1,
				    SCTP_BINDX_ADD_ADDR);
		if (result < 0) {
			perror("Server sctp_bindx ADD - ipv4");
			close(sock);
			exit(1);
		}
	} else {
		result = bind(sock, res->ai_addr, res->ai_addrlen);
		if (result < 0) {
			perror("Server bind");
			close(sock);
			exit(1);
		}
	}

	if (verbose) {
		print_context(sock, "Server LISTEN");
		print_ip_option(sock, ipv4, "Server LISTEN");
	}

	if (listen(sock, SOMAXCONN)) {
		perror("Server listen");
		close(sock);
		exit(1);
	}

	if (hints.ai_socktype == SOCK_STREAM) {
		if (verbose)
			print_context(sock, "Server STREAM");

		do {
			socklen_t labellen = sizeof(getsockopt_peerlabel);

			sinlen = sizeof(sin);

			newsock = accept(sock, (struct sockaddr *)&sin,
					 &sinlen);
			if (newsock < 0) {
				perror("Server accept");
				close(sock);
				exit(1);
			}

			if (verbose) {
				print_context(newsock,
					      "Server STREAM accept on newsock");
				print_addr_info((struct sockaddr *)&sin,
						"Server connected to Client");
				print_ip_option(newsock, ipv4,
						"Server STREAM accept on newsock");
			}

			if (nopeer) {
				peerlabel = strdup("nopeer");
			} else if (snd_opt) {
				peerlabel = get_ip_option(newsock, ipv4,
							  &opt_len);
				if (!peerlabel)
					peerlabel = strdup("no_ip_options");
			} else {
				result = getpeercon(newsock, &peerlabel);
				if (result < 0) {
					perror("Server getpeercon");
					close(sock);
					close(newsock);
					exit(1);
				}

				/* Also test the getsockopt version */
				result = getsockopt(newsock, SOL_SOCKET,
						    SO_PEERSEC,
						    getsockopt_peerlabel,
						    &labellen);
				if (result < 0) {
					perror("Server getsockopt: SO_PEERSEC");
					close(sock);
					close(newsock);
					exit(1);
				}
				if (verbose)
					printf("Server STREAM SO_PEERSEC peer label: %s\n",
					       getsockopt_peerlabel);
			}
			printf("Server STREAM %s: %s\n",
			       snd_opt ? "sock_opt" : "peer label", peerlabel);

			result = read(newsock, &byte, 1);
			if (result < 0) {
				perror("Server read");
				close(sock);
				close(newsock);
				exit(1);
			}

			result = write(newsock, peerlabel, strlen(peerlabel));
			if (result < 0) {
				perror("Server write");
				close(sock);
				close(newsock);
				exit(1);
			}

			if (verbose)
				printf("Server STREAM sent: %s\n", peerlabel);

			free(peerlabel);

			/* Let the client close the connection first as this
			 * will stop OOTB chunks if newsock closed early.
			 */
			poll_fd.fd = newsock;
			poll_fd.events = POLLRDHUP;
			poll_fd.revents = 1;
			result = poll(&poll_fd, 1, 1000);
			if (verbose && result == 1)
				printf("Server STREAM: Client closed connection\n");
			else if (verbose && result == 0)
				printf("Server: poll(2) timed out - OKAY\n");
			else if (result < 0)
				perror("Server - poll");

			close(newsock);
		} while (1);
	} else { /* hints.ai_socktype == SOCK_SEQPACKET */
		if (verbose)
			print_context(sock, "Server SEQPACKET sock");

		do {
			sinlen = sizeof(sin);

			result = sctp_recvmsg(sock, msglabel, sizeof(msglabel),
					      (struct sockaddr *)&sin, &sinlen,
					      &sinfo, &flags);
			if (result < 0) {
				perror("Server sctp_recvmsg");
				close(sock);
				exit(1);
			}

			if (verbose) {
				print_context(sock, "Server SEQPACKET recvmsg");
				print_addr_info((struct sockaddr *)&sin,
						"Server SEQPACKET recvmsg");
				print_ip_option(sock, ipv4,
						"Server SEQPACKET recvmsg");
			}

			if (nopeer) {
				peerlabel = strdup("nopeer");
			} else if (snd_opt) {
				peerlabel = get_ip_option(sock, ipv4, &opt_len);

				if (!peerlabel)
					peerlabel = strdup("no_ip_options");
			} else {
				result = getpeercon(sock, &peerlabel);
				if (result < 0) {
					perror("Server getpeercon");
					close(sock);
					exit(1);
				}
			}
			printf("Server SEQPACKET %s: %s\n",
			       snd_opt ? "sock_opt" : "peer label", peerlabel);

			if (sin.ss_family == AF_INET6 && host_addr)
				((struct sockaddr_in6 *)&sin)->sin6_scope_id = if_index;

			result = sctp_sendmsg(sock, peerlabel,
					      strlen(peerlabel),
					      (struct sockaddr *)&sin,
					      sinlen, 0, 0, 0, 0, 0);
			if (result < 0) {
				perror("Server sctp_sendmsg");
				close(sock);
				exit(1);
			}

			if (verbose)
				printf("Server SEQPACKET sent: %s\n",
				       peerlabel);

			free(peerlabel);
		} while (1);
	}

	close(sock);
	exit(0);
}
Example #22
0
int main(int argc,char **argv)
{
	int echo_to_all = 0;

	int ret_value;
	int sock_fd;
	int msg_flags;	// 記錄要傳送訊息時的相關設定
	char readbuf[BUFFERSIZE];
	struct sockaddr_in servaddr,cliaddr;
	struct sctp_sndrcvinfo sri;	// 記錄send, recv, association的相關資訊
	struct sctp_event_subscribe evnts;
	int stream_increment = 1;
	socklen_t len;
	size_t rd_sz;	// size_t指的就是unsigned long:rd_sz表示recv,send-size
	struct sockaddr *addrs;
	int addrcnt;
	int temp_step;

	if (argc == 2) {
		// 把字串轉換成數字
		stream_increment = atoi(argv[1]);
	}

	// 建立socket的型態為SCTP的one-to-many的型態
	sock_fd = socket(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP);
	if (sock_fd == -1) {
		printf("socket error\n");
		exit(-1);
	}
	// 初始化server address的設定
	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(SERV_PORT);
	
	// 把socket與所建立的address綁在一起
	ret_value = bind(sock_fd,(struct sockaddr *) &servaddr,sizeof(servaddr));
	if (ret_value == -1) {
		printf("bind error\n");
		exit(-1);
	}

	// Set up for notifications of internet
	bzero(&evnts,sizeof(evnts));
	evnts.sctp_data_io_event = 1;	// 使得sctp_sndrcvinfo可以伴隨資料傳送過來
	ret_value = setsockopt(sock_fd,IPPROTO_SCTP,SCTP_EVENTS,&evnts,sizeof(evnts));
	if (ret_value == -1) {
		printf("setsockopt error\n");
		exit(-1);
	}

	// 設定等待多少個client端連線
	ret_value = listen(sock_fd,LISTENQ);
	if (ret_value == -1) {
		printf("listen error\n");
		exit(-1);
	}
	printf("start wait...\n");

	for (;;) {
		len = sizeof(struct sockaddr_in);
		// 等待client端連線
		rd_sz = sctp_recvmsg(sock_fd,readbuf,sizeof(readbuf),(struct sockaddr *) &cliaddr,&len,&sri,&msg_flags);

		// 分別印出local與peer端的address - start
		if ((addrcnt = sctp_getladdrs(sock_fd,sri.sinfo_assoc_id,&addrs))==-1) {
			printf("sctp_getladdrs error\n");
			exit(-1);
		}
		printf("the local has %d address(es)\n",addrcnt);
		for (temp_step=0;temp_step<addrcnt;temp_step++) {
			printf("the address is %s\n",inet_ntoa(((struct sockaddr_in *) addrs+temp_step)->sin_addr));
		}
		sctp_freeladdrs(addrs);
		if ((addrcnt = sctp_getpaddrs(sock_fd,sri.sinfo_assoc_id,&addrs))==-1) {
			printf("sctp_getpaddrs error\n");
			exit(-1);
		}
		printf("the peer has %d address(es)\n",addrcnt);
		for (temp_step=0;temp_step<addrcnt;temp_step++) {
			printf("the address is %s\n",inet_ntoa(((struct sockaddr_in *) addrs+temp_step)->sin_addr));
		}
		sctp_freepaddrs(addrs);
		// 分別印出local與peer端的address - start

		if (stream_increment) {
			sri.sinfo_stream++;
			if (sri.sinfo_stream >= 100) {
				sri.sinfo_stream = 0;
			}
		}
		// 把接收到的資料回送給client
		ret_value = sctp_sendmsg(sock_fd,readbuf,rd_sz,(struct sockaddr *) &cliaddr,len,sri.sinfo_ppid,sri.sinfo_flags,sri.sinfo_stream,0,0);
		if (ret_value == -1) {
			printf("sctp_sendmsg error\n");
			exit(-1);
		}
	}
	return 0;
}
Example #23
0
File: tsctp.c Project: dreibh/tsctp
int main(int argc, char **argv)
{
	int fd, *cfdptr, c;
	size_t intlen;
	char *buffer;
	socklen_t addr_len;
	union sock_union{
		struct sockaddr sa;
		struct sockaddr_in s4;
		struct sockaddr_in6 s6;
	} remote_addr;
	struct sockaddr_storage local_addr[MAX_LOCAL_ADDR];
	char *local_addr_ptr = (char*) local_addr;
	unsigned int nr_local_addr = 0;
	struct timeval start_time, now, diff_time;
	int length, client;
	uint16_t local_port, remote_port, port;
#ifdef SCTP_REMOTE_UDP_ENCAPS_PORT
	uint16_t udp_port = 0;
	struct sctp_udpencaps encaps;
#endif
	double seconds;
	double throughput;
	const int on = 1;
	const int off = 0;
	int nodelay = 0;
	unsigned long i, number_of_messages;
	pthread_t tid;
	int rcvbufsize=0, sndbufsize=0, myrcvbufsize, mysndbufsize;
	struct linger linger;
	int fragpoint = 0;
	unsigned int timetolive = 0;
	unsigned int runtime = 0;
	struct sctp_setadaptation ind = {0};
#ifdef SCTP_AUTH_CHUNK
	unsigned int number_of_chunks_to_auth = 0;
	unsigned int chunk_number;
	unsigned char chunk[256];
	struct sctp_authchunk sac;
#endif
	struct sctp_assoc_value av;
	int unordered = 0;
	int ipv4only = 0;
	int ipv6only = 0;

	length             = DEFAULT_LENGTH;
	number_of_messages = DEFAULT_NUMBER_OF_MESSAGES;
	port               = DEFAULT_PORT;
	verbose            = 0;
	very_verbose       = 0;

	memset((void *) &remote_addr, 0, sizeof(remote_addr));

	while ((c = getopt(argc, argv, "a:"
#ifdef SCTP_AUTH_CHUNK
	                               "A:"
#endif
	                               "Df:l:L:n:p:R:S:t:T:u"
#ifdef SCTP_REMOTE_UDP_ENCAPS_PORT 
                                   "U:"
#endif
                                   "vV46")) != -1)
		switch(c) {
			case 'a':
				ind.ssb_adaptation_ind = atoi(optarg);
				break;
#ifdef SCTP_AUTH_CHUNK
			case 'A':
				if (number_of_chunks_to_auth < 256) {
					chunk[number_of_chunks_to_auth++] = (unsigned char)atoi(optarg);
				}
				break;
#endif
			case 'D':
				nodelay = 1;
				break;
			case 'f':
				fragpoint = atoi(optarg);
				break;
			case 'l':
				length = atoi(optarg);
				break;
			case 'L':
				if (nr_local_addr < MAX_LOCAL_ADDR) {
					struct sockaddr_in *s4 = (struct sockaddr_in*) local_addr_ptr;
					struct sockaddr_in6 *s6 = (struct sockaddr_in6*) local_addr_ptr;

					if (inet_pton(AF_INET6, optarg, &s6->sin6_addr)) {
						s6->sin6_family = AF_INET6;
#ifdef HAVE_SIN_LEN
						s6->sin6_len = sizeof(struct sockaddr_in6);
#endif
						local_addr_ptr += sizeof(struct sockaddr_in6);
						nr_local_addr++;
					} else {
						if (inet_pton(AF_INET, optarg, &s4->sin_addr)) {
							s4->sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
							s4->sin_len = sizeof(struct sockaddr_in);
#endif
							local_addr_ptr += sizeof(struct sockaddr_in);
							nr_local_addr++;
						} else {
							printf("Invalid address\n");
							fprintf(stderr, "%s", Usage);
							exit(1);
						}
					}
				}
				break;
			case 'n':
				number_of_messages = atoi(optarg);
				break;
			case 'p':
				port = atoi(optarg);
				break;
			case 'R':
				rcvbufsize = atoi(optarg);
				break;
			case 'S':
				sndbufsize = atoi(optarg);
				break;
			case 't':
				timetolive = atoi(optarg);
				break;
			case 'T':
				runtime = atoi(optarg);
				number_of_messages = 0;
				break;
			case 'u':
				unordered = 1;
				break;
#ifdef SCTP_REMOTE_UDP_ENCAPS_PORT
			case 'U':
				udp_port = atoi(optarg);
				break;
#endif
			case 'v':
				verbose = 1;
				break;
			case 'V':
				verbose = 1;
				very_verbose = 1;
				break;
			case '4':
				ipv4only = 1;
				if (ipv6only) {
					printf("IPv6 only already\n");
					exit(1);
				}
				break;
			case '6':
				ipv6only = 1;
				if (ipv4only) {
					printf("IPv4 only already\n");
					exit(1);
				}
				break;
			default:
				fprintf(stderr, "%s", Usage);
				exit(1);
		}

	if (optind == argc) {
		client      = 0;
		local_port  = port;
		remote_port = 0;
	} else {
		client      = 1;
		local_port  = 0;
		remote_port = port;
	}

	if (nr_local_addr == 0) {
		memset((void *) local_addr, 0, sizeof(local_addr));
		if (ipv4only) {
			struct sockaddr_in *s4 = (struct sockaddr_in*) local_addr;
			s4->sin_family      = AF_INET;
#ifdef HAVE_SIN_LEN
			s4->sin_len         = sizeof(struct sockaddr_in);
#endif
			s4->sin_addr.s_addr = htonl(INADDR_ANY);
		} else {
			struct sockaddr_in6 *s6 = (struct sockaddr_in6*) local_addr;
			s6->sin6_family      = AF_INET6;
#ifdef HAVE_SIN_LEN
			s6->sin6_len         = sizeof(struct sockaddr_in6);
#endif
			s6->sin6_addr = in6addr_any;
		}
		nr_local_addr = 1;
	}

	local_addr_ptr = (char*) local_addr;
	for (i = 0; i < nr_local_addr; i++) {
		struct sockaddr_in *s4 = (struct sockaddr_in*) local_addr_ptr;
		struct sockaddr_in6 *s6 = (struct sockaddr_in6*) local_addr_ptr;

		if (s4->sin_family == AF_INET) {
			s4->sin_port = htons(local_port);
			local_addr_ptr += sizeof(struct sockaddr_in);
			if (ipv6only) {
				printf("Can't use IPv4 address when IPv6 only\n");
				exit(1);
			}
		} else if (s6->sin6_family == AF_INET6) {
			s6->sin6_port = htons(local_port);
			local_addr_ptr += sizeof(struct sockaddr_in6);
			if (ipv4only) {
				printf("Can't use IPv6 address when IPv4 only\n");
				exit(1);
			}
		}
	}

	if ((fd = socket((ipv4only ? AF_INET : AF_INET6), SOCK_STREAM, IPPROTO_SCTP)) < 0)
		perror("socket");

	if (!ipv4only) {
		if (ipv6only) {
			if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const void*)&on, (socklen_t)sizeof(on)) < 0)
				perror("ipv6only");
		} else {
			if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const void*)&off, (socklen_t)sizeof(off)) < 0)
				perror("ipv6only");
		}
	}

#ifdef SCTP_AUTH_CHUNK
	for (chunk_number = 0; chunk_number < number_of_chunks_to_auth; chunk_number++) {
		sac.sauth_chunk = chunk[chunk_number];
		if (setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &sac, (socklen_t)sizeof(struct sctp_authchunk)) < 0)
			perror("setsockopt");
	}
#endif
	if (ind.ssb_adaptation_ind > 0) {
		if (setsockopt(fd, IPPROTO_SCTP, SCTP_ADAPTATION_LAYER, (const void*)&ind, (socklen_t)sizeof(struct sctp_setadaptation)) < 0) {
			perror("setsockopt");
		}
	}
	if (!client) {
		setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*)&on, (socklen_t)sizeof(on));
	}
#ifdef SCTP_REMOTE_UDP_ENCAPS_PORT
	memset(&encaps, 0, sizeof(struct sctp_udpencaps));
	encaps.sue_address.ss_family = (ipv4only ? AF_INET : AF_INET6);
	encaps.sue_port = htons(udp_port);
	if (setsockopt(fd, IPPROTO_SCTP, SCTP_REMOTE_UDP_ENCAPS_PORT, (const void*)&encaps, (socklen_t)sizeof(struct sctp_udpencaps)) < 0) {
		perror("setsockopt");
	}
#endif
	if (nr_local_addr > 0) {
		if (sctp_bindx(fd, (struct sockaddr *)local_addr, nr_local_addr, SCTP_BINDX_ADD_ADDR) != 0)
			perror("bind");
	}

	if (!client) {
		struct sctp_event_subscribe event;

		if (listen(fd, 100) < 0)
			perror("listen");
		if (rcvbufsize)
			if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbufsize, sizeof(int)) < 0)
				perror("setsockopt: rcvbuf");
		if (verbose) {
			intlen = sizeof(int);
			if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &myrcvbufsize, (socklen_t *)&intlen) < 0) {
				perror("setsockopt: rcvbuf");
			} else {
				fprintf(stdout,"Receive buffer size: %d.\n", myrcvbufsize);
			}
		}
		memset(&event, 0, sizeof(event));
		event.sctp_data_io_event=1;
		if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)) != 0) {
			perror("set event failed");
		}

		while (1) {
			memset(&remote_addr, 0, sizeof(remote_addr));

			if (ipv4only) {
				addr_len = sizeof(struct sockaddr_in);
			} else {
				addr_len = sizeof(struct sockaddr_in6);
			}

			cfdptr = malloc(sizeof(int));
			if ((*cfdptr = accept(fd, (struct sockaddr *)&remote_addr, &addr_len)) < 0) {
				perror("accept");
				continue;
			}
			if (verbose) {
				char temp[INET6_ADDRSTRLEN];

				if (remote_addr.sa.sa_family == AF_INET) {
					fprintf(stdout,"Connection accepted from %s:%d\n", inet_ntop(AF_INET, &remote_addr.s4.sin_addr, temp, INET_ADDRSTRLEN), ntohs(remote_addr.s4.sin_port));
				} else {
					fprintf(stdout,"Connection accepted from %s:%d\n", inet_ntop(AF_INET6, &remote_addr.s6.sin6_addr, temp, INET6_ADDRSTRLEN), ntohs(remote_addr.s6.sin6_port));
				}
			}
			pthread_create(&tid, NULL, &handle_connection, (void *) cfdptr);
		}
		close(fd);
	} else {
		if (inet_pton(AF_INET6, argv[optind], &remote_addr.s6.sin6_addr)) {
			remote_addr.s6.sin6_family = AF_INET6;
#ifdef HAVE_SIN_LEN
			remote_addr.s6.sin6_len = sizeof(struct sockaddr_in6);
#endif
			remote_addr.s6.sin6_port = htons(remote_port);
			addr_len = sizeof(struct sockaddr_in6);

			if (ipv4only) {
				printf("Can't use IPv6 address when IPv4 only\n");
				exit(1);
			}
		} else {
			if (inet_pton(AF_INET, argv[optind], &remote_addr.s4.sin_addr))
			{
				remote_addr.s4.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
				remote_addr.s4.sin_len = sizeof(struct sockaddr_in);
#endif
				remote_addr.s4.sin_port = htons(remote_port);
				addr_len = sizeof(struct sockaddr_in);

				if (ipv6only) {
					printf("Can't use IPv4 address when IPv6 only\n");
					exit(1);
				}
			} else {
				printf("Invalid address\n");
				fprintf(stderr, "%s", Usage);
				exit(1);
			}
		}

		if (fragpoint) {
			av.assoc_id = 0;
			av.assoc_value = fragpoint;
			if (setsockopt(fd, IPPROTO_SCTP, SCTP_MAXSEG, &av, sizeof(av)) < 0) {
				perror("setsockopt: SCTP_MAXSEG");
			}
		}

		if (connect(fd, (struct sockaddr *)&remote_addr, addr_len) < 0) {
			perror("connect");
		}

#ifdef SCTP_NODELAY
		/* Explicit settings, because LKSCTP does not enable it by default */
		if (nodelay == 1) {
			if (setsockopt(fd, IPPROTO_SCTP, SCTP_NODELAY, (char *)&on, sizeof(on)) < 0) {
				perror("setsockopt: nodelay");
			}
		} else {
			if (setsockopt(fd, IPPROTO_SCTP, SCTP_NODELAY, (char *)&off, sizeof(off)) < 0) {
				perror("setsockopt: nodelay");
			}
		}
#endif
		if (sndbufsize)
			if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbufsize, sizeof(int)) < 0) {
				perror("setsockopt: sndbuf");
			}

		if (verbose) {
			intlen = sizeof(int);
			if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &mysndbufsize, (socklen_t *)&intlen) < 0) {
				perror("setsockopt: sndbuf");
			} else {
				fprintf(stdout,"Send buffer size: %d.\n", mysndbufsize);
			}
		}
		buffer = malloc(length);
		memset(buffer, 'A', length);

		gettimeofday(&start_time, NULL);
		if (verbose) {
			printf("Start sending %ld messages...", (long)number_of_messages);
			fflush(stdout);
		}

		i = 0;
		done = 0;

		if (runtime > 0) {
			signal(SIGALRM, stop_sender);
			alarm(runtime);
		}

		while (!done && ((number_of_messages == 0) || (i < (number_of_messages - 1)))) {
			if (very_verbose) {
				printf("Sending message number %lu.\n", i);
			}
			if (sctp_sendmsg(fd, buffer, length, NULL, 0, 0, unordered?SCTP_UNORDERED:0, 0, timetolive, 0) < 0) {
				perror("sctp_sendmsg");
				break;
			}
			i++;
		}
		if (sctp_sendmsg(fd, buffer, length, NULL, 0, 0, unordered?SCTP_EOF|SCTP_UNORDERED:SCTP_EOF, 0, timetolive, 0) < 0) {
			perror("sctp_sendmsg");
		}
		i++;
		if (verbose)
			printf("done.\n");
		linger.l_onoff = 1;
		linger.l_linger = LINGERTIME;
		if (setsockopt(fd, SOL_SOCKET, SO_LINGER,(char*)&linger, sizeof(struct linger)) < 0) {
			perror("setsockopt");
		}
		close(fd);
		gettimeofday(&now, NULL);
		timersub(&now, &start_time, &diff_time);
		seconds = diff_time.tv_sec + (double)diff_time.tv_usec/1000000;
		fprintf(stdout, "%s of %ld messages of length %u took %f seconds.\n",
		       "Sending", i, length, seconds);
		throughput = (double)i * (double)length / seconds;
		fprintf(stdout, "Throughput was %f Byte/sec.\n", throughput);
	}
	return 0;
}
void *
pe_thread(void *thrid) {
    int tid;
    tid = (int)thrid;
    int listenSock, connSock, ret;
    struct sockaddr_in servaddr;
    struct sockaddr_in fromaddr;
    socklen_t socklen;
    struct sctp_initmsg initmsg;
    char buffer[MAX_BUFFER];
    char rcvbuf[MAX_BUFFER];

    printf("\t\t\tHello World! It's me, thread #%d!\n", tid);

    bzero((void *)rcvbuf, MAX_BUFFER);
    socklen = sizeof(struct sockaddr_in);
    /* Create SCTP TCP-Style Socket */
    listenSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP );

    /* Accept connections from any interface */
    bzero( (void *)&servaddr, sizeof(servaddr) );
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
    servaddr.sin_port = htons(MY_PORT_NUM);

    ret = bind( listenSock, (struct sockaddr *)&servaddr, sizeof(servaddr) );

    printf("Listening on port: 0x%x\n", servaddr.sin_port);
    /* Specify that a maximum of 5 streams will be available per socket */
    memset( &initmsg, 0, sizeof(initmsg) );
    initmsg.sinit_num_ostreams = 5;
    initmsg.sinit_max_instreams = 5;
    initmsg.sinit_max_attempts = 4;
    ret = setsockopt( listenSock, IPPROTO_SCTP, SCTP_INITMSG,
                       &initmsg, sizeof(initmsg) );

    /* Place the server socket into the listening state */
    listen( listenSock, 5 );

    /* Server loop... */
    while( 1 ) {

        /* Await a new client connection */
        printf("Awaiting a new connection\n");
        connSock = accept(listenSock, (struct sockaddr *)NULL, (socklen_t *)NULL);
        printf("Client Connected \n");
        /* New client socket has connected */

        ret = sctp_recvmsg(connSock, rcvbuf, MAX_BUFFER,
                           (struct sockaddr *)&fromaddr, &socklen,
                           NULL, 0);
        if (ret < 0) {
            perror("Error getting data");
            exit(1);
        }
        rcvbuf[ret] = '\0';
        printf("Got [%s]\n", rcvbuf);

        /* Send local time on stream 0 (local time stream) */
        snprintf(buffer, MAX_BUFFER, "I got [%s] from you", rcvbuf);
        printf("Sending [%s]\n",buffer);
        ret = sctp_sendmsg(connSock, (void *)buffer, (size_t)strlen(buffer),
                           NULL, 0, 0, 0, LOCALTIME_STREAM, 0, 0 );
        if (ret < 0) {
            perror("Error sending msg");
            exit(1);
        }

        /* Close the client connection */
        sleep(10);
        close( connSock );
    }
    pthread_exit(NULL);
}
Example #25
0
int run_test_client(int argc, char* argv[])
{
	int sctp_sock = -1, gai_stat = 0;		// socket
	struct sockaddr_storage server_addr;		// server address structure
	struct sockaddr_storage peer_addr;		// peer address structure
	
	// Lengths for address structures
	socklen_t server_addr_len = 0;
	socklen_t peer_addr_len = 0;
	
	struct sctp_event_subscribe sctp_events;	// sctp events
	struct sctp_sndrcvinfo infodata;		// sctp sender info
	struct addrinfo hints,*ai = NULL,*iter = NULL;	// for getaddrinfo
	
	// invalid amount of parameters
	if(argc != 3) return testclient_input_error((argc == 1) ? argv[0] : NULL);
	
	// Use stroull for larger numbers, atoi() can be used for short ints
	unsigned int port = strtoull(argv[2],NULL,10);
	
	printf("connecting to: %s %u\n",argv[1],port);
		
	memset(&server_addr,0,sizeof(struct sockaddr_storage));
	
	// Get the server address structure with getaddrinfo()
	memset(&hints,0,sizeof(hints));
	hints.ai_family = PF_UNSPEC; 			// To allow IPv4 or IPv6
	hints.ai_protocol = IPPROTO_SCTP;		// SCTP protocol supported
	hints.ai_socktype = SOCK_SEQPACKET;
	
	// Get (and set) server info
	if((gai_stat = getaddrinfo(argv[1],argv[2],&hints,&ai)) < 0) {
		fprintf(stderr, "Cannot resolve: ");
 		print_addr_type(argv[1]);
		fprintf(stderr, "Error: %s\n",gai_strerror(gai_stat));
		if(ai) freeaddrinfo(ai);
		return -1;
	}
	
	// Use the first of the returned addresses
	for(iter = ai; iter != NULL; iter = iter->ai_next) {
	
	  // To allow the usage of both use IPv6 type for socket, create socket for SCTP
	  if((sctp_sock = socket(iter->ai_family, iter->ai_socktype, iter->ai_protocol)) < 0) {
	  	perror("socket()");
	  	if(ai) freeaddrinfo(ai);
	  	return -1;
	  }
	
	// Note that we do not need connect() with SCTP
#ifdef USE_CONNECT
#if USE_CONNECT == 1
	  if(connect(sctp_sock,(SA*)&server_addr,server_addr_len) < 0 ) perror("connect");
	  else printf("connected\n");
#endif
#endif

	memcpy(&server_addr,iter->ai_addr,iter->ai_addrlen);
	server_addr_len = iter->ai_addrlen;
	break;
	}
	freeaddrinfo(ai); // No need for this anymore
  
	// Allow to receive events from SCTP stack
	memset(&sctp_events,0,sizeof(sctp_events));
	set_sctp_events(&sctp_events);
	if(setsockopt(sctp_sock, IPPROTO_SCTP, SCTP_EVENTS, &sctp_events, sizeof(sctp_events)) < 0) perror("setsockopt");

	int byte_count = 513;
	char* data_to_send = testclient_fill_random_data(byte_count);	// create some data to send
	
	int sent_bytes = sctp_sendmsg(sctp_sock, 		// socket file descriptor
					data_to_send, 		// Data to send
					byte_count,     	// Amount of data to send in bytes
					(SA*)&server_addr,	// address of receiver
					server_addr_len,	// length of address structure
					666,			// Protocol payload identifier
					0,			// flags
					2,			// stream id
					0, 			// time to live, 0 = infinite
					0);
											
	printf("Sent %d bytes\n", sent_bytes);
	
	int recv_flags = 0;	
	int read_bytes = 0;
	
	/* Read until something is received from peer (server) just for demonstrative purposes
	   Use select() in your code
	*/
	while(1)
	{
		memset(data_to_send,0,byte_count);	// clear the buffer so new data can be written to it
		memset(&infodata,0,sizeof(infodata));
		recv_flags = 0;
		memset(&peer_addr,0,sizeof(peer_addr));
		
		read_bytes = sctp_recvmsg(sctp_sock,
						data_to_send,
						byte_count,
						(SA*)&peer_addr,
						&peer_addr_len,
						&infodata,
						&recv_flags);
		if(read_bytes > 0)
		{
			// Is a SCTP notification
			if(recv_flags & MSG_NOTIFICATION)
			{
				printf("Got notification: ");
				check_sctp_event(data_to_send,read_bytes);
				printf("\n");
			}
			// Otherwise data is received from peer
			else
			{
				printf("Got %d bytes on stream %d\n", read_bytes,infodata.sinfo_stream);
				break; // Got data, expecting 1 packet (ignore further notifications) -> break
			}
		}
		else break;
	}
	
	free(data_to_send);
	
	sleep(5);
	
	data_to_send = testclient_fill_random_data(byte_count);
	
	// We can send data also with sendto() when SCTP is used !
	sent_bytes = sendto(sctp_sock, 			// socket file descriptor
				data_to_send, 		// Data to send
				byte_count,     	// Amount of data to send in bytes
				0,			// Flags
				(SA*)&server_addr,	// address of receiver
				server_addr_len		// length of address structure
				);
	printf("Sent %d bytes\n", sent_bytes);
	
	
	
	while(1)
	{
		memset(&infodata,0,sizeof(infodata));
		recv_flags = 0;
		memset(&peer_addr,0,sizeof(peer_addr));
		memset(data_to_send,0,byte_count);
		
		read_bytes = sctp_recvmsg(sctp_sock,
						data_to_send,
						byte_count,
						(SA*)&peer_addr,
						&peer_addr_len,
						&infodata,
						&recv_flags);
																	
		if(read_bytes > 0)
		{
			// Is a SCTP notification
			if(recv_flags & MSG_NOTIFICATION)
			{
				printf("Got notification: ");
				check_sctp_event(data_to_send,read_bytes);
				printf("\n");
			}
			// Otherwise data is received from peer
			else
			{
				printf("Got %d bytes on stream %d\n", read_bytes,infodata.sinfo_stream);
				break; // Got data, expecting 1 packet (ignore further notifications) -> break
			}
		}
		else break;
	}
	
	free(data_to_send);
	close(sctp_sock);
	return 0;
}
int main(int argc, char** argv)
{
  struct addrinfo hints;
  struct addrinfo* addressInfo = NULL;
  int i;
  int retVal;
  int optval;
  int serverSocket;
  struct sockaddr_storage clientAddress;
  struct AddrPortStrings clientAddrPortStrings;
  struct sctp_event_subscribe events;
  char buffer[2000];
  struct sctp_sndrcvinfo sndrcvinfo;
  int flags;
  socklen_t clientAddressSize;

  if (argc != 3)
  {
    printf("Usage: %s <address> <port>\n", argv[0]);
    return 1;
  }

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_SEQPACKET;
  hints.ai_protocol = IPPROTO_SCTP;
  hints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG);

  if (retVal = getaddrinfo(argv[1], argv[2],
                           &hints, &addressInfo) != 0)
  {
    printf("getaddrinfo failed, retVal = %d\n", retVal);
    return 1;
  }

  serverSocket = socket(addressInfo->ai_family,
                        addressInfo->ai_socktype,
                        addressInfo->ai_protocol);
  if (serverSocket < 0)
  {
    printf("error creating serverSocket, errno = %d\n", errno);
    return 1;
  }
  printf("created serverSocket %d\n", serverSocket);

  optval = 1;
  if (setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
  {
    printf("error setting SO_REUSEADDR errno = %d\n", errno);
    return 1;
  }

  retVal = bind(serverSocket,
                addressInfo->ai_addr,
                addressInfo->ai_addrlen);
  if (retVal < 0)
  {
    printf("bind failed, errno = %d\n", errno);
    return 1;
  }

  if (listen(serverSocket, SOMAXCONN) < 0)
  {
    printf("listen failed, errno = %d\n", errno);
    return 1;
  }

  memset(&events, 1, sizeof(events));
  retVal = setsockopt(serverSocket, SOL_SCTP, SCTP_EVENTS, &events, sizeof(events));
  if (retVal < 0)
  {
    printf("setsockopt(SCTP_EVENTS) error errno = %d\n", errno);
    return 1;
  }

  printLocalAddresses(serverSocket);

  while (1)
  {
    flags = 0;
    clientAddressSize = sizeof(clientAddress);
    printf("before sctp_recvmsg\n");
    retVal = sctp_recvmsg(serverSocket, buffer, 2000, 
                          (struct sockaddr*)&clientAddress, &clientAddressSize,
                          &sndrcvinfo, &flags);
    printf("sctp_recvmsg returns %d\n", retVal);
    if (retVal < 0)
    {
      printf("errno = %d\n", errno);
    }
    else if (flags & MSG_NOTIFICATION)
    {
      printf("got MSG_NOTIFICATION\n");
      printSctpNotification((union sctp_notification*)buffer);
    }
    else if (flags & MSG_EOR)
    {
      printf("got MSG_EOR\n");

      if (addressToNameAndPort(
            (struct sockaddr*)&clientAddress, clientAddressSize, &clientAddrPortStrings) < 0)
      {
        continue;
      }

      printf("received message length %d from client %s:%s\n",
             retVal,
             clientAddrPortStrings.addrString, clientAddrPortStrings.portString);

      printf("call sctp_sendmsg\n");
      retVal = sctp_sendmsg(serverSocket, buffer, retVal, 
                            (struct sockaddr*)&clientAddress, 
                            clientAddressSize, 0, 0, 0, 0, 0);
      printf("sctp_sendmsg returns %d\n", retVal);
    }
  }

  return 0;
}
Example #27
0
int main(int argc,char **argv)
{
	int echo_to_all = 0;

	int ret_value;
	int sock_fd;
	int msg_flags;	// 記錄要傳送訊息時的相關設定
	char readbuf[BUFFERSIZE];
	struct sockaddr_in servaddr,cliaddr;
	struct sctp_sndrcvinfo sri;	// 記錄send, recv, association的相關資訊
	struct sctp_event_subscribe evnts;
	int stream_increment = 1;
	socklen_t len;
	size_t rd_sz;	// size_t指的就是unsigned long
	struct sctp_initmsg initm;

	if (argc == 2) {
		// 把字串轉換成數字
		stream_increment = atoi(argv[1]);
	}

	// 建立socket的型態為SCTP的one-to-many的型態
	sock_fd = socket(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP);
	if (sock_fd == -1) {
		printf("socket error\n");
		exit(-1);
	}
	// 預設是10條stream,設定為30條
	memset(&initm,0,sizeof(initm));
	initm.sinit_num_ostreams = SERV_MORE_STRMS_SCTP;
	setsockopt(sock_fd,IPPROTO_SCTP,SCTP_INITMSG,&initm,sizeof(initm));
	// 初始化server address的設定
	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(SERV_PORT);
	
	// 把socket與所建立的address綁在一起
	ret_value = bind(sock_fd,(struct sockaddr *) &servaddr,sizeof(servaddr));
	if (ret_value == -1) {
		printf("bind error\n");
		exit(-1);
	}

	// Set up for notifications of internet
	bzero(&evnts,sizeof(evnts));
	evnts.sctp_data_io_event = 1;	// 監控sctp的data的io事件:1是打開的意思
	ret_value = setsockopt(sock_fd,IPPROTO_SCTP,SCTP_EVENTS,&evnts,sizeof(evnts));
	if (ret_value == -1) {
		printf("setsockopt error\n");
		exit(-1);
	}

	// 設定等待多少個client端連線
	ret_value = listen(sock_fd,LISTENQ);
	if (ret_value == -1) {
		printf("listen error\n");
		exit(-1);
	}

	printf("start wait...\n");
	for (;;) {
		len = sizeof(struct sockaddr_in);
		// 等待client端連線
		rd_sz = sctp_recvmsg(sock_fd,readbuf,sizeof(readbuf),(struct sockaddr *) &cliaddr,&len,&sri,&msg_flags);
		if (stream_increment) {
			sri.sinfo_stream++;
			if (sri.sinfo_stream >= 100) {
				sri.sinfo_stream = 0;
			}
		}
		// 把接收到的資料回送給client
		ret_value = sctp_sendmsg(sock_fd,readbuf,rd_sz,(struct sockaddr *) &cliaddr,len,sri.sinfo_ppid,sri.sinfo_flags,sri.sinfo_stream,0,0);
		if (ret_value == -1) {
			printf("sctp_sendmsg error\n");
			exit(-1);
		}
	}
	return 0;
}
Example #28
0
int main()
{
    int listenSock, connSock, ret;
    struct sockaddr_in servaddr;
    struct sctp_initmsg initmsg;
    char buffer[MAX_BUFFER+1];
    time_t currentTime;

    // ignore SIGPIPE
    signal(SIGPIPE, SIG_IGN);

    // Create SCTP TCP-Style Socket
    listenSock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);

    // Accept connections from any interface
    bzero((void *)&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(MY_PORT_NUM);

    ret = bind(listenSock, (struct sockaddr *)&servaddr, sizeof(servaddr));

    // Specify that a maximum of 5 streams will be available per socket
    memset(&initmsg, 0, sizeof(initmsg));
    initmsg.sinit_num_ostreams = 5;
    initmsg.sinit_max_instreams = 5;
    initmsg.sinit_max_attempts = 4;
    ret = setsockopt(listenSock, IPPROTO_SCTP, SCTP_INITMSG,
                      &initmsg, sizeof(initmsg));

    // Place the server socket into the listening state
    listen(listenSock, 5);
    printf("Listening on 0.0.0.0:%d ...\n", MY_PORT_NUM);

    while(1) {
        connSock = accept(listenSock, (struct sockaddr *)NULL, (socklen_t *)NULL);
        printf("Accepted a new connection: %d\n", connSock);

        // Grab the current time
        currentTime = time(NULL);

        // Send local time on stream LOCALTIME_STREAM
        snprintf(buffer, MAX_BUFFER, "%s", ctime(&currentTime));
        ret = sctp_sendmsg(connSock, (void *)buffer, (size_t)strlen(buffer),
                            NULL, 0, 0, 0, LOCALTIME_STREAM, 0, 0);
        if(ret == -1) {
            printf("sctp_sendmsg error: %s\n", strerror(errno));
            close(connSock);
            continue;
        }

        // Send GMT on stream GMT_STREAM
        snprintf(buffer, MAX_BUFFER, "%s", asctime(gmtime(&currentTime)));
        ret = sctp_sendmsg(connSock, (void *)buffer, (size_t)strlen(buffer),
                            NULL, 0, 0, 0, GMT_STREAM, 0, 0);
        if(ret == -1) {
            printf("sctp_sendmsg error: %s\n", strerror(errno));
            close(connSock);
            continue;
        }

        close(connSock);
    }

    return 0;
}