/*
 * Class:     net_tomp2p_sctp_core_Sctp
 * Method:    usrsctp_accept
 * Signature: (J)Z
 */
JNIEXPORT jboolean JNICALL
Java_net_tomp2p_sctp_core_Sctp_usrsctp_1accept
    (JNIEnv *env, jclass clazz, jlong ptr)
{
    SctpSocket *sctpSocket;
    struct socket* so;

    sctpSocket = (SctpSocket *) (intptr_t) ptr;
    if((so = usrsctp_accept(sctpSocket->so, NULL, NULL)))
    {
        usrsctp_close(sctpSocket->so);
        sctpSocket->so = so;
        return JNI_TRUE;
    }
    else
    {
        return JNI_FALSE;
    }
}
Example #2
0
int
main(int argc, char *argv[])
{
	struct socket *sock;
	struct sockaddr_in addr;
	socklen_t addr_len;
	char line[LINE_LENGTH + 1];
	unsigned int unordered, policy, value, id, seconds;
	unsigned int i;
	struct channel *channel;
	const int on = 1;
	struct sctp_assoc_value av;
	struct sctp_event event;
	struct sctp_udpencaps encaps;
	struct sctp_initmsg initmsg;
	uint16_t event_types[] = {SCTP_ASSOC_CHANGE,
	                          SCTP_PEER_ADDR_CHANGE,
	                          SCTP_REMOTE_ERROR,
	                          SCTP_SHUTDOWN_EVENT,
	                          SCTP_ADAPTATION_INDICATION,
	                          SCTP_SEND_FAILED_EVENT,
	                          SCTP_STREAM_RESET_EVENT,
	                          SCTP_STREAM_CHANGE_EVENT};

	if (argc > 1) {
		usrsctp_init(atoi(argv[1]), NULL, debug_printf);
	} else {
		usrsctp_init(9899, NULL, debug_printf);
	}
#ifdef SCTP_DEBUG
	usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_NONE);
