⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sctp_test.c

📁 SCTP 协议实现源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	return sk;} /* socket_r() */int bind_r(int sk, struct sockaddr_storage *saddr){        int error = 0, i = 0;	char *host_s, *serv_s;	if ((host_s = malloc(NI_MAXHOST)) == NULL) {		fprintf(stderr, "\n\t\t*** host_s malloc failed!!! ***\n");		exit(1);	}	if ((serv_s = malloc(NI_MAXSERV)) == NULL) {		fprintf(stderr, "\n\t\t*** serv_s malloc failed!!! ***\n");		exit(1);	}	do {		if (i > 0) sleep(1); /* sleep a while before new try... */		error = getnameinfo((struct sockaddr *)saddr, l_len, host_s,				    NI_MAXHOST, serv_s, NI_MAXSERV,				    NI_NUMERICHOST);		if (error)			printf("%s\n", gai_strerror(error));       		DEBUG_PRINT(DEBUG_MIN,			    "\tbind(sk=%d, [a:%s,p:%s])  --  attempt %d/%d\n",       			    sk, host_s, serv_s, i+1, MAX_BIND_RETRYS);       		error = bind(sk, (struct sockaddr *)saddr, l_len);	        if (error != 0) {	        	if( errno != EADDRINUSE ) {	        		if (do_exit) {	        		        fprintf(stderr, "\n\n\t\t***bind: can "						"not bind to %s:%s: %s ****\n",						host_s, serv_s,						strerror(errno));					exit(1);				} else {					return -1;				}			}		}		i++;		if (i >= MAX_BIND_RETRYS) {			fprintf(stderr, "Maximum bind() attempts. "				"Die now...\n\n");			exit(1);		}        } while (error < 0 && i < MAX_BIND_RETRYS);	return 0;} /* bind_r() */int listen_r(int sk, int listen_count){	int error = 0;	        DEBUG_PRINT(DEBUG_MIN, "\tlisten(sk=%d,backlog=%d)\n",		    sk, listen_count); 	/* Mark sk as being able to accept new associations */        error = listen(sk, 1);        if (error != 0) {        	if (do_exit) {                	fprintf(stderr, "\n\n\t\t*** listen:  %s ***\n\n\n",                       		strerror(errno));			exit(1);		}		else return -1;        }        return 0;} /* listen_r() */int receive_r(int sk, int once){	int i = 0, error = 0;        char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];        struct iovec iov;        struct msghdr inmessage;        /* Initialize inmessage with enough space for DATA... */        memset(&inmessage, 0, sizeof(inmessage));        if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) {		fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n");		exit(1);	}	iov.iov_len = REALLY_BIG;	inmessage.msg_iov = &iov;	inmessage.msg_iovlen = 1;	/* or a control message.  */	inmessage.msg_control = incmsg;	inmessage.msg_controllen = sizeof(incmsg);	/* Get the messages sent */	while (1) {		DEBUG_PRINT(DEBUG_MIN, "\trecvmsg(sk=%d) ", sk);		error = recvmsg(sk, &inmessage, MSG_WAITALL);		if (error < 0 && error != EAGAIN) {			fprintf(stderr, "\n\t\t*** recvmsg: %s ***\n\n",					strerror(errno));			fflush(stdout);			if (do_exit) exit(1);			else goto error_out;		}		else if (error == 0) {			printf("\n\t\trecvmsg() returned 0 !!!!\n");			fflush(stdout);		}		if (print_message(sk, &inmessage, error) > 0)			continue; /* got a notification... */		inmessage.msg_control = incmsg;		inmessage.msg_controllen = sizeof(incmsg);		iov.iov_len = REALLY_BIG;		i++;		if (once)			break;	}	free(iov.iov_base);	return 0;error_out:	close(sk);	free(iov.iov_base);	return -1;} /* receive_r () */int next_order(int state, int pattern){	switch (pattern){	case ORDER_PATTERN_UNORDERED:		state = 0;		break;	case ORDER_PATTERN_ORDERED:		state = 1;		break;	case ORDER_PATTERN_ALTERNATE:		state = state ? 0 : 1;		break;	case ORDER_PATTERN_RANDOM:		state = rand() % 2;		break;	}	return state;}int next_stream(int state, int pattern){	switch (pattern){	case STREAM_PATTERN_RANDOM:		state = rand() % (max_stream + 1);		break;	case STREAM_PATTERN_SEQUENTIAL:		state = state + 1;		if (state > max_stream)			state = 0;		break;	}	return state;}int next_msg_size(int msg_cnt){	int msg_size;	if (size_arg) {		msg_size = size_arg;	} else if (test_case < NCASES) {		msg_size = msg_sizes[test_case][msg_cnt];	} else {		msg_size = (rand() % max_msgsize) + 1;	}	return msg_size;} /* next_msg_size() */int next_assoc(int i, int state, int pattern){	int j;	int found = 0;	_assoc_state *as;	switch (pattern){	case ASSOC_PATTERN_RANDOM:		state = rand() % tosend;		break;	case ASSOC_PATTERN_SEQUENTIAL:		state = state + 1;		if (state >= tosend)			state = 0;		break;	}	as = poll_sks[i].assoc_state;	j = state;	do {		if (as[j].msg_sent < repeat_count) {			found = 1;			break;		}		if (++j >= tosend) {			j = 0;		}	} while (j != state);	if (found) {		return j;	} else {		return -1;	}	} /* next_assoc() */int send_r(int sk, int stream, int order, int send_size, int assoc_i){	int error = 0;	struct msghdr outmsg;	struct iovec iov;	char *message = NULL;	int msglen = 0;	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];	struct cmsghdr *cmsg;	struct sctp_sndrcvinfo *sinfo;	if (send_size > 0) {		message = build_msg(send_size);		msglen = strlen(message) + 1;		iov.iov_base = message;		iov.iov_len = msglen;	}	else {		if (do_exit) {			exit(1);		} else {			goto error_out;		}	}	outmsg.msg_name = &s_rem;       	outmsg.msg_namelen = sizeof(struct sockaddr_storage);	outmsg.msg_iov = &iov;	outmsg.msg_iovlen = 1;	outmsg.msg_control = outcmsg;	outmsg.msg_controllen = sizeof(outcmsg);	outmsg.msg_flags = 0;	cmsg = CMSG_FIRSTHDR(&outmsg);	cmsg->cmsg_level = IPPROTO_SCTP;	cmsg->cmsg_type = SCTP_SNDRCV;	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));	outmsg.msg_controllen = cmsg->cmsg_len;	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);	memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo));	sinfo->sinfo_ppid = rand();	sinfo->sinfo_stream = stream;	sinfo->sinfo_flags = 0;	if (!order)		sinfo->sinfo_flags = SCTP_UNORDERED;	DEBUG_PRINT(DEBUG_MIN, "\tsendmsg(sk=%d, assoc=%d) %4d bytes.\n",		    sk, assoc_i, send_size);	DEBUG_PRINT(DEBUG_MAX, "\t  SNDRCV");	if (DEBUG_MAX == debug_level) {        	printf("(stream=%u ", 	sinfo->sinfo_stream);		printf("flags=0x%x ",	sinfo->sinfo_flags);		printf("ppid=%u\n",	sinfo->sinfo_ppid);	}	/* Send to our neighbor.  */	error = sendmsg(sk, &outmsg, MSG_WAITALL);	if (error != msglen) {		fprintf(stderr, "\n\t\t*** sendmsg: %s ***\n\n",			strerror(errno));		fflush(stdout);			if (do_exit) {			exit(1);		} else {			if (!drain)				goto error_out;		}	}	if (send_size > 0) free(message);	return 0;error_out:	if (send_size > 0) free(message);	return -1;} /* send_r() */int close_r(int sk){	int error = 0;		DEBUG_PRINT(DEBUG_MIN, "\tclose(sk=%d)\n",sk);	error = close(sk);	if (error != 0) {		if (do_exit) {			fprintf(stderr, "\n\n\t\t*** close: %s ***\n\n",				strerror(errno));			exit(1);		} else {			return -1;		}	}	fflush(stdout);	return 0;} /* close_r() */voidserver(int sk){	if (max_msgsize > DEFAULT_MAX_WINDOW) {		if (setsockopt(sk, SOL_SOCKET, SO_RCVBUF, &max_msgsize,			       sizeof(max_msgsize)) < 0) {			perror("setsockopt(SO_RCVBUF)");			exit(1);		} 		}	receive_r(sk, 0);} /* server() */voidclient(int sk){	int msg_size;	int i;	for (i = 0; i < msg_cnt; i++) {		msg_size = next_msg_size(i);		order_state = next_order(order_state, order_pattern);		stream_state = next_stream(stream_state, stream_pattern);		if (send_r(sk, stream_state, order_state, msg_size, 0) < 0) {			close(sk);			break;		}		/* The sender is echoing so do discard the echoed data. */		if (drain) {			receive_r(sk, 1);		}	}} /* client() */voidmixed_mode_test(void){	int error, i, j, max_fd, sks, size;	int assoc_i, n_msg_size, n_order, n_stream;	int done = 0;	fd_set *ibitsp = NULL, *obitsp = NULL, *xbitsp = NULL;        char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];        struct iovec iov;        struct msghdr inmessage;	_assoc_state *as;		/* Set up the listeners.  If listeners is 0, set up one socket for	 * transmitting only.	 */	iov.iov_base = NULL;	max_fd = -1;	sks = (0 == listeners) ? 1 : listeners;	memset(poll_sks, 0, sizeof(sks * sizeof(_poll_sks)));	for (i = 0; i < sks; i++) {		poll_sks[i].sk = socket_r();		if (s_loc.ss_family == AF_INET6)			( (struct sockaddr_in6 *)&s_loc)->sin6_port =				htons(local_port + i);		else			( (struct sockaddr_in *)&s_loc)->sin_port =				htons(local_port + i);		bind_r(poll_sks[i].sk, &s_loc);		if (listeners) {			listen_r(poll_sks[i].sk, 100);		}		if (max_msgsize > DEFAULT_MAX_WINDOW) {			if (setsockopt(poll_sks[i].sk, SOL_SOCKET, SO_RCVBUF,				&max_msgsize, sizeof(max_msgsize)) < 0) {				perror("setsockopt(SO_RCVBUF)");				exit(1);			}		} 			if (tosend) {			if ((poll_sks[i].assoc_state = (_assoc_state *)malloc(				sizeof(_assoc_state) * tosend)) == NULL) {				printf("Can't allocate memory.\n");				goto clean_up;			}			memset(poll_sks[i].assoc_state, 0,				sizeof(_assoc_state) * tosend);		}		if (poll_sks[i].sk > max_fd) {			max_fd = poll_sks[i].sk;		}	}	size = howmany(max_fd + 1, NFDBITS) * sizeof(fd_mask);	if ((ibitsp = (fd_set *)malloc(size)) == NULL) {		printf("Can't allocate memory.\n");		goto clean_up;	}	if ((obitsp = (fd_set *)malloc(size)) == NULL) {		printf("Can't allocate memory.\n");		goto clean_up;	}	if ((xbitsp = (fd_set *)malloc(size)) == NULL) {		printf("Can't allocate memory.\n");		goto clean_up;	}	memset(ibitsp, 0, size);	memset(obitsp, 0, size);	memset(xbitsp, 0, size);        /* Initialize inmessage with enough space for DATA... */        memset(&inmessage, 0, sizeof(inmessage));        if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) {		fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n");		goto clean_up;	}	iov.iov_len = REALLY_BIG;	inmessage.msg_iov = &iov;	inmessage.msg_iovlen = 1;	/* or a control message.  */	inmessage.msg_control = incmsg;	inmessage.msg_controllen = sizeof(incmsg);	/* Set up the remote port number per association for output.  */	for (i = 0; i < sks; i++) {		as = poll_sks[i].assoc_state;		for (j = 0; j < tosend; j++) {			as[j].rem_port = remote_port + j;		}	}	while (!done) {		for (i = 0; i < sks; i++) {			FD_SET(poll_sks[i].sk, ibitsp);			FD_SET(poll_sks[i].sk, obitsp);			FD_SET(poll_sks[i].sk, xbitsp);		}		if ((error = select(max_fd + 1, ibitsp, obitsp, xbitsp,			(struct timeval *)0)) < 0) {			fprintf(stderr, "\n\t\t*** select() failed ");			fprintf(stderr, "with error: %s\n\n",				strerror(errno));			fflush(stdout);			goto clean_up;		}				for (i = 0; i < sks; i++) {			/* Is there anything to read from the socket?  */			if (listeners && FD_ISSET(poll_sks[i].sk, ibitsp)) {				FD_CLR(poll_sks[i].sk, ibitsp);				error = recvmsg(poll_sks[i].sk, &inmessage,					MSG_WAITALL);				if (error < 0) {					fprintf(stderr,						"\n\t\t*** recvmsg: %s ***\n\n",						strerror(errno));					fflush(stdout);					goto clean_up;				}				else if (error == 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -