示例#1
2
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;
}
示例#2
0
int SctpSocket::RemoveAddress(SocketAddress& ad)
{
	if (!ad.IsValid())
	{
		Handler().LogError(this, "SctpSocket", -1, "invalid address", LOG_LEVEL_ERROR);
		return -1;
	}
	if (GetSocket() == INVALID_SOCKET)
	{
		Handler().LogError(this, "SctpSocket", -1, "RemoveAddress called with invalid file descriptor", LOG_LEVEL_ERROR);
		return -1;
	}
	int n = sctp_bindx(GetSocket(), ad, ad, SCTP_BINDX_REM_ADDR);
	if (n == -1)
	{
		Handler().LogError(this, "SctpSocket", -1, "sctp_bindx() failed", LOG_LEVEL_ERROR);
	}
	return n;
}
示例#3
0
int
bindx_r(int sk, struct sockaddr *addrs, int count, int flag)
{
	int error;
	int i;
	struct sockaddr *sa_addr;
	void *aptr;

	/* Set the port in every address.  */
	aptr = addrs;
	for (i = 0; i < count; i++) {
		sa_addr = (struct sockaddr *)aptr;

		switch(sa_addr->sa_family) {
		case AF_INET:
			((struct sockaddr_in *)sa_addr)->sin_port =
				htons(local_port);
			aptr += sizeof(struct sockaddr_in);
			break;
		case AF_INET6:
			((struct sockaddr_in6 *)sa_addr)->sin6_port =
				htons(local_port);
			aptr += sizeof(struct sockaddr_in6);
			break;
		default:
			fprintf(stderr, "Invalid address family\n");
			exit(1);
		}
	}

	error = sctp_bindx(sk, addrs, count, flag);
	if (error != 0) {
		fprintf(stderr, "\n\n\t\t***bindx_r: error adding addrs:"
			" %s. ***\n", strerror(errno));
		exit(1);
	}

	return 0;

} /* bindx_r() */
示例#4
0
文件: tsctp.c 项目: 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;
}
示例#5
0
文件: sctp.c 项目: inibir/daemongroup
/* book add for multi-homing and normal sctp connection, 2012-12-29 */
int	make_lep_v2(udp_addr_t	p_addr, udp_addr_t	s_addr, m3_u32 proc, m3_u8 multi_switch)
{
    iu_log_debug("%s  %d: %s\n",__FILE__, __LINE__, __func__);

    if(proc >= MAX_LOCAL_EP)
	{
	    iu_log_error("Error: invalid value of proc\n");
	    return -1;
	}
	
    int idx = proc;
    int enable = 1;
    struct sockaddr_in *paddr = NULL;
    struct sockaddr_in *saddr = NULL;
    struct sockaddr_in *addrs = NULL;
	struct sctp_event_subscribe evt;
	int addr_count = multi_switch ? 2 : 1;
	int addr_size = sizeof(struct sockaddr_in);
	
	addrs = (struct sockaddr_in*)malloc(addr_size*addr_count);
	if(addrs == NULL)
	{
	    perror("malloc");
	    return -1;
	}

    if (0 == from[idx].e_state) 
    {
        paddr = (struct sockaddr_in*)&from[idx].addr[0];
        paddr->sin_family		= AF_INET;
        paddr->sin_port		    = htons(p_addr.port);
        paddr->sin_addr.s_addr	= htonl(p_addr.ipaddr);
        /* copy primary_addr to addrs */
        memcpy(addrs+0, paddr, addr_size);
        from[idx].e_state = 1;
        from[idx].sockid = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
        iu_log_debug("socketid = %d, idx = %d, primary_ip = %x, primary_port = %x \n", from[idx].sockid, idx, from[idx].addr[0].sin_addr.s_addr, from[idx].addr[0].sin_port);
        if(multi_switch)
        {
            saddr = (struct sockaddr_in*)&from[idx].addr[1];
            saddr->sin_family		= AF_INET;
            saddr->sin_port		    = htons(s_addr.port);
            saddr->sin_addr.s_addr	= htonl(s_addr.ipaddr);
            /* copy secondary_addr to addrs */
            memcpy(addrs+1, saddr, addr_size);
            iu_log_debug("secondary_ip = %x, secondary_port = %x \n", from[idx].addr[1].sin_addr.s_addr, from[idx].addr[1].sin_port);
        }
        setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
        if (-1 == sctp_bindx(from[idx].sockid, (struct sockaddr*)addrs,
            addr_count, SCTP_BINDX_ADD_ADDR)) 
        {
            iu_log_debug("ERRNO:%d  sctp lep bindx failed\n", errno);
            perror("sctp E_bind_Fail");
            free(addrs);
            return -1;
        }
		memset(&evt, 0, sizeof(evt));
		/* all event paras set default value to be 1 */
		evt.sctp_data_io_event = 1;
		evt.sctp_association_event = 1;
		evt.sctp_address_event = 1;
		evt.sctp_send_failure_event = 1;
		evt.sctp_peer_error_event = 1;
		evt.sctp_shutdown_event = 1;
		evt.sctp_partial_delivery_event = 1;
		//evt.sctp_adaption_layer_event = 1;

	    if (setsockopt(from[idx].sockid, IPPROTO_SCTP, SCTP_EVENTS, 
					&evt, sizeof(evt)) != 0) 
		{
		    iu_log_debug("ERRNO:%d  sctp lep setsockopt failed\n", errno);
			perror("setevent failed");
			free(addrs);
			return -1;
		}
		
        if (-1 == listen(from[idx].sockid, 2)) 
        {
            iu_log_debug("ERRNO:%d sctp lep listen failed\n", errno);
            perror("E_listen_Fail");
            free(addrs);
            return -1;
        }
    }
    
    free(addrs);
    return idx;
}
示例#6
0
sctpAdaptorMod *
create_SCTP_adaptor(distributor *o,uint16_t port, int model, int rwnd , int swnd )
{
	sctpAdaptorMod *r;
	socklen_t length;
	struct sockaddr_in6 inAddr6,myAddr6;
	struct sctp_event_subscribe event;
	int optval;
	socklen_t optlen;
	int bindsa_len;

	memset(&inAddr6,0,sizeof(inAddr6));
	memset(&myAddr6,0,sizeof(myAddr6));
	inAddr6.sin6_port = htons(port);
	myAddr6.sin6_port = 0;
	inAddr6.sin6_family = AF_INET6;
	myAddr6.sin6_family = AF_INET6;
#ifdef HAVE_SA_LEN
	inAddr6.sin6_len = sizeof(struct sockaddr_in6);
	myAddr6.sin6_len = sizeof(struct sockaddr_in6);
#endif

	memset(to_ip,0,sizeof(to_ip));
	r = calloc(1,sizeof(sctpAdaptorMod));
	if(r == NULL)
		return(r);
	r->o = o;
	if(model & SCTP_UDP_TYPE){
		if (v4only) {
			mainFd = r->fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
		} else {
			mainFd = r->fd = socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP);
		}
	}else{
		if (v4only) {
			mainFd = r->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
		} else {
			mainFd = r->fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP);
		}
	}
	if(r->fd < 0){
		printf("errno:%d\n", errno);
		free(r);
		return(NULL);
	}
	optval = 1;
	errno = 0;
	/*  ret = ioctl(r->fd,FIONBIO,&optval);
	    printf("ret from FIONBIO ioctl is %d err:%d\n",
	    ret,errno);
	*/
	r->model = model & (SCTP_UDP_TYPE|SCTP_TCP_TYPE);
	if (v6only) {
		/* set this to v6 only... */
		optval = 1;
		if (setsockopt(r->fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&optval,
			       sizeof(optval)) == -1) {
			close(r->fd);
			free(r);
			return(NULL);
		}
	}
	/* fill in specific local server address if doing bind specific */
	if (bindSpecific) {
		int i, ret;
		for (i=0; i<bindSpecific; i++) {
			struct sockaddr *sa = (struct sockaddr *)&bind_ss[i];
			/* copy bind address in */
			memcpy(&inAddr6, &bind_ss[i], sizeof(struct sockaddr_in6));
			/* set desired port */
			if (sa->sa_family == AF_INET) {
				struct sockaddr_in *sin = (struct sockaddr_in *)&inAddr6;
				sin->sin_port = htons(port); 
				bindsa_len = sizeof(struct sockaddr_in);
			} else {
				inAddr6.sin6_port = htons(port);
				bindsa_len = sizeof(struct sockaddr_in6);
				inAddr6.sin6_scope_id = scope_id;
			}
			errno = 0;
			ret = sctp_bindx(r->fd, 
							 (struct sockaddr *)&inAddr6, 1, 
							 SCTP_BINDX_ADD_ADDR);
		}
	} else {
		if (v4only) {
			struct sockaddr_in *sin = (struct sockaddr_in *)&inAddr6;
			memset(sin, 0, sizeof(*sin));
			sin->sin_family = AF_INET;
#ifdef HAVE_SA_LEN
			sin->sin_len = sizeof(struct sockaddr_in);
#endif
			sin->sin_port = htons(port);
			bindsa_len = sizeof(struct sockaddr_in);
		} else {
			inAddr6.sin6_port = htons(port);
			bindsa_len = sizeof(struct sockaddr_in6);
			inAddr6.sin6_scope_id = scope_id;
		}
	}
	/* enable all event notifications */
	event.sctp_data_io_event = 1;
	event.sctp_association_event = 1;
	event.sctp_address_event = 1;
	event.sctp_send_failure_event = 1;
	event.sctp_peer_error_event = 1;
	event.sctp_shutdown_event = 1;
	event.sctp_partial_delivery_event = 1;