#endif
	usrsctp_sysctl_set_sctp_blackhole(2);

	if ((sock = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, receive_cb, NULL, 0, &peer_connection)) == NULL) {
		perror("socket");
	}
	init_peer_connection(&peer_connection);
	if (argc > 2) {
		memset(&encaps, 0, sizeof(struct sctp_udpencaps));
		encaps.sue_address.ss_family = AF_INET6;
		encaps.sue_port = htons(atoi(argv[2]));
		if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_REMOTE_UDP_ENCAPS_PORT, (const void*)&encaps, (socklen_t)sizeof(struct sctp_udpencaps)) < 0) {
			perror("setsockopt");
		}
	}
	if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_RECVRCVINFO, &on, sizeof(int)) < 0) {
		perror("setsockopt SCTP_RECVRCVINFO");
	}
	if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_EXPLICIT_EOR, &on, sizeof(int)) < 0) {
		perror("setsockopt SCTP_EXPLICIT_EOR");
	}
	/* Allow resetting streams. */
	av.assoc_id = SCTP_ALL_ASSOC;
	av.assoc_value = SCTP_ENABLE_RESET_STREAM_REQ | SCTP_ENABLE_CHANGE_ASSOC_REQ;
	if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_ENABLE_STREAM_RESET, &av, sizeof(struct sctp_assoc_value)) < 0) {
		perror("setsockopt SCTP_ENABLE_STREAM_RESET");
	}
	/* Enable the events of interest. */
	memset(&event, 0, sizeof(event));
	event.se_assoc_id = SCTP_ALL_ASSOC;
	event.se_on = 1;
	for (i = 0; i < sizeof(event_types)/sizeof(uint16_t); i++) {
		event.se_type = event_types[i];
		if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(event)) < 0) {
			perror("setsockopt SCTP_EVENT");
		}
	}
	memset(&initmsg, 0, sizeof(struct sctp_initmsg));
	initmsg.sinit_num_ostreams = 5;
	initmsg.sinit_max_instreams = 65535;
	if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(struct sctp_initmsg)) < 0) {
		perror("setsockopt SCTP_INITMSG");
	}
	
	if (argc == 5) {
		/* operating as client */
		memset(&addr, 0, sizeof(struct sockaddr_in));
		addr.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
		addr.sin_len = sizeof(struct sockaddr_in);
#endif
		addr.sin_addr.s_addr = inet_addr(argv[3]);
		addr.sin_port = htons(atoi(argv[4]));
		if (usrsctp_connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
			perror("connect");
		}
		printf("Connected to %s:%d.\n",
		       inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
	} else if (argc == 4) {
		struct socket *conn_sock;

		/* operating as server */
		memset(&addr, 0, sizeof(struct sockaddr_in));
		addr.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
		addr.sin_len = sizeof(struct sockaddr_in);
#endif
		addr.sin_addr.s_addr = INADDR_ANY;
		addr.sin_port = htons(atoi(argv[3]));
		if (usrsctp_bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
			perror("bind");
		}
		if (usrsctp_listen(sock, 1) < 0) {
			perror("listen");
		}
		addr_len = (socklen_t)sizeof(struct sockaddr_in);
		memset(&addr, 0, sizeof(struct sockaddr_in));
		if ((conn_sock = usrsctp_accept(sock, (struct sockaddr *)&addr, &addr_len)) == NULL) {
			perror("accept");
		}
		usrsctp_close(sock);
		sock = conn_sock;
		printf("Connected to %s:%d.\n",
		       inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
	} else {
		printf("Usage: %s local_udp_port remote_udp_port local_port when operating as server\n"
		       "       %s local_udp_port remote_udp_port remote_addr remote_port when operating as client\n",
		       argv[0], argv[0]);
		return (0);
	}

	lock_peer_connection(&peer_connection);
	peer_connection.sock = sock;
	unlock_peer_connection(&peer_connection);

	for (;;) {
#ifdef _WIN32
		if (gets_s(line, LINE_LENGTH) == NULL) {
#else
		if (fgets(line, LINE_LENGTH, stdin) == NULL) {
#endif
			if (usrsctp_shutdown(sock, SHUT_WR) < 0) {
				perror("usrsctp_shutdown");
			}
			while (usrsctp_finish() != 0) {
#ifdef _WIN32
				Sleep(1000);
#else
				sleep(1);
#endif
			}
			break;
		}
		if (strncmp(line, "?", strlen("?")) == 0 ||
		    strncmp(line, "help", strlen("help")) == 0) {
			printf("Commands:\n"
			       "open unordered pr_policy pr_value - opens a channel\n"
			       "close channel - closes the channel\n"
			       "send channel:string - sends string using channel\n"
			       "status - prints the status\n"
			       "sleep n - sleep for n seconds\n"
			       "help - this message\n");
		} else if (strncmp(line, "status", strlen("status")) == 0) {
			lock_peer_connection(&peer_connection);
			print_status(&peer_connection);
			unlock_peer_connection(&peer_connection);
		} else if (strncmp(line, "quit", strlen("quit")) == 0) {
			if (usrsctp_shutdown(sock, SHUT_WR) < 0) {
				perror("usrsctp_shutdown");
			}
			while (usrsctp_finish() != 0) {
#ifdef _WIN32
				Sleep(1000);
#else
				sleep(1);
#endif
			}
			break;
		} else if (sscanf(line, "open %u %u %u", &unordered, &policy, &value) == 3) {
			lock_peer_connection(&peer_connection);
			channel = open_channel(&peer_connection, (uint8_t)unordered, (uint16_t)policy, (uint32_t)value);
			unlock_peer_connection(&peer_connection);
			if (channel == NULL) {
				printf("Creating channel failed.\n");
			} else {
				printf("Channel with id %u created.\n", channel->id);
			}
		} else if (sscanf(line, "close %u", &id) == 1) {
			if (id < NUMBER_OF_CHANNELS) {
				lock_peer_connection(&peer_connection);
				close_channel(&peer_connection, &peer_connection.channels[id]);
				unlock_peer_connection(&peer_connection);
			}
		} else if (sscanf(line, "send %u", &id) == 1) {
			if (id < NUMBER_OF_CHANNELS) {
				char *msg;

				msg = strstr(line, ":");
				if (msg) {
					msg++;
					lock_peer_connection(&peer_connection);
#ifdef _WIN32
					if (send_user_message(&peer_connection, &peer_connection.channels[id], msg, strlen(msg))) {
#else
					if (send_user_message(&peer_connection, &peer_connection.channels[id], msg, strlen(msg) - 1)) {
#endif
						printf("Message sent.\n");
					} else {
						printf("Message sending failed.\n");
					}
					unlock_peer_connection(&peer_connection);
				}
			}
		} else if (sscanf(line, "sleep %u", &seconds) == 1) {
#ifdef _WIN32
			Sleep(seconds * 1000);
#else
			sleep(seconds);
#endif
		} else {
			printf("Unknown command: %s", line);
		}
	}
	return (0);
}
Example #3
0
int
rtcdc_parse_offer_sdp(struct rtcdc_peer_connection *peer, const char *offer)
{
  if (peer == NULL || offer == NULL)
    return -1;

  if (peer->transport == NULL) {
    if (create_rtcdc_transport(peer, RTCDC_PEER_ROLE_CLIENT) < 0)
      return -1;
  }

  char **lines;
  lines = g_strsplit(offer, "\r\n", 0);

  char buf[BUFFER_SIZE];
  memset(buf, 0, sizeof buf);
  int pos = 0;
  int remote_port = 0;
  for (int i = 0; lines && lines[i]; ++i) {

#ifdef LEGACY_SDP
    if (g_str_has_prefix(lines[i], "m=application")) {
      char **columns = g_strsplit(lines[i], " ", 0);
      remote_port = atoi(columns[3]);
#else
    if (g_str_has_prefix(lines[i], "a=sctp-port:")) {
      char **columns = g_strsplit(lines[i], ":", 0);
      remote_port = atoi(columns[1]);
#endif
      if (remote_port <= 0)
        return -1;
      peer->transport->sctp->remote_port = remote_port;
      g_strfreev(columns);
    } else if (g_str_has_prefix(lines[i], "a=setup:")) {
      char **columns = g_strsplit(lines[i], ":", 0);
      if (strcmp(columns[1], "active") == 0 && peer->role == RTCDC_PEER_ROLE_CLIENT) {
        peer->role = RTCDC_PEER_ROLE_SERVER;
      } else if (strcmp(columns[1], "passive") == 0 && peer->role == RTCDC_PEER_ROLE_SERVER) {
        //peer->role = RTCDC_PEER_ROLE_CLIENT;
        peer->role = RTCDC_PEER_ROLE_SERVER;
      } else { // actpass
        // nothing to do
      }
      g_strfreev(columns);
    }
    pos += sprintf(buf + pos, "%s\n", lines[i]);
  }
  g_strfreev(lines);

  return parse_remote_sdp(peer->transport->ice, buf);
}

int
rtcdc_parse_candidate_sdp(struct rtcdc_peer_connection *peer, const char *candidates)
{
  if (peer == NULL || peer->transport == NULL)
    return -1;

  return parse_remote_candidate_sdp(peer->transport->ice, candidates);
}

struct rtcdc_data_channel *
rtcdc_create_data_channel(struct rtcdc_peer_connection *peer,
                          const char *label, const char *protocol,
                          rtcdc_on_open_cb on_open,
                          rtcdc_on_message_cb on_message,
                          rtcdc_on_close_cb on_close,
                          void *user_data)
{
  if (peer == NULL || peer->transport == NULL)
    return NULL;

  struct rtcdc_transport *transport = peer->transport;
  struct sctp_transport *sctp = transport->sctp;

  int i;
  for (i = 0; i < RTCDC_MAX_CHANNEL_NUM; ++i) {
    if (peer->channels[i])
      continue;
    break;
  }

  if (i == RTCDC_MAX_CHANNEL_NUM)
    return NULL;

  struct rtcdc_data_channel *ch = (struct rtcdc_data_channel *)calloc(1, sizeof *ch);
  if (ch == NULL)
    return NULL;
  ch->on_open = on_open;
  ch->on_message = on_message;
  ch->on_close = on_close;
  ch->user_data = user_data;
  ch->sctp = sctp;

  struct dcep_open_message *req;
  int rlen = sizeof *req + strlen(label) + strlen(protocol);
  req = (struct dcep_open_message *)calloc(1, rlen);
  if (req == NULL)
    goto open_channel_err;

  ch->type = DATA_CHANNEL_RELIABLE;
  ch->state = RTCDC_CHANNEL_STATE_CONNECTING;
  if (label)
    ch->label = strdup(label);
  if (protocol)
    ch->protocol = strdup(protocol);
  ch->sid = sctp->stream_cursor;
  sctp->stream_cursor += 2;

  req->message_type = DATA_CHANNEL_OPEN;
  req->channel_type = ch->type;
  req->priority = htons(0);
  req->reliability_param = htonl(0);
  if (label)
    req->label_length = htons(strlen(label));
  if (protocol)
    req->protocol_length = htons(strlen(protocol));
  memcpy(req->label_and_protocol, label, strlen(label));
  memcpy(req->label_and_protocol + strlen(label), protocol, strlen(protocol));

  int ret = send_sctp_message(sctp, req, rlen, ch->sid, WEBRTC_CONTROL_PPID);
  free(req);
  if (ret < 0)
    goto open_channel_err;

  if (0) {
open_channel_err:
    free(ch);
    ch = NULL;
  }

  peer->channels[i] = ch;
  return ch;
}

void
rtcdc_destroy_data_channel(struct rtcdc_data_channel *channel)
{
  if (channel == NULL)
    return;

  // todo: close channel
  if (channel->label)
    free(channel->label);
  if (channel->protocol)
    free(channel->protocol);
}

int
rtcdc_send_message(struct rtcdc_data_channel *channel, int datatype, void *data, size_t len)
{
  if (channel == NULL)
    return -1;

  int ppid;
  if (datatype == RTCDC_DATATYPE_STRING) {
    if (data == NULL || len == 0)
      ppid = WEBRTC_STRING_EMPTY_PPID;
    else
      ppid = WEBRTC_STRING_PPID;
  } else if (datatype == RTCDC_DATATYPE_BINARY) {
    if (data == NULL || len == 0)
      ppid = WEBRTC_BINARY_EMPTY_PPID;
    else
      ppid = WEBRTC_BINARY_PPID;
  } else
    return -1;

  return send_sctp_message(channel->sctp, data, len, channel->sid, ppid);
}

static gpointer
startup_thread(gpointer user_data)
{
  struct rtcdc_peer_connection *peer = (struct rtcdc_peer_connection *)user_data;
  struct rtcdc_transport *transport = peer->transport;
  struct ice_transport *ice = transport->ice;
  struct dtls_transport *dtls = transport->dtls;
  struct sctp_transport *sctp = transport->sctp;

  while (!peer->exit_thread && !ice->negotiation_done)
    g_usleep(2500);
  if (peer->exit_thread)
    return NULL;

#ifdef DEBUG_SCTP
  fprintf(stderr, "ICE negotiation done\n");
#endif

  if (peer->role == RTCDC_PEER_ROLE_CLIENT)
    SSL_set_connect_state(dtls->ssl);
  else
    SSL_set_accept_state(dtls->ssl);
  SSL_do_handshake(dtls->ssl);

  while (!peer->exit_thread && !dtls->handshake_done)
    g_usleep(2500);
  if (peer->exit_thread)
    return NULL;

#ifdef DEBUG_SCTP
  fprintf(stderr, "DTLS handshake done\n");
#endif

  if (peer->role == RTCDC_PEER_ROLE_CLIENT) {
    sctp->stream_cursor = 0; // use even streams
    struct sockaddr_conn sconn;
    memset(&sconn, 0, sizeof sconn);
    sconn.sconn_family = AF_CONN;
    sconn.sconn_port = htons(sctp->remote_port);
    sconn.sconn_addr = (void *)sctp;
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
    sconn.sconn_len = sizeof *sctp;
#endif
    fprintf(stderr, "usrsctp_connect ... \n");
    if (usrsctp_connect(sctp->sock, (struct sockaddr *)&sconn, sizeof sconn) < 0) {
#ifdef DEBUG_SCTP
      fprintf(stderr, "SCTP connection failed\n");
#endif
    } else {
#ifdef DEBUG_SCTP
      fprintf(stderr, "SCTP connected\n");
#endif
      sctp->handshake_done = TRUE;

      if (peer->on_connect)
        peer->on_connect(peer, peer->user_data);
    }
  } else {
    sctp->stream_cursor = 1; // use odd streams
    struct sockaddr_conn sconn;
    memset(&sconn, 0, sizeof sconn);
    sconn.sconn_family = AF_CONN;
    sconn.sconn_port = htons(sctp->local_port);
    sconn.sconn_addr = (void *)sctp;
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
    sconn.sconn_len = sizeof *sctp;
#endif
    usrsctp_listen(sctp->sock, 1);
    socklen_t len = sizeof sconn;
    fprintf(stderr, "usrsctp_accept ... \n");
    struct socket *s = usrsctp_accept(sctp->sock, (struct sockaddr *)&sconn, &len);
    if (s) {
#ifdef DEBUG_SCTP
      fprintf(stderr, "SCTP accepted\n");
#endif
      sctp->handshake_done = TRUE;
      struct socket *t = sctp->sock;
      sctp->sock = s;
      usrsctp_close(t);

      if (peer->on_connect)
        peer->on_connect(peer, peer->user_data);
    } else {
#ifdef DEBUG_SCTP
      fprintf(stderr, "SCTP acception failed\n");
#endif
    }
  }

  return NULL;
}

void
rtcdc_loop(struct rtcdc_peer_connection *peer)
{
  if (peer == NULL)
    return;

  while (!peer->initialized)
    g_usleep(50000);

  GThread *thread_ice = g_thread_new("ICE thread", &ice_thread, peer);
  GThread *thread_sctp = g_thread_new("SCTP thread", &sctp_thread, peer);
  GThread *thread_startup = g_thread_new("Startup thread", &startup_thread, peer);

  struct ice_transport *ice = peer->transport->ice;
  g_main_loop_run(ice->loop);
  peer->exit_thread = TRUE;

  g_thread_join(thread_ice);
  g_thread_join(thread_sctp);
  g_thread_join(thread_startup);

  g_thread_unref(thread_ice);
  g_thread_unref(thread_sctp);
  g_thread_unref(thread_startup);
}
Example #4
0
int main(int argc, char **argv)
{
#ifndef _WIN32
	int c;
#endif
	socklen_t addr_len;
	struct sockaddr_in local_addr;
	struct timeval start_time, now, diff_time;
	int client;
	uint16_t local_port, remote_port, port, local_udp_port, remote_udp_port;
	double seconds;
	double throughput;
	int nodelay = 0;
	struct sctp_assoc_value av;
	struct sctp_udpencaps encaps;
	struct sctp_sndinfo sndinfo;
#ifdef _WIN32
	HANDLE tid;
#else
	pthread_t tid;
#endif
	int fragpoint = 0;
	unsigned int runtime = 0;
	struct sctp_setadaptation ind = {0};
#ifdef _WIN32
	char *opt;
	int optind;
#endif
	unordered = 0;
	/*struct sctp_prinfo prinfo;
	struct sctp_sendv_spa spa;*/

	length = DEFAULT_LENGTH;
	number_of_messages = DEFAULT_NUMBER_OF_MESSAGES;
	port = DEFAULT_PORT;
	remote_udp_port = 0;
	local_udp_port = 9899;
	verbose = 0;
	very_verbose = 0;

	memset((void *) &remote_addr, 0, sizeof(struct sockaddr_in));
	memset((void *) &local_addr, 0, sizeof(struct sockaddr_in));

#ifndef _WIN32
	while ((c = getopt(argc, argv, "a:cp:l:E:f:n:T:uU:vVD")) != -1)
		switch(c) {
			case 'a':
				ind.ssb_adaptation_ind = atoi(optarg);
				break;
			case 'c':
				use_cb = 1;
				break;
			case 'l':
				length = atoi(optarg);
				break;
			case 'n':
				number_of_messages = atoi(optarg);
				break;
			case 'p':
				port = atoi(optarg);
				break;
			case 'E':
				local_udp_port = atoi(optarg);
				break;
			case 'f':
				fragpoint = atoi(optarg);
				break;
			case 'T':
				runtime = atoi(optarg);
				number_of_messages = 0;
				break;
			case 'u':
				unordered = 1;
				break;
			case 'U':
				remote_udp_port = atoi(optarg);
				break;
			case 'v':
				verbose = 1;
				break;
			case 'V':
				verbose = 1;
				very_verbose = 1;
				break;
			case 'D':
				nodelay = 1;
				break;
			default:
				fprintf(stderr, "%s", Usage);
				exit(1);
		}
#else
	for (optind = 1; optind < argc; optind++) {
		if (argv[optind][0] == '-') {
			switch (argv[optind][1]) {
				case 'a':
					if (++optind >= argc) {
						printf("%s", Usage);
						exit(1);
					}
					opt = argv[optind];
					ind.ssb_adaptation_ind = atoi(opt);
					break;
				case 'c':
					use_cb = 1;
					break;
				case 'l':
					if (++optind >= argc) {
						printf("%s", Usage);
						exit(1);
					}
					opt = argv[optind];
					length = atoi(opt);
					break;
				case 'p':
					if (++optind >= argc) {
						printf("%s", Usage);
						exit(1);
					}
					opt = argv[optind];
					port = atoi(opt);
					break;
				case 'n':
					if (++optind >= argc) {
						printf("%s", Usage);
						exit(1);
					}
					opt = argv[optind];
					number_of_messages = atoi(opt);
					break;
				case 'f':
					if (++optind >= argc) {
						printf("%s", Usage);
						exit(1);
					}
					opt = argv[optind];
					fragpoint = atoi(opt);
					break;
				case 'U':
					if (++optind >= argc) {
						printf("%s", Usage);
						exit(1);
					}
					opt = argv[optind];
					remote_udp_port = atoi(opt);
					break;
				case 'E':
					if (++optind >= argc) {
						printf("%s", Usage);
						exit(1);
					}
					opt = argv[optind];
					local_udp_port = atoi(opt);
					break;
				case 'T':
					if (++optind >= argc) {
						printf("%s", Usage);
						exit(1);
					}
					opt = argv[optind];
					runtime = atoi(opt);
					number_of_messages = 0;
					break;
				case 'u':
					unordered = 1;
					break;
				case 'v':
					verbose = 1;
					break;
				case 'V':
					verbose = 1;
					very_verbose = 1;
					break;
				case 'D':
					nodelay = 1;
					break;
				default:
					printf("%s", Usage);
					exit(1);
			}
		} else {
			break;
		}
	}
#endif
	if (optind == argc) {
		client = 0;
		local_port = port;
		remote_port = 0;
	} else {
		client = 1;
		local_port = 0;
		remote_port = port;
	}
	local_addr.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
	local_addr.sin_len = sizeof(struct sockaddr_in);
#endif
	local_addr.sin_port = htons(local_port);
	local_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	usrsctp_init(local_udp_port, NULL, debug_printf);
#ifdef SCTP_DEBUG
	usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_NONE);
#endif
	usrsctp_sysctl_set_sctp_blackhole(2);

	if (client) {
		if (use_cb) {
			if (!(psock = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, receive_cb, send_cb, length, NULL)) ){
				printf("user_socket() returned NULL\n");
				exit(1);
			}
		} else {
			if (!(psock = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, NULL, NULL, 0, NULL)) ){
				printf("user_socket() returned NULL\n");
				exit(1);
			}
		}
	} else {
		if (use_cb) {
			if (!(psock = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, receive_cb, NULL, 0, NULL)) ){
				printf("user_socket() returned NULL\n");
				exit(1);
			}
		} else {
			if (!(psock = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, NULL, NULL, 0, NULL)) ){
				printf("user_socket() returned NULL\n");
				exit(1);
			}
		}
	}

	if (usrsctp_bind(psock, (struct sockaddr *)&local_addr, sizeof(struct sockaddr_in)) == -1) {
		printf("usrsctp_bind failed.\n");
		exit(1);
	}

	if (usrsctp_setsockopt(psock, IPPROTO_SCTP, SCTP_ADAPTATION_LAYER, (const void*)&ind, (socklen_t)sizeof(struct sctp_setadaptation)) < 0) {
		perror("setsockopt");
	}

	if (!client) {
		if (usrsctp_listen(psock, 1) < 0) {
			printf("usrsctp_listen failed.\n");
			exit(1);
		}

		while (1) {
			memset(&remote_addr, 0, sizeof(struct sockaddr_in));
			addr_len = sizeof(struct sockaddr_in);
			if (use_cb) {
				struct socket *conn_sock;

				if ((conn_sock = usrsctp_accept(psock, (struct sockaddr *) &remote_addr, &addr_len))== NULL) {
					printf("usrsctp_accept failed.  exiting...\n");
					continue;
				}
			} else {
				struct socket **conn_sock;

				conn_sock = (struct socket **)malloc(sizeof(struct socket *));
				if ((*conn_sock = usrsctp_accept(psock, (struct sockaddr *) &remote_addr, &addr_len))== NULL) {
					printf("usrsctp_accept failed.  exiting...\n");
					continue;
				}
#ifdef _WIN32
				tid = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&handle_connection, (void *)conn_sock, 0, NULL);
#else
				pthread_create(&tid, NULL, &handle_connection, (void *)conn_sock);
#endif
			}
			if (verbose)
				printf("Connection accepted from %s:%d\n", inet_ntoa(remote_addr.sin_addr), ntohs(remote_addr.sin_port));
		}
		usrsctp_close(psock);
	} else {
		memset(&encaps, 0, sizeof(struct sctp_udpencaps));
		encaps.sue_address.ss_family = AF_INET;
		encaps.sue_port = htons(remote_udp_port);
		if (usrsctp_setsockopt(psock, IPPROTO_SCTP, SCTP_REMOTE_UDP_ENCAPS_PORT, (const void*)&encaps, (socklen_t)sizeof(struct sctp_udpencaps)) < 0) {
			perror("setsockopt");
		}

		remote_addr.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
		remote_addr.sin_len = sizeof(struct sockaddr_in);
#endif
		remote_addr.sin_addr.s_addr = inet_addr(argv[optind]);
		remote_addr.sin_port = htons(remote_port);

		/* TODO fragpoint stuff */
		if (nodelay == 1) {
			optval = 1;
		} else {
			optval = 0;
		}
		usrsctp_setsockopt(psock, IPPROTO_SCTP, SCTP_NODELAY, &optval, sizeof(int));

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

		if (usrsctp_connect(psock, (struct sockaddr *) &remote_addr, sizeof(struct sockaddr_in)) == -1 ) {
			printf("usrsctpconnect failed.  exiting...\n");
			exit(1);
		}

		buffer = malloc(length);
		memset(buffer, 'b', length);
		gettimeofday(&start_time, NULL);
		if (verbose) {
			printf("Start sending %ld messages...\n", (long)number_of_messages);
			fflush(stdout);
		}

		done = 0;

		if (runtime > 0) {
#ifndef _WIN32
			signal(SIGALRM, stop_sender);
			alarm(runtime);
#else
			printf("You cannot set the runtime in Windows yet\n");
			exit(-1);
#endif
		}

		messages = 0;

		sndinfo.snd_sid = 0;
		sndinfo.snd_flags = 0;
		sndinfo.snd_ppid = 0;
		sndinfo.snd_context = 0;
		sndinfo.snd_assoc_id = 0;

	/*prinfo.pr_policy = SCTP_PR_SCTP_RTX;
		prinfo.pr_value = 2;
		spa.sendv_sndinfo = sndinfo;
		spa.sendv_prinfo = prinfo;
		spa.sendv_flags = SCTP_SEND_SNDINFO_VALID | SCTP_SEND_PRINFO_VALID;*/

		if (use_cb) {
			if (very_verbose)
				printf("Sending message number %lu.\n", messages);

				if (usrsctp_sendv(psock, buffer, length, (struct sockaddr *) &remote_addr, 1,
				                  (void *)&sndinfo, (socklen_t)sizeof(struct sctp_sndinfo), SCTP_SENDV_SNDINFO,
				                  unordered?SCTP_UNORDERED:0) < 0) {
				perror("usrctp_sendv returned < 0");
				exit(1);
			}
			messages++;
			while (!done && (messages < (number_of_messages - 1))) {
#ifdef _WIN32
				Sleep(1000);
#else
				sleep(1);
#endif
			}
		} else {
			while (!done && ((number_of_messages == 0) || (messages < (number_of_messages - 1)))) {
				if (very_verbose)
					printf("Sending message number %lu.\n", messages + 1);

				if (usrsctp_sendv(psock, buffer, length, (struct sockaddr *) &remote_addr, 1,
				                  (void *)&sndinfo, (socklen_t)sizeof(struct sctp_sndinfo), SCTP_SENDV_SNDINFO,
				                  unordered?SCTP_UNORDERED:0) < 0) {
					perror("usrsctp_sendv returned < 0");
					exit(1);
				}
				messages++;
			}
			if (very_verbose)
				printf("Sending message number %lu.\n", messages + 1);

			if (usrsctp_sendv(psock, buffer, length, (struct sockaddr *) &remote_addr, 1,
			                  (void *)&sndinfo, (socklen_t)sizeof(struct sctp_sndinfo), SCTP_SENDV_SNDINFO,
			                  unordered?SCTP_UNORDERED:0) < 0) {
				perror("final usrsctp_sendv returned\n");
				exit(1);
			}
			messages++;
		}
		free (buffer);
		if (verbose)
			printf("done.\n");

		usrsctp_close(psock);
		gettimeofday(&now, NULL);
		timersub(&now, &start_time, &diff_time);
		seconds = diff_time.tv_sec + (double)diff_time.tv_usec/1000000;
		printf("%s of %ld messages of length %u took %f seconds.\n",
		       "Sending", messages, length, seconds);
		throughput = (double)messages * (double)length / seconds;
		printf("Throughput was %f Byte/sec.\n", throughput);
	}

	while (usrsctp_finish() != 0) {
#ifdef _WIN32
		Sleep(1000);
#else
		sleep(1);
#endif
	}
	return 0;
}
Example #5
0
int main(int argc, char **argv)
{
#ifndef _WIN32
    int c;
#endif
    socklen_t addr_len;
    struct sockaddr_in local_addr;
    struct timeval start_time, now, diff_time;
    int client;
    uint16_t local_port, remote_port, port, local_udp_port, remote_udp_port;
    int rcvbufsize=0, sndbufsize=0, myrcvbufsize, mysndbufsize;
    socklen_t intlen;
    double seconds;
    double throughput;
    int nodelay = 0;
    struct sctp_assoc_value av;
    struct sctp_udpencaps encaps;
    struct sctp_sndinfo sndinfo;
#ifdef _WIN32
    unsigned long srcAddr;
    HANDLE tid;
#else
    in_addr_t srcAddr;
    pthread_t tid;
#endif
    int fragpoint = 0;
    struct sctp_setadaptation ind = {0};
#ifdef _WIN32
    char *opt;
    int optind;
#endif
    unordered = 0;

    length = DEFAULT_LENGTH;
    number_of_messages = DEFAULT_NUMBER_OF_MESSAGES;
    port = DEFAULT_PORT;
    remote_udp_port = 0;
    local_udp_port = 9899;
    verbose = 0;
    very_verbose = 0;
    srcAddr = htonl(INADDR_ANY);

    memset((void *) &remote_addr, 0, sizeof(struct sockaddr_in));
    memset((void *) &local_addr, 0, sizeof(struct sockaddr_in));

#ifndef _WIN32
    while ((c = getopt(argc, argv, "a:cp:l:E:f:L:n:R:S:T:uU:vVD")) != -1)
        switch(c) {
        case 'a':
            ind.ssb_adaptation_ind = atoi(optarg);
            break;
        case 'c':
            use_cb = 1;
            break;
        case 'l':
            length = atoi(optarg);
            break;
        case 'n':
            number_of_messages = atoi(optarg);
            break;
        case 'p':
            port = atoi(optarg);
            break;
        case 'E':
            local_udp_port = atoi(optarg);
            break;
        case 'f':
            fragpoint = atoi(optarg);
            break;
        case 'L':
            inet_pton(AF_INET, optarg, &srcAddr);
            break;
        case 'R':
            rcvbufsize = atoi(optarg);
            break;
        case 'S':
            sndbufsize = atoi(optarg);
            break;
        case 'T':
            runtime = atoi(optarg);
            number_of_messages = 0;
            break;
        case 'u':
            unordered = 1;
            break;
        case 'U':
            remote_udp_port = atoi(optarg);
            break;
        case 'v':
            verbose = 1;
            break;
        case 'V':
            verbose = 1;
            very_verbose = 1;
            break;
        case 'D':
            nodelay = 1;
            break;
        default:
            fprintf(stderr, "%s", Usage);
            exit(1);
        }
#else
    for (optind = 1; optind < argc; optind++) {
        if (argv[optind][0] == '-') {
            switch (argv[optind][1]) {
            case 'a':
                if (++optind >= argc) {
                    printf("%s", Usage);
                    exit(1);
                }
                opt = argv[optind];
                ind.ssb_adaptation_ind = atoi(opt);
                break;
            case 'c':
                use_cb = 1;
                break;
            case 'l':
                if (++optind >= argc) {
                    printf("%s", Usage);
                    exit(1);
                }
                opt = argv[optind];
                length = atoi(opt);
                break;
            case 'p':
                if (++optind >= argc) {
                    printf("%s", Usage);
                    exit(1);
                }
                opt = argv[optind];
                port = atoi(opt);
                break;
            case 'n':
                if (++optind >= argc) {
                    printf("%s", Usage);
                    exit(1);
                }
                opt = argv[optind];
                number_of_messages = atoi(opt);
                break;
            case 'f':
                if (++optind >= argc) {
                    printf("%s", Usage);
                    exit(1);
                }
                opt = argv[optind];
                fragpoint = atoi(opt);
                break;
            case 'L':
                if (++optind >= argc) {
                    printf("%s", Usage);
                    exit(1);
                }
                opt = argv[optind];
                inet_pton(AF_INET, opt, &srcAddr);
                break;
            case 'U':
                if (++optind >= argc) {
                    printf("%s", Usage);
                    exit(1);
                }
                opt = argv[optind];
                remote_udp_port = atoi(opt);
                break;
            case 'E':
                if (++optind >= argc) {
                    printf("%s", Usage);
                    exit(1);
                }
                opt = argv[optind];
                local_udp_port = atoi(opt);
                break;
            case 'R':
                if (++optind >= argc) {
                    printf("%s", Usage);
                    exit(1);
                }
                opt = argv[optind];
                rcvbufsize = atoi(opt);
                break;
            case 'S':
                if (++optind >= argc) {
                    printf("%s", Usage);
                    exit(1);
                }
                opt = argv[optind];
                sndbufsize = atoi(opt);
                break;
            case 'T':
                if (++optind >= argc) {
                    printf("%s", Usage);
                    exit(1);
                }
                opt = argv[optind];
                runtime = atoi(opt);
                number_of_messages = 0;
                break;
            case 'u':
                unordered = 1;
                break;
            case 'v':
                verbose = 1;
                break;
            case 'V':
                verbose = 1;
                very_verbose = 1;
                break;
            case 'D':
                nodelay = 1;
                break;
            default:
                printf("%s", Usage);
                exit(1);
            }
        } else {
            break;
        }
    }
#endif
    if (optind == argc) {
        client = 0;
        local_port = port;
        remote_port = 0;
    } else {
        client = 1;
        local_port = 0;
        remote_port = port;
    }
    local_addr.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
    local_addr.sin_len = sizeof(struct sockaddr_in);
#endif
    local_addr.sin_port = htons(local_port);
    local_addr.sin_addr.s_addr = srcAddr;

    usrsctp_init(local_udp_port, NULL, debug_printf);
#ifdef SCTP_DEBUG
    usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_ALL);
