Exemple #1
0
/*
 * ------------------------------------------
 * Hang the process for a specified time.
 *
 *	Goes to sleep for a positive value.
 *	Any caught signal will terminate the sleep
 *	following the execution of that signal's catching routine.
 *
 * 	The actual hang duration should be NO LESS than the specified
 * 	duration for specified durations greater than .001 seconds.
 * 	Certain applications depend on this assumption.
 *
 * Arguments:
 *	num - time to sleep
 *
 * Return:
 *	none
 * ------------------------------------------
 */
void op_hang(mval* num)
{
	int		ms;
	double		tmp;
	mv_stent	*mv_zintcmd;
	ABS_TIME	cur_time, end_time;
#	ifdef VMS
	uint4 		time[2];
	int4		efn_mask, status;
#	endif
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	ms = 0;
	MV_FORCE_NUM(num);
	if (num->mvtype & MV_INT)
	{
		if (0 < num->m[1])
		{
			assert(MV_BIAS >= 1000);	/* if formats change overflow may need attention */
			ms = num->m[1] * (1000 / MV_BIAS);
		}
	} else if (0 == num->sgn) 		/* if sign is not 0 it means num is negative */
	{
		tmp = mval2double(num) * (double)1000;
		ms = ((double)MAXPOSINT4 >= tmp) ? (int)tmp : (int)MAXPOSINT4;
	}
	if (ms)
	{
		if (TREF(tpnotacidtime) * 1000 < ms)
			TPNOTACID_CHECK(HANGSTR);
#		if defined(DEBUG) && defined(UNIX)
		if (WBTEST_ENABLED(WBTEST_DEFERRED_TIMERS) && (3 > gtm_white_box_test_case_count) && (123000 == ms))
		{
			DEFER_INTERRUPTS(INTRPT_NO_TIMER_EVENTS);
			DBGFPF((stderr, "OP_HANG: will sleep for 20 seconds\n"));
			LONG_SLEEP(20);
			DBGFPF((stderr, "OP_HANG: done sleeping\n"));
			ENABLE_INTERRUPTS(INTRPT_NO_TIMER_EVENTS);
			return;
		}
		if (WBTEST_ENABLED(WBTEST_BREAKMPC)&& (0 == gtm_white_box_test_case_count) && (999 == ms))
		{
			frame_pointer->old_frame_pointer->mpc = (unsigned char *)GTM64_ONLY(0xdeadbeef12345678)
				NON_GTM64_ONLY(0xdead1234);
			return;
		}
		if (WBTEST_ENABLED(WBTEST_UTIL_OUT_BUFFER_PROTECTION) && (0 == gtm_white_box_test_case_count) && (999 == ms))
		{	/* Upon seeing a .999s hang this white-box test launches a timer that pops with a period of
		 	 * UTIL_OUT_SYSLOG_INTERVAL and prints a long message via util_out_ptr.
			 */
			start_timer((TID)&util_out_syslog_dump, UTIL_OUT_SYSLOG_INTERVAL, util_out_syslog_dump, 0, NULL);
			return;
		}
#		endif
		sys_get_curr_time(&cur_time);
		mv_zintcmd = find_mvstent_cmd(ZINTCMD_HANG, restart_pc, restart_ctxt, FALSE);
		if (!mv_zintcmd)
			add_int_to_abs_time(&cur_time, ms, &end_time);
		else
		{
			end_time = mv_zintcmd->mv_st_cont.mvs_zintcmd.end_or_remain;
			cur_time = sub_abs_time(&end_time, &cur_time);	/* get remaing time to sleep */
			if (0 <= cur_time.at_sec)
				ms = (int4)(cur_time.at_sec * 1000 + cur_time.at_usec / 1000);
			else
				ms = 0;		/* all done */
			/* restore/pop previous zintcmd_active[ZINTCMD_HANG] hints */
			TAREF1(zintcmd_active, ZINTCMD_HANG).restart_pc_last = mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_pc_prior;
			TAREF1(zintcmd_active, ZINTCMD_HANG).restart_ctxt_last
				= mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_ctxt_prior;
			TAREF1(zintcmd_active, ZINTCMD_HANG).count--;
			assert(0 <= TAREF1(zintcmd_active, ZINTCMD_HANG).count);
			if (mv_chain == mv_zintcmd)
				POP_MV_STENT();	/* just pop if top of stack */
			else
			{	/* flag as not active */
				mv_zintcmd->mv_st_cont.mvs_zintcmd.command = ZINTCMD_NOOP;
				mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_pc_check = NULL;
			}
			if (0 == ms)
				return;		/* done HANGing */
		}
#		ifdef UNIX
		if (ms < 10)
			SLEEP_USEC(ms * 1000, TRUE);	/* Finish the sleep if it is less than 10ms. */
		else
			hiber_start(ms);
#		elif defined(VMS)
		time[0] = -time_low_ms(ms);
		time[1] = -time_high_ms(ms) - 1;
		efn_mask = (1 << efn_outofband | 1 << efn_timer);
		if (SS$_NORMAL != (status = sys$setimr(efn_timer, &time, NULL, &time, 0)))
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$setimr"), CALLFROM, status);
		if (SS$_NORMAL != (status = sys$wflor(efn_outofband, efn_mask)))
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$wflor"), CALLFROM, status);
		if (outofband)
		{
			if (SS$_WASCLR == (status = sys$readef(efn_timer, &efn_mask)))
			{
				if (SS$_NORMAL != (status = sys$cantim(&time, 0)))
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$cantim"),
						CALLFROM, status);
			} else
				assertpro(SS$_WASSET == status);
		}
#		endif
	} else
		rel_quant();
	if (outofband)
	{
		PUSH_MV_STENT(MVST_ZINTCMD);
		mv_chain->mv_st_cont.mvs_zintcmd.end_or_remain = end_time;
		mv_chain->mv_st_cont.mvs_zintcmd.restart_ctxt_check = restart_ctxt;
		mv_chain->mv_st_cont.mvs_zintcmd.restart_pc_check = restart_pc;
		/* save current information from zintcmd_active */
		mv_chain->mv_st_cont.mvs_zintcmd.restart_ctxt_prior = TAREF1(zintcmd_active, ZINTCMD_HANG).restart_ctxt_last;
		mv_chain->mv_st_cont.mvs_zintcmd.restart_pc_prior = TAREF1(zintcmd_active, ZINTCMD_HANG).restart_pc_last;
		TAREF1(zintcmd_active, ZINTCMD_HANG).restart_pc_last = restart_pc;
		TAREF1(zintcmd_active, ZINTCMD_HANG).restart_ctxt_last = restart_ctxt;
		TAREF1(zintcmd_active, ZINTCMD_HANG).count++;
		mv_chain->mv_st_cont.mvs_zintcmd.command = ZINTCMD_HANG;
		outofband_action(FALSE);
	}
	return;
}
Exemple #2
0
int main(int argc, char **argv)
{
	int opt;
	int num_parms;
	char equiv_cmd[1024];
	char *buff;
	SOCKET sock;
	socklen_t fromlen = sizeof(struct sockaddr_in);
	int default_rcvbuf_sz, cur_size, sz;
	int num_rcvd;
	struct sockaddr_in name;
	struct sockaddr_in src;
	struct ip_mreq imr;
	struct timeval tv;
	int num_sent;
	float perc_loss;
	int cur_seq;
	struct iovec iov;
	ssize_t iovnr;
	int iovfd;
	char strbuffer[1000];

	prog_name = argv[0];


	if (o_log == 1) {
		iov.iov_base=strbuffer;
		iov.iov_len=0; //To be defined latter.
		iovfd= open ("log.out", O_WRONLY | O_CREAT | O_TRUNC);
		if (iovfd == -1) {
			perror ("open error");
			exit(1);
		}
	}


	buff = malloc(65536 + 1);  /* one extra for trailing null (if needed) */
	if (buff == NULL) { fprintf(stderr, "malloc failed\n"); exit(1); }

	signal(SIGPIPE, SIG_IGN);

	if((sock = socket(PF_INET,SOCK_DGRAM,0)) == INVALID_SOCKET) {
		fprintf(stderr, "ERROR: ");  perror("socket");
		exit(1);
	}
	sz = sizeof(default_rcvbuf_sz);
	if (getsockopt(sock,SOL_SOCKET,SO_RCVBUF,(char *)&default_rcvbuf_sz,
			(unsigned int *)&sz) == SOCKET_ERROR) {
		fprintf(stderr, "ERROR: ");  perror("getsockopt - SO_RCVBUF");
		exit(1);
	}

	/* default values for options */
	o_quiet_lvl = 0;
	o_rcvbuf_size = 0x400000;  /* 4MB */
	o_pause_ms = 0;
	o_verify = 0;
	o_stop = 0;
	o_log = 0;

	/* default values for optional positional params */
	bind_if = NULL;

	while ((opt = getopt(argc, argv, "hqQ:p:r:vsl")) != EOF) {
		switch (opt) {
		  case 'h':
			help(NULL);  exit(0);
			break;
		  case 'q':
			o_quiet_lvl = 2;
			break;
		  case 'Q':
			o_quiet_lvl = atoi(optarg);
			break;
		  case 'p':
			o_pause_ms = atoi(optarg);
			break;
		  case 'r':
			o_rcvbuf_size = atoi(optarg);
			if (o_rcvbuf_size == 0)
				o_rcvbuf_size = default_rcvbuf_sz;
			break;
		  case 'v':
			o_verify = 1;
			break;
		  case 's':
			o_stop = 1;
			break;
		  case 'l':
			o_log = 1;
		  default:
			usage("unrecognized option");
			exit(1);
			break;
		}  /* switch */
	}  /* while opt */

	num_parms = argc - optind;
	
	if (o_log == 1) {
		iov.iov_base=strbuffer;
		iov.iov_len=0; //To be defined latter.
		iovfd= open ("log.out", O_WRONLY | O_CREAT | O_TRUNC);
		if (iovfd == -1) {
			perror ("open error");
			exit(1);
		}
	}


	/* handle positional parameters */
	if (num_parms == 2) {
		groupaddr = inet_addr(argv[optind]);
		groupport = (unsigned short)atoi(argv[optind+1]);
		sprintf(equiv_cmd, "mdump -p%d -Q%d -r%d %s%s%s %s",
				o_pause_ms, o_quiet_lvl, o_rcvbuf_size,
				o_verify ? "-v " : "",
				o_stop ? "-s " : "",
				argv[optind],argv[optind+1]);
		printf("Equiv cmd line: %s\n", equiv_cmd);
		fflush(stdout);
		fprintf(stderr, "Equiv cmd line: %s\n", equiv_cmd);
		fflush(stderr);
	} else if (num_parms == 3) {
		groupaddr = inet_addr(argv[optind]);
		groupport = (unsigned short)atoi(argv[optind+1]);
		bind_if  = argv[optind+2];
		sprintf(equiv_cmd, "mdump -p%d -Q%d -r%d %s%s %s %s",
				o_pause_ms, o_quiet_lvl, o_rcvbuf_size,
				o_verify ? "-v " : "",
				argv[optind],argv[optind+1],argv[optind+2]);
		printf("Equiv cmd line: %s\n", equiv_cmd);
		fflush(stdout);
		fprintf(stderr, "Equiv cmd line: %s\n", equiv_cmd);
		fflush(stderr);
	} else {
		usage("need 2-3 positional parameters");
		exit(1);
	}

	if(setsockopt(sock,SOL_SOCKET,SO_RCVBUF,(const char *)&o_rcvbuf_size,
			sizeof(o_rcvbuf_size)) == SOCKET_ERROR) {
		printf("WARNING: setsockopt - SO_RCVBUF\n");
		fflush(stdout);
		fprintf(stderr, "WARNING: "); perror("setsockopt - SO_RCVBUF");
		fflush(stderr);
	}
	sz = sizeof(cur_size);
	if (getsockopt(sock,SOL_SOCKET,SO_RCVBUF,(char *)&cur_size,
			(unsigned int *)&sz) == SOCKET_ERROR) {
		fprintf(stderr, "ERROR: ");  perror("getsockopt - SO_RCVBUF");
		exit(1);
	}
	if (cur_size < o_rcvbuf_size) {
		printf("WARNING: tried to set SO_RCVBUF to %d, only got %d\n",
				o_rcvbuf_size, cur_size);
		fflush(stdout);
		fprintf(stderr, "WARNING: tried to set SO_RCVBUF to %d, only got %d\n",
				o_rcvbuf_size, cur_size);
		fflush(stderr);
	}

	memset((char *)&imr,0,sizeof(imr));
	imr.imr_multiaddr.s_addr = groupaddr;
	if (bind_if != NULL) {
		imr.imr_interface.s_addr = inet_addr(bind_if);
	} else {
		imr.imr_interface.s_addr = htonl(INADDR_ANY);
	}

	opt = 1;
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) == SOCKET_ERROR) {
		fprintf(stderr, "ERROR: ");  perror("setsockopt SO_REUSEADDR");
		exit(1);
	}

	memset((char *)&name,0,sizeof(name));
	name.sin_family = AF_INET;
	name.sin_addr.s_addr = groupaddr;
	name.sin_port = htons(groupport);
	if (bind(sock,(struct sockaddr *)&name,sizeof(name)) == SOCKET_ERROR) {
		name.sin_addr.s_addr = htonl(INADDR_ANY);
		if (bind(sock,(struct sockaddr *)&name, sizeof(name)) == -1) {
			fprintf(stderr, "ERROR: ");  perror("bind");
			exit(1);
		}
	}

	if (setsockopt(sock,IPPROTO_IP,IP_ADD_MEMBERSHIP,
				(char *)&imr,sizeof(struct ip_mreq)) == SOCKET_ERROR ) {
		fprintf(stderr, "ERROR: ");  perror("setsockopt - IP_ADD_MEMBERSHIP");
		exit(1);
	}

	cur_seq = 0;
	num_rcvd = 0;
	for (;;) {
		cur_size = recvfrom(sock,buff,65536,0,
				(struct sockaddr *)&src,&fromlen);
		if (cur_size == SOCKET_ERROR) {
			fprintf(stderr, "ERROR: ");  perror("recv");
			exit(1);
		}

		if (o_log == 1 ) {
			currenttv(&tv);
			sprintf(strbuffer, "%s %s.%d %d bytes:\n",
				format_time(&tv), inet_ntoa(src.sin_addr),
				ntohs(src.sin_port), cur_size);
			
		}

		if (o_quiet_lvl == 0) {  /* non-quiet: print full dump */
			currenttv(&tv);
			printf("%s %s.%d %d bytes:\n",
					format_time(&tv), inet_ntoa(src.sin_addr),
					ntohs(src.sin_port), cur_size);
			dump(buff,cur_size);
		}
		if (o_quiet_lvl == 1) {  /* semi-quiet: print datagram summary */
			currenttv(&tv);
			printf("%s %s.%d %d bytes\n",  /* no colon */
					format_time(&tv), inet_ntoa(src.sin_addr),
					ntohs(src.sin_port), cur_size);
			fflush(stdout);
		}

		if (o_pause_ms > 0) {
			SLEEP_USEC(o_pause_ms);
		}

		if (cur_size > 5 && memcmp(buff, "echo ", 5) == 0) {
			/* echo command */
			buff[cur_size] = '\0';  /* guarantee trailing null */
			if (buff[cur_size - 1] == '\n')
				buff[cur_size - 1] = '\0';  /* strip trailing nl */
			printf("%s\n", buff);
			fflush(stdout);
			fprintf(stderr, "%s\n", buff);
			fflush(stderr);
		}
		else if (cur_size > 5 && memcmp(buff, "stat ", 5) == 0) {
			/* when sender tells us to, calc and print stats */
			buff[cur_size] = '\0';  /* guarantee trailing null */
			/* 'stat' message contains num msgs sent */
			num_sent = atoi(&buff[5]);
			perc_loss = (float)(num_sent - num_rcvd) * 100.0 / (float)num_sent;
			printf("%d msgs sent, %d received (not including 'stat')\n",
					num_sent, num_rcvd);
			printf("%f%% loss\n", perc_loss);
			fflush(stdout);
			fprintf(stderr, "%d msgs sent, %d received (not including 'stat')\n",
					num_sent, num_rcvd);
			fprintf(stderr, "%f%% loss\n", perc_loss);
			fflush(stderr);

			if (o_stop)
				exit(0);

			/* reset stats */
			num_rcvd = 0;
			cur_seq = 0;
		}
		else {  /* not a cmd */
			if (o_verify) {
				buff[cur_size] = '\0';  /* guarantee trailing null */
				if (cur_seq != strtol(&buff[8], NULL, 16)) {
					printf("Expected seq %x (hex), got %s\n", cur_seq, &buff[8]);
					fflush(stdout);
					/* resyncronize sequence numbers in case there is loss */
					cur_seq = strtol(&buff[8], NULL, 16);
				}
			}

			++num_rcvd;
			++cur_seq;
		}
	}  /* for ;; */

	CLOSESOCKET(sock);

	exit(0);
}  /* main */