#if defined(__BSD_SCTP_STACK__)
	event.sctp_adaptation_layer_event = 1;
#else
	event.sctp_adaption_layer_event = 1;
#endif
#if defined(__BSD_SCTP_STACK__)
	event.sctp_authentication_event = 1;
	event.sctp_sender_dry_event = 1;
	event.sctp_stream_reset_event = 1;
#endif

	if (setsockopt(r->fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)) != 0) {
		printf("Can't do SET_EVENTS socket option! err:%d\n", errno);
	}
	optlen = 4;
	if(swnd) {
		optval = swnd;
		if(setsockopt(r->fd, SOL_SOCKET, SO_SNDBUF, &optval, optlen) != 0){
			printf("err:%d could not set sndbuf\n",errno);
		}
	}
	if (rwnd){
		optval = rwnd;
		if(setsockopt(r->fd, SOL_SOCKET, SO_RCVBUF, &optval, optlen) != 0){
			printf("err:%d could not set rcvbuf\n",errno);
		}
	}
	optval = 0;
	if(getsockopt(r->fd, SOL_SOCKET, SO_SNDBUF, &optval, &optlen) != 0)
		printf("err:%d could not read sndbuf\n",errno);
	else
		printf("snd buffer is %d\n",optval);

	optval = 0;
	if(getsockopt(r->fd, SOL_SOCKET, SO_RCVBUF, &optval, &optlen) != 0)
		printf("err:%d could not read rcvbuf\n",errno);
	else
		printf("rcv buffer is %d\n",optval);

	if ((port) && (bindSpecific == 0)) {
		if(bind(r->fd,(struct sockaddr *)&inAddr6, bindsa_len) < 0){
			printf("bind failed err:%d\n",errno);
			close(r->fd);
			free(r);
			return(NULL);
		}
	}

	if(model & SCTP_UDP_TYPE){
		printf("Calling listen for one-to-many model\n");
		listen(r->fd,1);
#ifdef __APPLE__
		{
			int opt = 0;
			/* fix Apple listen() issue */
			setsockopt(r->fd, IPPROTO_SCTP, SCTP_LISTEN_FIX, &opt, sizeof(opt));
		}
#endif
	}
	if(port){
		length = sizeof(myAddr6);
		if(getsockname(r->fd, (struct sockaddr *)&myAddr6, &length) < 0){
			printf("get sockname failed err:%d\n",errno);
			close(r->fd);
			free(r);
			return(NULL);
		}	

		if(port != ntohs(myAddr6.sin6_port)){
			printf("Can't get my port:%d got %d\n",port,ntohs(myAddr6.sin6_port));
			close(r->fd);
			free(r);
			return(NULL);
		}
	}
	dist_addFd(o,r->fd,sctpFdInput,POLLIN,(void *)r);
	object_in = r;
	return(r);
}
示例#7
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);
}
static int mca_btl_sctp_create(int if_index, const char* if_name)
{
    if(mca_btl_sctp_component.sctp_if_11) {

        char param[256];
        struct mca_btl_sctp_module_t* btl = (struct mca_btl_sctp_module_t *)malloc(sizeof(mca_btl_sctp_module_t));
        if(NULL == btl) {
            return OMPI_ERR_OUT_OF_RESOURCE;
        }
        memcpy(btl, &mca_btl_sctp_module, sizeof(mca_btl_sctp_module));
        OBJ_CONSTRUCT(&btl->sctp_endpoints, opal_list_t);
        mca_btl_sctp_component.sctp_btls[mca_btl_sctp_component.sctp_num_btls++] = btl;

        /* initialize the btl */
        btl->sctp_ifindex = if_index;
#if MCA_BTL_SCTP_STATISTICS
        btl->sctp_bytes_recv = 0;
        btl->sctp_bytes_sent = 0;
        btl->sctp_send_handler = 0;
#endif
        opal_ifindextoaddr(if_index, (struct sockaddr*)&btl->sctp_ifaddr, sizeof(btl->sctp_ifaddr));
        /* prepare for bind call later before connect */
        btl->sctp_ifaddr.sin_family = AF_INET;
#ifdef FREEBSD
        btl->sctp_ifaddr.sin_len = sizeof(struct sockaddr);
#endif
        btl->sctp_ifaddr.sin_port = 0;       
        opal_ifindextomask(if_index, (uint32_t *)&btl->sctp_ifmask, sizeof(btl->sctp_ifmask));

        /* allow user to specify interface bandwidth */
        sprintf(param, "bandwidth_%s", if_name);
        btl->super.btl_bandwidth = mca_btl_sctp_param_register_int(param, 0);

        /* allow user to override/specify latency ranking */
        sprintf(param, "latency_%s", if_name);
        btl->super.btl_latency = mca_btl_sctp_param_register_int(param, 0);

#if 0 && OPAL_ENABLE_DEBUG
        BTL_OUTPUT(("interface: %s bandwidth %d latency %d",
                    if_name, btl->super.btl_bandwidth, btl->super.btl_latency));
#endif
        return OMPI_SUCCESS;
    }

    else {
        /* 1 to many */
        struct mca_btl_sctp_module_t* btl;
        char param[256];
        struct sockaddr_in next_ifaddr;
        socklen_t len = sizeof(struct sockaddr_in);
        opal_socklen_t addrlen;
        
        /* check if this is the first time this function is being called */
        if(0 == mca_btl_sctp_component.sctp_num_btls) {

            /* fill in btl struct with first interface's information (arbitary) */

            btl = (struct mca_btl_sctp_module_t *)malloc(sizeof(mca_btl_sctp_module_t));
            if(NULL == btl) {
                return OMPI_ERR_OUT_OF_RESOURCE;
            }
            memcpy(btl, &mca_btl_sctp_module, sizeof(mca_btl_sctp_module));
            OBJ_CONSTRUCT(&btl->sctp_endpoints, opal_list_t);
            mca_btl_sctp_component.sctp_btls[mca_btl_sctp_component.sctp_num_btls++] = btl;

            /* initialize the btl */
            btl->sctp_ifindex = if_index;
#if MCA_BTL_SCTP_STATISTICS
            btl->sctp_bytes_recv = 0;
            btl->sctp_bytes_sent = 0;
            btl->sctp_send_handler = 0;
#endif
            opal_ifindextoaddr(if_index, (struct sockaddr*)&btl->sctp_ifaddr, sizeof(btl->sctp_ifaddr));
            opal_ifindextomask(if_index, (uint32_t *)&btl->sctp_ifmask, sizeof(btl->sctp_ifmask));

            /* allow user to specify interface bandwidth */
            sprintf(param, "bandwidth_%s", if_name);
            btl->super.btl_bandwidth = mca_btl_sctp_param_register_int(param, 0);

            /* allow user to override/specify latency ranking */
            sprintf(param, "latency_%s", if_name);
            btl->super.btl_latency = mca_btl_sctp_param_register_int(param, 0);

#if 0 && OPAL_ENABLE_DEBUG
            BTL_OUTPUT(("interface: %s bandwidth %d latency %d",
                        if_name, btl->super.btl_bandwidth, btl->super.btl_latency));
#endif
            /* call bind to this (initial) addr */
            opal_ifindextoaddr(if_index, (struct sockaddr*)&next_ifaddr, sizeof(next_ifaddr));
            next_ifaddr.sin_family = AF_INET;
#ifdef FREEBSD
            next_ifaddr.sin_len = sizeof(struct sockaddr);
#endif
            next_ifaddr.sin_port = 0;

            if(bind(mca_btl_sctp_component.sctp_listen_sd, (struct sockaddr *) &next_ifaddr, len) < 0) {
                return OMPI_ERR_FATAL;
            }

            /* resolve system assignend port */
            addrlen = sizeof(struct sockaddr_in);
            if(getsockname(mca_btl_sctp_component.sctp_listen_sd, (struct sockaddr*)&next_ifaddr, &addrlen) < 0) {
                BTL_ERROR(("getsockname() failed with errno=%d", opal_socket_errno));
                return OMPI_ERROR;
            }
            /* need to get the port after the first bind call for subsequent
             *  sctp_bindx calls.
             */
            mca_btl_sctp_component.sctp_listen_port = next_ifaddr.sin_port;
            
        } 

        else {
            next_ifaddr.sin_port = htons((unsigned short) mca_btl_sctp_component.sctp_listen_port);

            /* add this addr to bindx */
            opal_ifindextoaddr(if_index, (struct sockaddr*)&next_ifaddr, sizeof(next_ifaddr));
            next_ifaddr.sin_family = AF_INET;
#ifdef FREEBSD
            next_ifaddr.sin_len = sizeof(struct sockaddr);
#endif

            if(sctp_bindx(mca_btl_sctp_component.sctp_listen_sd, (struct sockaddr *) &next_ifaddr,
                          1, SCTP_BINDX_ADD_ADDR) < 0) {
                return OMPI_ERR_FATAL;
            }

        }

        return OMPI_SUCCESS;
    }
}
示例#9
0
static PyObject* bindx(PyObject* dummy, PyObject* args)
{
	PyObject* ret = 0;
	int fd;
	PyObject* addrs;
	struct sockaddr saddr;
	struct sockaddr* saddrs;
	int saddr_len, saddrs_len;
	int addrcount;
	int flags;
	int x;

	if (! PyArg_ParseTuple(args, "iOi", &fd, &addrs, &flags)) {
		return ret;
	}

	if (! PySequence_Check(addrs)) {
		PyErr_SetString(PyExc_ValueError, "Second parameter must be a sequence of address/port tuples");
		return ret;
	}

	addrcount = PySequence_Length(addrs);
	if (addrcount <= 0) {
		PyErr_SetString(PyExc_ValueError, "Second parameter must be a non-empty sequence");
		return ret;
	}

	saddrs_len = 0;
	saddrs = (struct sockaddr*) malloc(saddrs_len);

	for(x = 0; x < addrcount; ++x) {
		const char* caddr;
		int iport;

		PyObject* otuple = PySequence_GetItem(addrs, x);

		if (! PyArg_ParseTuple(otuple, "si", &caddr, &iport)) {
			free(saddrs);
			return ret;
		}
		
		if (! to_sockaddr(caddr, iport, &saddr, &saddr_len)) {
			PyErr_Format(PyExc_ValueError, "Invalid address: %s", caddr);
			free(saddrs);
			return ret;
		}

		if (saddr_len == 0) {
			PyErr_Format(PyExc_ValueError, "Invalid address family: %s", caddr);
			free(saddrs);
			return ret;
		}

		saddrs = realloc(saddrs, saddrs_len + saddr_len);
		memcpy( ((char*) saddrs) + saddrs_len, &saddr, saddr_len);
		saddrs_len += saddr_len;
	}

	if (sctp_bindx(fd, saddrs, addrcount, flags)) {
		PyErr_SetFromErrno(PyExc_IOError);
	} else {
		ret = Py_None; Py_INCREF(ret);
	}

	free(saddrs);
	return ret;
}
int main(int argc, char **argv) 
{
	unsigned int i, j, k;
	int num_messages=24;
	struct sockaddr_in bindaddr[10];
	char *baddr[10];
	int bndcnt=0;
	char *toaddr = NULL;
	int port = htons(DISCARD_PORT);

	while((i= getopt(argc,argv,"P:I:B:b:h:p:m:?")) != EOF)
	{
		switch(i) {
		case 'p':
			port = htons(strtol(optarg, NULL, 0));
			break;
		case 'P':
			pframe_rel = strtol(optarg, NULL, 0);
			break;
		case 'I':
			iframe_rel = strtol(optarg, NULL, 0);
			break;
		case 'B':
			bframe_rel = strtol(optarg, NULL, 0);
			break;


		case 'b':
			if (bndcnt < 10) {
				baddr[bndcnt] = optarg;
				bndcnt++;
			}
			break;
		case 'h':
			toaddr = optarg;
			break;
		case 'm':
			num_messages = strtol(optarg, NULL, 0);
			break;
		case '?':
		default:
			goto use;
			break;
		};
	}
	if (toaddr == NULL) {
	use:
		printf("use %s -h to-addr-in-dot-notation [-m message-cnt -b bindaddr]\n",
		       argv[0]);
		printf("                    [-P rel -I rel -B rel]\n");
		exit(0);
	}
	memset((void *)buffer, 'A', SIZE_OF_MESSAGE);
	if ((fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0)
		perror("socket");
	

	i = 1;
    	if(setsockopt(fd, IPPROTO_SCTP, SCTP_NODELAY, &i, sizeof(int))<0) {
        	perror("SCTP_NODELAY");
	}

	if (bndcnt) {
		/* prepare */
		memset(bindaddr, 0, sizeof(bindaddr));
		for(i=0; i<bndcnt; i++) {
			bindaddr[i].sin_len    = sizeof(struct sockaddr_in);
			bindaddr[i].sin_family = AF_INET;
			bindaddr[i].sin_port   = 0;
			inet_pton(AF_INET, baddr[i], &bindaddr[i].sin_addr);
		}
		/* bindx */
		if (sctp_bindx(fd, (struct sockaddr *)bindaddr,
			       bndcnt, SCTP_BINDX_ADD_ADDR) != 0) {
			perror("bind failed");
			exit(0);
		}
	}
	memset((void *)&addr, 0, sizeof(struct sockaddr_in));
	addr.sin_len    = sizeof(struct sockaddr_in);
	addr.sin_family = AF_INET;
	addr.sin_port   = port;
	inet_pton(AF_INET, toaddr, &addr.sin_addr);
	for (i = 0; i <  num_messages; i++) {
		if (send_iframe() < 0) {
			exit(-4);
		}
		if (send_pframe() < 0) {
			exit(-3);
		}
		for (j=0; j<5; j++) {
			if (send_pframe() < 0) {
				exit(-2);
			}
			for (k=0; k<6; k++) {
				if (send_bframe() < 0) {
					exit(-1);
				}
			}
		}
	}
	if (close(fd) < 0)
		perror("close");
	printf("\n");
	return(0);
}
示例#11
0
static int sctp_create_new_listener(SctpInit *init_p)
{
    struct sctp_event_subscribe event;
    struct sockaddr *addr;

    struct sctp_arg_s *sctp_arg_p;

    uint16_t i = 0, j;
    int sd;
    int used_addresses = 0;

    DevAssert(init_p != NULL);

    if (init_p->ipv4 == 0 && init_p->ipv6 == 0) {
        SCTP_ERROR("Illegal IP configuration upper layer should request at"
                   "least ipv4 and/or ipv6 config\n");
        return -1;
    }

    if ((used_addresses = init_p->nb_ipv4_addr + init_p->nb_ipv6_addr) == 0) {
        SCTP_WARN("No address provided...\n");
        return -1;
    }

    addr = calloc(used_addresses, sizeof(struct sockaddr));

    SCTP_DEBUG("Creating new listen socket on port %u with\n", init_p->port);

    if (init_p->ipv4 == 1) {
        struct sockaddr_in *ip4_addr;

        SCTP_DEBUG("ipv4 addresses:\n");

        for (i = 0; i < init_p->nb_ipv4_addr; i++) {
            SCTP_DEBUG("\t- "IPV4_ADDR"\n",
                       IPV4_ADDR_FORMAT(init_p->ipv4_address[i]));
            ip4_addr = (struct sockaddr_in *)&addr[i];
            ip4_addr->sin_family = AF_INET;
            ip4_addr->sin_port   = htons(init_p->port);
            ip4_addr->sin_addr.s_addr = init_p->ipv4_address[i];
        }
    }

    if (init_p->ipv6 == 1) {
        struct sockaddr_in6 *ip6_addr;

        SCTP_DEBUG("ipv6 addresses:\n");

        for (j = 0; j < init_p->nb_ipv6_addr; j++) {
            SCTP_DEBUG("\t- %s\n", init_p->ipv6_address[j]);
            ip6_addr = (struct sockaddr_in6 *)&addr[i + j];
            ip6_addr->sin6_family = AF_INET6;
            ip6_addr->sin6_port  = htons(init_p->port);

            if (inet_pton(AF_INET6, init_p->ipv6_address[j],
                          ip6_addr->sin6_addr.s6_addr) <= 0) {
                SCTP_WARN("Provided ipv6 address %s is not valid\n",
                          init_p->ipv6_address[j]);
            }
        }
    }

    if ((sd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) < 0) {
        SCTP_ERROR("socket: %s:%d\n", strerror(errno), errno);
        return -1;
    }

    memset((void *)&event, 1, sizeof(struct sctp_event_subscribe));

    if (setsockopt(sd, IPPROTO_SCTP, SCTP_EVENTS, &event,
                   sizeof(struct sctp_event_subscribe)) < 0) {
        SCTP_ERROR("setsockopt: %s:%d\n", strerror(errno), errno);
        return -1;
    }

    /* Some pre-bind socket configuration */
    if (sctp_set_init_opt(sd, sctp_desc.nb_instreams, sctp_desc.nb_outstreams,
                          0, 0) < 0) {
        goto err;
    }

    if (sctp_bindx(sd, addr, used_addresses, SCTP_BINDX_ADD_ADDR) != 0) {
        SCTP_ERROR("sctp_bindx: %s:%d\n", strerror(errno), errno);
        return -1;
    }

    if (listen(sd, 5) < 0) {
        SCTP_ERROR("listen: %s:%d\n", strerror(errno), errno);
        return -1;
    }

    if ((sctp_arg_p = malloc(sizeof(struct sctp_arg_s))) == NULL) {
        return -1;
    }

    sctp_arg_p->sd = sd;
    sctp_arg_p->ppid = init_p->ppid;

    if (pthread_create(&assoc_thread, NULL, &sctp_receiver_thread,
                       (void *)sctp_arg_p) < 0) {
        SCTP_ERROR("pthread_create: %s:%d\n", strerror(errno), errno);
        return -1;
    }

    return sd;
err:

    if (sd != -1) {
        close(sd);
        sd = -1;
    }

    return -1;
}
示例#12
-1
int Sctp_bindx(int sock_fd, struct sockaddr_storage* at, int num, int op)
{
    int ret;
    ret = sctp_bindx(sock_fd, at, num, op);
    if (ret < 0) {
        err_sys("sctp_bindx error");
    }
    return (ret);
}
示例#13
-1
文件: socket.c 项目: mlzboy/resys
/* sctp address format sctp:127.0.0.1,192.168.0.17:3031 */
int bind_to_sctp(char *socket_name, int listen_queue, char *sctp_port) {
    int serverfd;
    struct sockaddr_in uws_addr[MAX_SCTP_ADDRESS];
    int num_ip = 0;

    struct sctp_initmsg sctp_im;


    sctp_port[0] = 0;
    memset(uws_addr, 0, sizeof(struct sockaddr_in) * MAX_SCTP_ADDRESS);
    memset(&sctp_im, 0, sizeof(struct sctp_initmsg));

    while (socket_name != NULL && num_ip < MAX_SCTP_ADDRESS) {
        char *ap;
        while ((ap = strsep(&socket_name, ",")) != NULL) {
            if (*ap != '\0') {
                uws_addr[num_ip].sin_family = AF_INET;
                uws_addr[num_ip].sin_port = htons(atoi(sctp_port + 1));
                uws_addr[num_ip].sin_addr.s_addr = inet_addr(ap);
                num_ip++;
            }
        }
    }

    serverfd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
    if (serverfd < 0) {
        uwsgi_error("socket()");
        exit(1);
    }

    fprintf(stderr, "binding on %d SCTP interfaces on port: %d\n", num_ip, ntohs(uws_addr[0].sin_port));


    if (sctp_bindx(serverfd, (struct sockaddr *) uws_addr, num_ip, SCTP_BINDX_ADD_ADDR) != 0) {
        uwsgi_error("sctp_bindx()");
        exit(1);
    }

    sctp_im.sinit_max_instreams = 0xFFFF;
    sctp_im.sinit_num_ostreams = 0xFFFF;

    if (setsockopt(serverfd, IPPROTO_SCTP, SCTP_INITMSG, &sctp_im, sizeof(sctp_im))) {
        uwsgi_error("setsockopt()");
    }

    if (listen(serverfd, listen_queue) != 0) {
        uwsgi_error("listen()");
        exit(1);
    }

    return serverfd;
}