#endif
    usrsctp_sysctl_set_sctp_blackhole(2);
    usrsctp_sysctl_set_sctp_enable_sack_immediately(1);

    if (client) {
        if (use_cb) {
            if (!(psock = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, client_receive_cb, send_cb, length, NULL))) {
                perror("user_socket");
                exit(1);
            }
        } else {
            if (!(psock = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, NULL, NULL, 0, NULL))) {
                perror("user_socket");
                exit(1);
            }
        }
    } else {
        if (use_cb) {
            if (!(psock = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, server_receive_cb, NULL, 0, NULL))) {
                perror("user_socket");
                exit(1);
            }
        } else {
            if (!(psock = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, NULL, NULL, 0, NULL))) {
                perror("user_socket");
                exit(1);
            }
        }
    }

    if (usrsctp_bind(psock, (struct sockaddr *)&local_addr, sizeof(struct sockaddr_in)) == -1) {
        perror("usrsctp_bind");
        exit(1);
    }

    if (usrsctp_setsockopt(psock, IPPROTO_SCTP, SCTP_ADAPTATION_LAYER, (const void*)&ind, (socklen_t)sizeof(struct sctp_setadaptation)) < 0) {
        perror("setsockopt");
    }

    if (!client) {
        if (rcvbufsize) {
            if (usrsctp_setsockopt(psock, SOL_SOCKET, SO_RCVBUF, &rcvbufsize, sizeof(int)) < 0) {
                perror("setsockopt: rcvbuf");
            }
        }
        if (verbose) {
            intlen = sizeof(int);
            if (usrsctp_getsockopt(psock, SOL_SOCKET, SO_RCVBUF, &myrcvbufsize, (socklen_t *)&intlen) < 0) {
                perror("getsockopt: rcvbuf");
            } else {
                fprintf(stdout,"Receive buffer size: %d.\n", myrcvbufsize);
            }
        }

        if (usrsctp_listen(psock, 1) < 0) {
            perror("usrsctp_listen");
            exit(1);
        }

        while (1) {
            memset(&remote_addr, 0, sizeof(struct sockaddr_in));
            addr_len = sizeof(struct sockaddr_in);
            if (use_cb) {
                struct socket *conn_sock;

                if ((conn_sock = usrsctp_accept(psock, (struct sockaddr *) &remote_addr, &addr_len))== NULL) {
                    perror("usrsctp_accept");
                    continue;
                }
            } else {
                struct socket **conn_sock;

                conn_sock = (struct socket **)malloc(sizeof(struct socket *));
                if ((*conn_sock = usrsctp_accept(psock, (struct sockaddr *) &remote_addr, &addr_len))== NULL) {
                    perror("usrsctp_accept");
                    continue;
                }
#ifdef _WIN32
                tid = CreateThread(NULL, 0, &handle_connection, (void *)conn_sock, 0, NULL);
#else
                pthread_create(&tid, NULL, &handle_connection, (void *)conn_sock);
#endif
            }
            if (verbose) {
                // const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
                //inet_ntoa(remote_addr.sin_addr)
                char addrbuf[INET_ADDRSTRLEN];
                printf("Connection accepted from %s:%d\n", inet_ntop(AF_INET, &(remote_addr.sin_addr), addrbuf, INET_ADDRSTRLEN), ntohs(remote_addr.sin_port));
            }
        }
        usrsctp_close(psock);
    } else {
        memset(&encaps, 0, sizeof(struct sctp_udpencaps));
        encaps.sue_address.ss_family = AF_INET;
        encaps.sue_port = htons(remote_udp_port);
        if (usrsctp_setsockopt(psock, IPPROTO_SCTP, SCTP_REMOTE_UDP_ENCAPS_PORT, (const void*)&encaps, (socklen_t)sizeof(struct sctp_udpencaps)) < 0) {
            perror("setsockopt");
        }

        remote_addr.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
        remote_addr.sin_len = sizeof(struct sockaddr_in);
#endif
        if (!inet_pton(AF_INET, argv[optind], &remote_addr.sin_addr.s_addr)) {
            printf("error: invalid destination address\n");
            exit(1);
        }
        remote_addr.sin_port = htons(remote_port);

        /* TODO fragpoint stuff */
        if (nodelay == 1) {
            optval = 1;
        } else {
            optval = 0;
        }
        usrsctp_setsockopt(psock, IPPROTO_SCTP, SCTP_NODELAY, &optval, sizeof(int));

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

        if (sndbufsize) {
            if (usrsctp_setsockopt(psock, SOL_SOCKET, SO_SNDBUF, &sndbufsize, sizeof(int)) < 0) {
                perror("setsockopt: sndbuf");
            }
        }
        if (verbose) {
            intlen = sizeof(int);
            if (usrsctp_getsockopt(psock, SOL_SOCKET, SO_SNDBUF, &mysndbufsize, (socklen_t *)&intlen) < 0) {
                perror("setsockopt: SO_SNDBUF");
            } else {
                fprintf(stdout,"Send buffer size: %d.\n", mysndbufsize);
            }
        }

        buffer = malloc(length);
        memset(buffer, 'b', length);

        if (usrsctp_connect(psock, (struct sockaddr *) &remote_addr, sizeof(struct sockaddr_in)) == -1 ) {
            perror("usrsctp_connect");
            exit(1);
        }

        gettimeofday(&start_time, NULL);

        done = 0;

        if (runtime > 0) {
#ifndef _WIN32
            signal(SIGALRM, stop_sender);
            alarm(runtime);
#else
            printf("You cannot set the runtime in Windows yet\n");
            exit(-1);
#endif
        }

        if (use_cb) {
            while (!done && (messages < (number_of_messages - 1))) {
#ifdef _WIN32
                Sleep(1000);
#else
                sleep(1);
#endif
            }
        } else {
            sndinfo.snd_sid = 0;
            sndinfo.snd_flags = 0;
            if (unordered != 0) {
                sndinfo.snd_flags |= SCTP_UNORDERED;
            }
            sndinfo.snd_ppid = 0;
            sndinfo.snd_context = 0;
            sndinfo.snd_assoc_id = 0;
            if (verbose) {
                printf("Start sending ");
                if (number_of_messages > 0) {
                    printf("%ld messages ", (long)number_of_messages);
                }
                if (runtime > 0) {
                    printf("for %u seconds ...", runtime);
                }
                printf("\n");
                fflush(stdout);
            }
            while (!done && ((number_of_messages == 0) || (messages < (number_of_messages - 1)))) {
                if (very_verbose) {
                    printf("Sending message number %lu.\n", messages + 1);
                }

                if (usrsctp_sendv(psock, buffer, length, (struct sockaddr *) &remote_addr, 1,
                                  (void *)&sndinfo, (socklen_t)sizeof(struct sctp_sndinfo), SCTP_SENDV_SNDINFO,
                                  0) < 0) {
                    perror("usrsctp_sendv");
                    exit(1);
                }
                messages++;
            }
            if (very_verbose) {
                printf("Sending message number %lu.\n", messages + 1);
            }

            sndinfo.snd_flags |= SCTP_EOF;
            if (usrsctp_sendv(psock, buffer, length, (struct sockaddr *) &remote_addr, 1,
                              (void *)&sndinfo, (socklen_t)sizeof(struct sctp_sndinfo), SCTP_SENDV_SNDINFO,
                              0) < 0) {
                perror("usrsctp_sendv");
                exit(1);
            }
            messages++;
        }
        free (buffer);

        if (verbose) {
            printf("Closing socket.\n");
        }

        usrsctp_close(psock);
        gettimeofday(&now, NULL);
        timersub(&now, &start_time, &diff_time);
        seconds = diff_time.tv_sec + (double)diff_time.tv_usec/1000000;
        printf("%s of %ld messages of length %u took %f seconds.\n",
               "Sending", messages, length, seconds);
        throughput = (double)messages * (double)length / seconds;
        printf("Throughput was %f Byte/sec.\n", throughput);
    }

    while (usrsctp_finish() != 0) {
#ifdef _WIN32
        Sleep(1000);
#else
        sleep(1);
#endif
    }
    return 0;
}
Example #6
0
static gpointer
startup_thread(gpointer user_data)
{
  struct rtcdc_peer_connection *peer = (struct rtcdc_peer_connection *)user_data;
  struct rtcdc_transport *transport = peer->transport;
  struct ice_transport *ice = transport->ice;
  struct dtls_transport *dtls = transport->dtls;
  struct sctp_transport *sctp = transport->sctp;

  while (!peer->exit_thread && !ice->negotiation_done)
    g_usleep(2500);
  if (peer->exit_thread)
    return NULL;

#ifdef DEBUG_SCTP
  fprintf(stderr, "ICE negotiation done\n");
#endif

  if (peer->role == RTCDC_PEER_ROLE_CLIENT)
    SSL_set_connect_state(dtls->ssl);
  else
    SSL_set_accept_state(dtls->ssl);
  SSL_do_handshake(dtls->ssl);

  while (!peer->exit_thread && !dtls->handshake_done)
    g_usleep(2500);
  if (peer->exit_thread)
    return NULL;

#ifdef DEBUG_SCTP
  fprintf(stderr, "DTLS handshake done\n");
#endif

  if (peer->role == RTCDC_PEER_ROLE_CLIENT) {
    sctp->stream_cursor = 0; // use even streams
    struct sockaddr_conn sconn;
    memset(&sconn, 0, sizeof sconn);
    sconn.sconn_family = AF_CONN;
    sconn.sconn_port = htons(sctp->remote_port);
    sconn.sconn_addr = (void *)sctp;
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
    sconn.sconn_len = sizeof *sctp;
#endif
    if (usrsctp_connect(sctp->sock, (struct sockaddr *)&sconn, sizeof sconn) < 0) {
#ifdef DEBUG_SCTP
      fprintf(stderr, "SCTP connection failed\n");
#endif
    } else {
#ifdef DEBUG_SCTP
      fprintf(stderr, "SCTP connected\n");
#endif
      sctp->handshake_done = TRUE;

      if (peer->on_connect)
        peer->on_connect(peer, peer->user_data);
    }
  } else {
    sctp->stream_cursor = 1; // use odd streams
    struct sockaddr_conn sconn;
    memset(&sconn, 0, sizeof sconn);
    sconn.sconn_family = AF_CONN;
    sconn.sconn_port = htons(sctp->local_port);
    sconn.sconn_addr = (void *)sctp;
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
    sconn.sconn_len = sizeof *sctp;
#endif
    usrsctp_listen(sctp->sock, 1);
    socklen_t len = sizeof sconn;
    struct socket *s = usrsctp_accept(sctp->sock, (struct sockaddr *)&sconn, &len);
    if (s) {
#ifdef DEBUG_SCTP
      fprintf(stderr, "SCTP accepted\n");
#endif
      sctp->handshake_done = TRUE;
      struct socket *t = sctp->sock;
      sctp->sock = s;
      usrsctp_close(t);

      if (peer->on_connect)
        peer->on_connect(peer, peer->user_data);
    } else {
#ifdef DEBUG_SCTP
      fprintf(stderr, "SCTP acception failed\n");
#endif
    }
  }

  return NULL;
}
Example #7
0
int
main(void)
{
	struct sockaddr_in sin_s, sin_c;
	struct sockaddr_conn sconn;
#ifdef _WIN32
	SOCKET fd_c, fd_s;
#else
	int fd_c, fd_s;
#endif
	struct socket *s_c, *s_s, *s_l;
#ifdef _WIN32
	HANDLE tid_c, tid_s;
#else
	pthread_t tid_c, tid_s;
#endif
	int cur_buf_size, snd_buf_size, rcv_buf_size;
	socklen_t opt_len;
	struct sctp_sndinfo sndinfo;
	char *line;
#ifdef _WIN32
	WSADATA wsaData;
#endif

#ifdef _WIN32
	if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
		printf("WSAStartup failed\n");
		exit (EXIT_FAILURE);
	}
