Merge pull request #294 from weinrank/cherry-pick-windows

Fixing some Windows specific errors and freeing memory in tsctp_upcall
diff --git a/programs/chargen_server_upcall.c b/programs/chargen_server_upcall.c
index 06056bc..a069f92 100644
--- a/programs/chargen_server_upcall.c
+++ b/programs/chargen_server_upcall.c
@@ -136,7 +136,7 @@
 		snd_info.snd_context = 0;
 		snd_info.snd_assoc_id = 0;
 		if (usrsctp_sendv(upcall_socket, buffer, strlen(buffer), NULL, 0, &snd_info, (socklen_t)sizeof(struct sctp_sndinfo), SCTP_SENDV_SNDINFO, 0) < 0) {
-			if (errno != EAGAIN) {
+			if (errno != EAGAIN && errno != EWOULDBLOCK) {
 				send_done = 1;
 				usrsctp_close(upcall_socket);
 				printf("client socket %p closed\n", (void *)upcall_socket);
diff --git a/programs/tsctp_upcall.c b/programs/tsctp_upcall.c
index 7830628..c29cef3 100644
--- a/programs/tsctp_upcall.c
+++ b/programs/tsctp_upcall.c
@@ -100,6 +100,18 @@
 	} while (0)
 #endif
 
+#ifdef _WIN32
+static void
+gettimeofday(struct timeval *tv, void *ignore)
+{
+	struct timeb tb;
+
+	ftime(&tb);
+	tv->tv_sec = (long)tb.time;
+	tv->tv_usec = tb.millitm * 1000;
+}
+#endif
+
 
 char Usage[] =
 "Usage: tsctp [options] [address]\n"
@@ -165,11 +177,21 @@
 	}
 
 	meta_accepted = malloc(sizeof(struct tsctp_meta));
+	if (!meta_accepted) {
+		printf("malloc() failed!\n");
+		exit(EXIT_FAILURE);
+	}
+
 	memset(meta_accepted, 0, sizeof(struct tsctp_meta));
 
 	meta_accepted->par_role = meta_listening->par_role;
 	meta_accepted->par_stats_human = meta_listening->par_stats_human;
 	meta_accepted->buffer = malloc(BUFFERSIZE);
+	
+	if (!meta_accepted->buffer) {
+		printf("malloc() failed!\n");
+		exit(EXIT_FAILURE);
+	}
 
 	usrsctp_set_upcall(conn_sock, handle_upcall, meta_accepted);
 }
@@ -220,7 +242,11 @@
 			} else {
 				if (par_very_verbose) {
 					if (infotype == SCTP_RECVV_RCVINFO) {
+#ifdef _WIN32
+						printf("Message received - %" PRIu64 " bytes - %s - sid %u - tsn %u %s\n",
+#else					
 						printf("Message received - %zd bytes - %s - sid %u - tsn %u %s\n",
+#endif
 							n,
 							(rcvinfo->rcv_flags & SCTP_UNORDERED) ? "unordered" : "ordered",
 							rcvinfo->rcv_sid,
@@ -229,7 +255,11 @@
 						);
 
 					} else {
+#ifdef _WIN32
+						printf("Message received - %" PRIu64 " bytes %s\n", n, (recv_flags & MSG_EOR) ? "- EOR" : "");
+#else
 						printf("Message received - %zd bytes %s\n", n, (recv_flags & MSG_EOR) ? "- EOR" : "");
+#endif
 					}
 				}
 				tsctp_meta->stat_fragment_sum += n;
@@ -242,7 +272,7 @@
 			}
 		}
 
-		if (n < 0 && errno != EAGAIN) {
+		if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
 			perror("usrsctp_recvv");
 			exit(EXIT_FAILURE);
 		}
@@ -277,6 +307,10 @@
 			}
 			fflush(stdout);
 			usrsctp_close(upcall_socket);
+
+			free(tsctp_meta->buffer);
+			free(tsctp_meta);
+			return;
 		}
 	}
 
@@ -302,10 +336,12 @@
 			}
 		}
 
-		if (errno != EAGAIN) {
+		if (errno != EAGAIN && errno != EWOULDBLOCK) {
 			done = 1;
 			usrsctp_close(upcall_socket);
 			printf("client socket %p closed\n", (void *)upcall_socket);
+			free(tsctp_meta->buffer);
+			free(tsctp_meta);
 			return;
 		}
 
@@ -322,24 +358,15 @@
 
 			done = 1;
 			usrsctp_close(upcall_socket);
+			free(tsctp_meta->buffer);
+			free(tsctp_meta);
+			return;
 		}
 	}
 
 	return;
 }
 
-#ifdef _WIN32
-static void
-gettimeofday(struct timeval *tv, void *ignore)
-{
-	struct timeb tb;
-
-	ftime(&tb);
-	tv->tv_sec = (long)tb.time;
- 	tv->tv_usec = tb.millitm * 1000;
-}
-#endif
-
 void
 debug_printf(const char *format, ...)
 {
@@ -380,7 +407,6 @@
 
 #ifdef _WIN32
 	unsigned long src_addr;
-	HANDLE tid;
 #else
 	in_addr_t src_addr;
 #endif
@@ -399,19 +425,13 @@
 	memset((void *) &local_addr, 0, sizeof(struct sockaddr_in));
 
 #ifndef _WIN32
-	while ((c = getopt(argc, argv, "a:cp:l:E:f:HL:n:R:S:T:uU:vVD")) != -1)
+	while ((c = getopt(argc, argv, "a:DE:f:Hl:L:n:p:R:S:T:uU:vV")) != -1)
 		switch(c) {
 			case 'a':
 				ind.ssb_adaptation_ind = atoi(optarg);
 				break;
-			case 'l':
-				par_message_length = atoi(optarg);
-				break;
-			case 'n':
-				par_messages = atoi(optarg);
-				break;
-			case 'p':
-				par_port = atoi(optarg);
+			case 'D':
+				nodelay = 1;
 				break;
 			case 'E':
 				local_udp_port = atoi(optarg);
@@ -422,11 +442,21 @@
 			case 'H':
 				par_stats_human = 1;
 				break;
+			case 'l':
+				par_message_length = atoi(optarg);
+				break;
 			case 'L':
 				if (inet_pton(AF_INET, optarg, &src_addr) != 1) {
 					printf("Can't parse %s\n", optarg);
+					exit(EXIT_FAILURE);
 				}
 				break;
+			case 'n':
+				par_messages = atoi(optarg);
+				break;
+			case 'p':
+				par_port = atoi(optarg);
+				break;
 			case 'R':
 				rcvbufsize = atoi(optarg);
 				break;
@@ -450,9 +480,6 @@
 				par_verbose = 1;
 				par_very_verbose = 1;
 				break;
-			case 'D':
-				nodelay = 1;
-				break;
 			default:
 				fprintf(stderr, "%s", Usage);
 				exit(1);
@@ -469,29 +496,16 @@
 					opt = argv[optind];
 					ind.ssb_adaptation_ind = atoi(opt);
 					break;
-				case 'l':
-					if (++optind >= argc) {
-						printf("%s", Usage);
-						exit(1);
-					}
-					opt = argv[optind];
-					length = atoi(opt);
+				case 'D':
+					nodelay = 1;
 					break;
-				case 'p':
+				case 'E':
 					if (++optind >= argc) {
 						printf("%s", Usage);
 						exit(1);
 					}
 					opt = argv[optind];
-					par_port = atoi(opt);
-					break;
-				case 'n':
-					if (++optind >= argc) {
-						printf("%s", Usage);
-						exit(1);
-					}
-					opt = argv[optind];
-					number_of_messages = atoi(opt);
+					local_udp_port = atoi(opt);
 					break;
 				case 'f':
 					if (++optind >= argc) {
@@ -501,6 +515,17 @@
 					opt = argv[optind];
 					fragpoint = atoi(opt);
 					break;
+				case 'H':
+					par_stats_human = 1;
+					break;
+				case 'l':
+					if (++optind >= argc) {
+						printf("%s", Usage);
+						exit(1);
+					}
+					opt = argv[optind];
+					par_message_length = atoi(opt);
+					break;
 				case 'L':
 					if (++optind >= argc) {
 						printf("%s", Usage);
@@ -509,21 +534,21 @@
 					opt = argv[optind];
 					inet_pton(AF_INET, opt, &src_addr);
 					break;
-				case 'U':
+				case 'n':
 					if (++optind >= argc) {
 						printf("%s", Usage);
 						exit(1);
 					}
 					opt = argv[optind];
-					remote_udp_port = atoi(opt);
+					par_messages = atoi(opt);
 					break;
-				case 'E':
+				case 'p':
 					if (++optind >= argc) {
 						printf("%s", Usage);
 						exit(1);
 					}
 					opt = argv[optind];
-					local_udp_port = atoi(opt);
+					par_port = atoi(opt);
 					break;
 				case 'R':
 					if (++optind >= argc) {
@@ -547,11 +572,19 @@
 						exit(1);
 					}
 					opt = argv[optind];
-					runtime = atoi(opt);
-					number_of_messages = 0;
+					par_runtime = atoi(opt);
+					par_messages = 0;
 					break;
 				case 'u':
-					unordered = 1;
+					par_ordered = 0;
+					break;
+				case 'U':
+					if (++optind >= argc) {
+						printf("%s", Usage);
+						exit(1);
+					}
+					opt = argv[optind];
+					remote_udp_port = atoi(opt);
 					break;
 				case 'v':
 					par_verbose = 1;
@@ -560,9 +593,6 @@
 					par_verbose = 1;
 					par_very_verbose = 1;
 					break;
-				case 'D':
-					nodelay = 1;
-					break;
 				default:
 					printf("%s", Usage);
 					exit(1);
@@ -574,9 +604,18 @@
 #endif
 
 	meta = malloc(sizeof(struct tsctp_meta));
+	if (!meta) {
+		printf("malloc() failed!\n");
+		exit(EXIT_FAILURE);
+	}
+
 	memset(meta, 0, sizeof(struct tsctp_meta));
 
 	meta->buffer = malloc(BUFFERSIZE);
+	if (!meta->buffer) {
+		printf("malloc() failed!\n");
+		exit(EXIT_FAILURE);
+	}
 
 	meta->par_stats_human = par_stats_human;
 	meta->par_message_length = par_message_length;
@@ -651,7 +690,11 @@
 		usrsctp_set_upcall(psock, handle_accept, meta);
 
 		while (1) {
+#ifdef _WIN32
+			Sleep(1000);
+#else
 			sleep(1);
+#endif
 		}
 
 	} else {
@@ -728,5 +771,6 @@
 		sleep(1);
 #endif
 	}
+
 	return 0;
 }