#endif
	usrsctp_init(0, conn_output, debug_printf);
	/* set up a connected UDP socket */
#ifdef _WIN32
	if ((fd_c = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
		printf("socket() failed with error: %d\n", WSAGetLastError());
		exit(EXIT_FAILURE);
	}
	if ((fd_s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
		printf("socket() failed with error: %d\n", WSAGetLastError());
		exit(EXIT_FAILURE);
	}
#else
	if ((fd_c = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
		perror("socket");
		exit(EXIT_FAILURE);
	}
	if ((fd_s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
		perror("socket");
		exit(EXIT_FAILURE);
	}
#endif
	memset(&sin_c, 0, sizeof(struct sockaddr_in));
	sin_c.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
	sin_c.sin_len = sizeof(struct sockaddr_in);
#endif
	sin_c.sin_port = htons(9900);
	sin_c.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	memset(&sin_s, 0, sizeof(struct sockaddr_in));
	sin_s.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
	sin_s.sin_len = sizeof(struct sockaddr_in);
#endif
	sin_s.sin_port = htons(9901);
	sin_s.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
#ifdef _WIN32
	if (bind(fd_c, (struct sockaddr *)&sin_c, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
		printf("bind() failed with error: %d\n", WSAGetLastError());
		exit(EXIT_FAILURE);
	}
	if (bind(fd_s, (struct sockaddr *)&sin_s, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
		printf("bind() failed with error: %d\n", WSAGetLastError());
		exit(EXIT_FAILURE);
	}
#else
	if (bind(fd_c, (struct sockaddr *)&sin_c, sizeof(struct sockaddr_in)) < 0) {
		perror("bind");
		exit(EXIT_FAILURE);
	}
	if (bind(fd_s, (struct sockaddr *)&sin_s, sizeof(struct sockaddr_in)) < 0) {
		perror("bind");
		exit(EXIT_FAILURE);
	}
#endif
#ifdef _WIN32
	if (connect(fd_c, (struct sockaddr *)&sin_s, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
		printf("connect() failed with error: %d\n", WSAGetLastError());
		exit(EXIT_FAILURE);
	}
	if (connect(fd_s, (struct sockaddr *)&sin_c, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
		printf("connect() failed with error: %d\n", WSAGetLastError());
		exit(EXIT_FAILURE);
	}
#else
	if (connect(fd_c, (struct sockaddr *)&sin_s, sizeof(struct sockaddr_in)) < 0) {
		perror("connect");
		exit(EXIT_FAILURE);
	}
	if (connect(fd_s, (struct sockaddr *)&sin_c, sizeof(struct sockaddr_in)) < 0) {
		perror("connect");
		exit(EXIT_FAILURE);
	}
#endif
#ifdef _WIN32
	tid_c = CreateThread(NULL, 0, &handle_packets, (void *)&fd_c, 0, NULL);
	tid_s = CreateThread(NULL, 0, &handle_packets, (void *)&fd_s, 0, NULL);
#else
	if (pthread_create(&tid_c, NULL, &handle_packets, (void *)&fd_c)) {
		perror("pthread_create tid_c");
		exit(EXIT_FAILURE);
	}

	if (pthread_create(&tid_s, NULL, &handle_packets, (void *)&fd_s)) {
		perror("pthread_create tid_s");
		exit(EXIT_FAILURE);
	};
#endif
#ifdef SCTP_DEBUG
	usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_NONE);
#endif
	usrsctp_sysctl_set_sctp_ecn_enable(0);
	usrsctp_register_address((void *)&fd_c);
	usrsctp_register_address((void *)&fd_s);
	if ((s_c = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, receive_cb, NULL, 0, &fd_c)) == NULL) {
		perror("usrsctp_socket");
		exit(EXIT_FAILURE);
	}
	opt_len = (socklen_t)sizeof(int);
	cur_buf_size = 0;
	if (usrsctp_getsockopt(s_c, SOL_SOCKET, SO_SNDBUF, &cur_buf_size, &opt_len) < 0) {
		perror("usrsctp_getsockopt");
		exit(EXIT_FAILURE);
	}
	printf("Change send socket buffer size from %d ", cur_buf_size);
	snd_buf_size = 1<<22; /* 4 MB */
	if (usrsctp_setsockopt(s_c, SOL_SOCKET, SO_SNDBUF, &snd_buf_size, sizeof(int)) < 0) {
		perror("usrsctp_setsockopt");
		exit(EXIT_FAILURE);
	}
	opt_len = (socklen_t)sizeof(int);
	cur_buf_size = 0;
	if (usrsctp_getsockopt(s_c, SOL_SOCKET, SO_SNDBUF, &cur_buf_size, &opt_len) < 0) {
		perror("usrsctp_getsockopt");
		exit(EXIT_FAILURE);
	}
	printf("to %d.\n", cur_buf_size);
	if ((s_l = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, receive_cb, NULL, 0, &fd_s)) == NULL) {
		perror("usrsctp_socket");
		exit(EXIT_FAILURE);
	}
	opt_len = (socklen_t)sizeof(int);
	cur_buf_size = 0;
	if (usrsctp_getsockopt(s_l, SOL_SOCKET, SO_RCVBUF, &cur_buf_size, &opt_len) < 0) {
		perror("usrsctp_getsockopt");
		exit(EXIT_FAILURE);
	}
	printf("Change receive socket buffer size from %d ", cur_buf_size);
	rcv_buf_size = 1<<16; /* 64 KB */
	if (usrsctp_setsockopt(s_l, SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(int)) < 0) {
		perror("usrsctp_setsockopt");
		exit(EXIT_FAILURE);
	}
	opt_len = (socklen_t)sizeof(int);
	cur_buf_size = 0;
	if (usrsctp_getsockopt(s_l, SOL_SOCKET, SO_RCVBUF, &cur_buf_size, &opt_len) < 0) {
		perror("usrsctp_getsockopt");
		exit(EXIT_FAILURE);
	}
	printf("to %d.\n", cur_buf_size);
	/* Bind the client side. */
	memset(&sconn, 0, sizeof(struct sockaddr_conn));
	sconn.sconn_family = AF_CONN;
#ifdef HAVE_SCONN_LEN
	sconn.sconn_len = sizeof(struct sockaddr_conn);
#endif
	sconn.sconn_port = htons(5001);
	sconn.sconn_addr = &fd_c;
	if (usrsctp_bind(s_c, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn)) < 0) {
		perror("usrsctp_bind");
		exit(EXIT_FAILURE);
	}
	/* Bind the server side. */
	memset(&sconn, 0, sizeof(struct sockaddr_conn));
	sconn.sconn_family = AF_CONN;
#ifdef HAVE_SCONN_LEN
	sconn.sconn_len = sizeof(struct sockaddr_conn);
#endif
	sconn.sconn_port = htons(5001);
	sconn.sconn_addr = &fd_s;
	if (usrsctp_bind(s_l, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn)) < 0) {
		perror("usrsctp_bind");
		exit(EXIT_FAILURE);
	}
	/* Make server side passive... */
	if (usrsctp_listen(s_l, 1) < 0) {
		perror("usrsctp_listen");
		exit(EXIT_FAILURE);
	}
	/* Initiate the handshake */
	memset(&sconn, 0, sizeof(struct sockaddr_conn));
	sconn.sconn_family = AF_CONN;
#ifdef HAVE_SCONN_LEN
	sconn.sconn_len = sizeof(struct sockaddr_conn);
#endif
	sconn.sconn_port = htons(5001);
	sconn.sconn_addr = &fd_c;
	if (usrsctp_connect(s_c, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn)) < 0) {
		perror("usrsctp_connect");
		exit(EXIT_FAILURE);
	}
	if ((s_s = usrsctp_accept(s_l, NULL, NULL)) == NULL) {
		perror("usrsctp_accept");
		exit(EXIT_FAILURE);
	}
	usrsctp_close(s_l);
	if ((line = malloc(LINE_LENGTH)) == NULL) {
		exit(EXIT_FAILURE);
	}
	memset(line, 'A', LINE_LENGTH);
	sndinfo.snd_sid = 1;
	sndinfo.snd_flags = 0;
	sndinfo.snd_ppid = htonl(DISCARD_PPID);
	sndinfo.snd_context = 0;
	sndinfo.snd_assoc_id = 0;
	/* Send a 1 MB ordered message */
	if (usrsctp_sendv(s_c, line, LINE_LENGTH, NULL, 0, (void *)&sndinfo,
	                 (socklen_t)sizeof(struct sctp_sndinfo), SCTP_SENDV_SNDINFO, 0) < 0) {
		perror("usrsctp_sendv");
		exit(EXIT_FAILURE);
	}
	/* Send a 1 MB ordered message */
	if (usrsctp_sendv(s_c, line, LINE_LENGTH, NULL, 0, (void *)&sndinfo,
	                 (socklen_t)sizeof(struct sctp_sndinfo), SCTP_SENDV_SNDINFO, 0) < 0) {
		perror("usrsctp_sendv");
		exit(EXIT_FAILURE);
	}
	free(line);
	usrsctp_shutdown(s_c, SHUT_WR);

	while (usrsctp_finish() != 0) {
#ifdef _WIN32
		Sleep(1000);
#else
		sleep(1);
#endif
	}
#ifdef _WIN32
	TerminateThread(tid_c, 0);
	WaitForSingleObject(tid_c, INFINITE);
	TerminateThread(tid_s, 0);
	WaitForSingleObject(tid_s, INFINITE);
	if (closesocket(fd_c) == SOCKET_ERROR) {
		printf("closesocket() failed with error: %d\n", WSAGetLastError());
		exit(EXIT_FAILURE);
	}
	if (closesocket(fd_s) == SOCKET_ERROR) {
		printf("closesocket() failed with error: %d\n", WSAGetLastError());
		exit(EXIT_FAILURE);
	}
	WSACleanup();
#else
	pthread_cancel(tid_c);
	pthread_join(tid_c, NULL);
	pthread_cancel(tid_s);
	pthread_join(tid_s, NULL);
	if (close(fd_c) < 0) {
		perror("close");
		exit(EXIT_FAILURE);
	}
	if (close(fd_s) < 0) {
		perror("close");
		exit(EXIT_FAILURE);
	}
#endif
	return (0);
}
Example #8
0
int
main(int argc, char *argv[])
{
	struct sockaddr_in sin;
	struct sockaddr_conn sconn;
#ifdef _WIN32
	SOCKET fd;
#else
	int fd;
#endif
	struct socket *s;
#ifdef _WIN32
	HANDLE tid;
#else
	pthread_t tid;
#endif
#ifdef _WIN32
	WSADATA wsaData;
#endif

	if (argc < 4) {
		printf("error: this program requires 4 arguments!\n");
		exit(EXIT_FAILURE);
	}

#ifdef _WIN32
	if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
		printf("WSAStartup failed\n");
		exit (EXIT_FAILURE);
	}
#endif
	usrsctp_init(0, conn_output, debug_printf);
	/* set up a connected UDP socket */
#ifdef _WIN32
	if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
		printf("socket() failed with error: %d\n", WSAGetLastError());
	}
#else
	if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
		perror("socket");
	}
#endif
	memset(&sin, 0, sizeof(struct sockaddr_in));
	sin.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
	sin.sin_len = sizeof(struct sockaddr_in);
#endif
	sin.sin_port = htons(atoi(argv[2]));
	if (!inet_pton(AF_INET, argv[1], &sin.sin_addr.s_addr)){
		printf("error: invalid address\n");
		exit(1);
	}
#ifdef _WIN32
	if (bind(fd, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
		printf("bind() failed with error: %d\n", WSAGetLastError());
	}
#else
	if (bind(fd, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) < 0) {
		perror("bind");
	}
#endif
	memset(&sin, 0, sizeof(struct sockaddr_in));
	sin.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
	sin.sin_len = sizeof(struct sockaddr_in);
#endif
	sin.sin_port = htons(atoi(argv[4]));
	if (!inet_pton(AF_INET, argv[3], &sin.sin_addr.s_addr)){
		printf("error: invalid address\n");
		exit(1);
	}
#ifdef _WIN32
	if (connect(fd, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
		printf("connect() failed with error: %d\n", WSAGetLastError());
	}
#else
	if (connect(fd, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) < 0) {
		perror("connect");
	}
#endif
#ifdef SCTP_DEBUG
	usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_NONE);
#endif
	usrsctp_sysctl_set_sctp_ecn_enable(0);
	usrsctp_register_address((void *)&fd);
#ifdef _WIN32
	tid = CreateThread(NULL, 0, &handle_packets, (void *)&fd, 0, NULL);
#else
	pthread_create(&tid, NULL, &handle_packets, (void *)&fd);
#endif
	if ((s = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, receive_cb, NULL, 0, NULL)) == NULL) {
		perror("usrsctp_socket");
	}
	memset(&sconn, 0, sizeof(struct sockaddr_conn));
	sconn.sconn_family = AF_CONN;
#ifdef HAVE_SCONN_LEN
	sconn.sconn_len = sizeof(struct sockaddr_conn);
#endif
	sconn.sconn_port = htons(5001);
	sconn.sconn_addr = (void *)&fd;
	if (usrsctp_bind(s, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn)) < 0) {
		perror("usrsctp_bind");
	}
	if (usrsctp_listen(s, 1) < 0) {
		perror("usrsctp_listen");
	}
	while (1) {
		if (usrsctp_accept(s, NULL, NULL) == NULL) {
			perror("usrsctp_accept");
		}
	}
	usrsctp_close(s);
	usrsctp_deregister_address((void *)&fd);
	while (usrsctp_finish() != 0) {
#ifdef _WIN32
		Sleep(1000);
#else
		sleep(1);
#endif
	}
#ifdef _WIN32
	TerminateThread(tid, 0);
	WaitForSingleObject(tid, INFINITE);
	if (closesocket(fd) == SOCKET_ERROR) {
		printf("closesocket() failed with error: %d\n", WSAGetLastError());
	}
	WSACleanup();
#else
	pthread_cancel(tid);
	pthread_join(tid, NULL);
	if (close(fd) < 0) {
		perror("close");
	}
#endif
	return (0);
}