Ejemplo n.º 1
0
/*--------------------------------------------------------------------------
 Create and show the send dialog box.
 The CRC field will display signature.
 The comments box will accept commentLen characters.
 If timeout is non-zero, the dialog box will cancel automatically in
 timeout seconds if the user does not interact with it.
 Returns 0 on success, non-zero on failure.
--------------------------------------------------------------------------*/
int sendbox_create(int iCmdShow, char *signature, int commentLen, int timeout)
{
	HINSTANCE hInstance = GetModuleHandle(NULL);
	clock_t now = eclock();

	sendbox.hwnd = CreateDialog(hInstance, "Sendbox", NULL, SendboxProc);
	if (sendbox.hwnd == NULL)
		return 1;
	sendbox.hComments = NULL;
	EnumChildWindows(sendbox.hwnd, &FindChildren, 0);
	if (!sendbox.hComments || !sendbox.hCRC)
		return 2;
	if (signature)
		SetWindowText(sendbox.hCRC, signature);

	sendbox.commentLen = commentLen;
	sendbox.buttonClicked = sendbox_CLICKED_NONE;
	if (timeout > 0)
		sendbox.timeout = now + timeout * ECLOCKS_PER_SEC;
	else
		sendbox.timeout = 0;
	DPRINT(("sendbox_create: t:%d, created with show:%d maxcomment:%d timeout:%d eclocks, at t:%d\n", now, iCmdShow, sendbox.commentLen, timeout * ECLOCKS_PER_SEC, sendbox.timeout));
	ShowWindow(sendbox.hwnd, iCmdShow);
	UpdateWindow(sendbox.hwnd);
	return 0;
}
Ejemplo n.º 2
0
/*------------------------------------------------------------------------
 Add a handle to the bhttp.
 Returns 0 on success,
 		 -1 on failure.
------------------------------------------------------------------------*/
static int bhttp_handleOpened(bhttp_t *bhttp, int h)
{
	clock_t now = eclock();
	bhttp_conn_t *pc;

	if (!bhttp || (h == -1))
		return -1;
	pc = (bhttp_conn_t *)assoctab_subscript(bhttp->conns, h);
	if (pc) {
		DPRINT(("bhttp_handleOpened: h:%d already open\n", h));
		return -1;
	}
	pc = (bhttp_conn_t *)assoctab_subscript_grow(bhttp->conns, h);
	if (!pc) {
		DPRINT(("bhttp_handleOpened: can't grow table for h:%d\n", h));
		return -1;
	}
	memset(pc, 0, sizeof(bhttp_conn_t));
	pc->ilen = 0;
	pc->ipos = 0;
	FD_SET(h, &bhttp->rfds);
	pc->t_connect = now;
	if (h > bhttp->sockmax)
		bhttp->sockmax = h;
	bhttp_assertValid(bhttp);
	DPRINT(("bhttp_handleOpened(h:%d)\n", h));
	return 0;
}
Ejemplo n.º 3
0
/*------------------------------------------------------------------------
 Add a handle to the sbdserv.
 Returns 0 on success,
 		 -1 on failure.
------------------------------------------------------------------------*/
static int sbdserv_handleOpened(sbdserv_t *sbdserv, int h)
{
	clock_t now = eclock();
	sbdserv_conn_t *pc;

	if (!sbdserv || (h == -1))
		return -1;
	pc = (sbdserv_conn_t *)assoctab_subscript(sbdserv->conns, h);
	if (pc) {
		DPRINT(("sbdserv_handleOpened: h:%d already open\n", h));
		return -1;
	}
	pc = (sbdserv_conn_t *)assoctab_subscript_grow(sbdserv->conns, h);
	if (!pc) {
		DPRINT(("sbdserv_handleOpened: can't grow table for h:%d\n", h));
		return -1;
	}
	memset(pc, 0, sizeof(sbdserv_conn_t));
	pc->pos = 0;
	pc->len = 0;
	FD_SET(h, &sbdserv->fds);
	pc->t_connect = now;
	if (h > sbdserv->sockmax)
		sbdserv->sockmax = h;
	sbdserv_assertValid(sbdserv);
	DPRINT(("sbdserv_handleOpened(h:%d)\n", h));
	return 0;
}
Ejemplo n.º 4
0
/*--------------------------------------------------------------------------
 Process any window events for the send dialog box.
 If OK is returned, up to commentLen characters of text in the comments box
 are returned in comment.
 Returns sendbox_CLICKED_NONE if no interesting events have occured,
         sendbox_CLICKED_CANCEL if the user clicked cancel,
		 sendbox_CLICKED_OK if the user clicked OK. 
--------------------------------------------------------------------------*/
int sendbox_poll(char *comment)
{
	MSG msg;
	int bUserInput = 0;
	const int oldButtonClicked = sendbox.buttonClicked;
	clock_t now = eclock();

	while ((oldButtonClicked == sendbox.buttonClicked)
	   &&  PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
		if (!IsDialogMessage(sendbox.hwnd, &msg)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		if (sendbox.timeout
		&&  (msg.hwnd == sendbox.hComments)
		&&  (msg.message == WM_KEYDOWN)) {
			DPRINT(("sendbox_poll: t:%d, user keystroke cancelled timeout\n", now));
			sendbox.timeout = 0;
		}
	}
	if (sendbox.buttonClicked == sendbox_CLICKED_OK) {
		comment[0] = '\0';
		GetWindowText(sendbox.hComments, comment, sendbox.commentLen);
		comment[sendbox.commentLen-1] = '\0';
		DPRINT(("sendbox_poll: t:%d, got comment:%d\n", now, comment));
	}
	if (sendbox.timeout && (long)(now - sendbox.timeout) > 0) {
		DPRINT(("sendbox_poll: t:%d, timed out waiting for input\n", now));
		sendbox.buttonClicked = sendbox_CLICKED_CANCEL;
	}
	return sendbox.buttonClicked;
}
Ejemplo n.º 5
0
/*------------------------------------------------------------------------
 Create an instance of the sbdserv module, listening on port for new
 connections.
------------------------------------------------------------------------*/
sbdserv_t *sbdserv_create(unsigned short port)
{
	clock_t now = eclock();
	sbdserv_t *sbdserv;
	struct protoent *pe;
	struct sockaddr_in addr;
	int sockin;
	int flags;

	DPRINT(("sbdserv_create: creating my socket\n"));
	pe = getprotobyname("tcp");
	if (!pe) {
		DPRINT(("sbdserv_create: unknown protocol:TCP\n"));
		return NULL;
	}
	if ((sockin = socket(AF_INET, SOCK_STREAM, pe->p_proto)) == -1) {
		DPRINT(("sbdserv_create: socket error:%d\n", errno));
		return NULL;
	}
	flags = fcntl(sockin, F_GETFL, 0);
	if ((-1 == flags)
	||  (-1 == fcntl(sockin, F_SETFL, (flags | O_NONBLOCK)))) {
		DPRINT(("sbdserv_create: fcntl(sock:%d) error:%d\n", sockin, errno));
		return NULL;
	}

	DPRINT(("sbdserv_create: binding socket:%d\n", sockin));
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET; 
	addr.sin_port = htons(port); 
	addr.sin_addr.s_addr = htons(INADDR_ANY); 
	if (bind(sockin, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		DPRINT(("sbdserv_create: bind error:%d\n", errno));
		return NULL;
	}

	DPRINT(("sbdserv_create: starting listen\n"));
	if (listen(sockin, 10) < 0) {
		DPRINT(("sbdserv_create: listen error:%d\n", errno));
		return NULL;
	}

	sbdserv = (sbdserv_t *)malloc(sizeof(sbdserv_t));
	if (!sbdserv)
		return NULL;
	sbdserv->conns = assoctab_create(sizeof(sbdserv_conn_t));
	if (!sbdserv->conns) {
		free(sbdserv);
		return NULL;
	}
	FD_ZERO(&sbdserv->fds);
	sbdserv->sockin = sockin;
	sbdserv->sockmax = sbdserv->sockin;
	sbdserv->cursock = 0;
	sbdserv->nsocks = 0;
	sbdserv->t_last_poll = now;
	return sbdserv;
}
Ejemplo n.º 6
0
/*-------------------------------------------------------------------------
 Check for network packets and handle them.
 Sets globals qq_src and su_src if/when qq or su packet received.
-------------------------------------------------------------------------*/
void poll_test(dpio_t *dpio, dptab_t *tab)
{
	dp_result_t err;
	playerHdl_t src;
	size_t size;
	char pkt[dpio_MAXLEN_UNRELIABLE];

	err = dptab_update(tab);
	assert(err == dp_RES_OK || err == dp_RES_EMPTY);

	dpio_now = eclock();
	err = dpio_update(dpio);
	if (err != dp_RES_OK && err != dp_RES_EMPTY) {
		printf("dpio_update reports error %d\n", err);
		assert(FALSE);
	}
	/*printf("%1d", results.thisHost);*/
	//src = (dpid_t) PLAYER_NONE;	/* kludge */
	size = sizeof(pkt);
	err = dpio_get(dpio, &src, &pkt, &size, NULL);
	if (err != dp_RES_OK && err != dp_RES_EMPTY && err != dp_RES_AGAIN) {
		printf("dpio_get reports error %d\n", err);
		assert(FALSE);
	}
	if (err == dp_RES_OK) {
		/*printf("Got packet from handle %x\n", src);*/
		switch (*(dp_packetType_t *)pkt) {
			case PKT_IT:
				it_src = src;
				it_num = pkt[sizeof(dp_packetType_t)];
				printf("Node %d: Got it=%d packet from source h:%x\n", results.thisHost, it_num, src);
				break;
			case PKT_SU:
				su_src = src;
				printf("Node %d: Got su packet from source h:%x\n", results.thisHost, src);
				break;
			case PKT_QQ:
				qq_src = src;
				printf("Got qq packet from source h:%x\n", src);
				break;
			default:
				err = dptab_handlePacket(tab, src, size, pkt);
				if (err != dp_RES_OK && err != dp_RES_EMPTY) {
					printf("dptab_handlePacket reports error %d\n", err);
					fflush(stdout);
					assert(FALSE);
				}
				break;
		}
	}
}
Ejemplo n.º 7
0
int main(int argc, char **argv)
{
	sbdclnt_t *sbdclnt;
	int port;
	int clicked;
	clock_t timeout;
	aeh_t aeh;
	int ninst;
	char comments[sendcrsh_COMMENT_MAXLEN];
	int len, lensent;
	char buf[sbd_MAXLEN];
	int pos;
	unsigned long crc;
	char signature[10];
	int i = 0;

	logprint_setFile("sendcrsh.log");

	if (!checkEnvironment()) {
		DPRINT(("anet2.dll did not set our environment!\n"));
		return 1;
	}
	if (!checkUnique()) {
		DPRINT(("Another instance of sendcrsh was running!\n"));
		return 1;
	}

	if (argc <= 3) { /* Usage: sendcrsh <host> <port> <hexdata> */
		DPRINT(("sendcrsh invoked with fewer than 3 arguments\n"));
		return 1;
	}
	DPRINT(("%s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]));

	port = atoi(argv[2]);
	if ((port < 1024) || (port > 65536)) {
		DPRINT(("sendcrsh invoked with invalid port %d\n", port));
		return 1;
	}

	if (NULL == hex2buf(argv[3], buf, 2)) {
		DPRINT(("hex2buf(datalen) failed\n"));
		return 1;
	}
	len = dpMAKESHORT(buf[0], buf[1]);
	if (NULL == hex2buf(argv[3] + 4, buf, len)) {
		DPRINT(("hex2buf(data) failed\n"));
		return 1;
	}
	if (argv[3][4 + 2*len] != '\0') {
		DPRINT(("data does not end at datalen:%d\n", len));
		return 1;
	}
	if (len > sbd_MAXLEN) {
		DPRINT(("datalen:%d is greater than max:%d\n", len, sbd_MAXLEN));
		return 1;
	}
	pos = getLastRecord(buf, len, &aeh, &ninst);
	if (pos == -1) {
		DPRINT(("getLastRecord failed\n"));
		return 1;
	}
	if (aeh.nstk == 0) {
		DPRINT(("exception has 0 length stack trace\n"));
	}
	crc = aeh_getSignature(&aeh);
	if (crc == 0) {
		DPRINT(("aeh_getSignature returns 0 crc, error?\n"));
	}
	aeh_signature_toString(crc, signature);

	DPRINT(("%s to %s:%d len:%d data:%s\n", argv[0], argv[1], port, len,
		argv[3] + 4));
	sendbox_create(winCmdShow, signature, sendcrsh_COMMENT_MAXLEN, 120);
	while (1) {
		clock_t now = eclock();

		clicked = sendbox_poll(comments);
		if (clicked != sendbox_CLICKED_NONE) {
			DPRINT(("t:%d, clicked:%d, breaking\n", now, clicked));
			break;
		}
		Sleep(100);
		if (!((++i)%10)) {
			DPRINT(("%dth call to sendbox_poll at t:%d\n", i, now));
		}
	}
	sendbox_destroy();

	if (clicked != sendbox_CLICKED_OK) {
		DPRINT(("User cancelled send, clicked:%d\n", clicked));
		return 0;
	}

	timeout = eclock() + 30 * ECLOCKS_PER_SEC;
	/* add the comments to the buffer */
	if (comments[0]) {
		aeh_buf_t aehbuf;
		int commentlen = strlen(comments);
		int nwritten;

		if ((len + sizeof(unsigned int /* aeh_info_t.id */) + sizeof(commentlen) + commentlen) > sbd_MAXLEN) {
			DPRINT(("no room in buf for comment\n"));
			return 1;
		}
		/* stuff the comment into the info list */
		if (aeh_RES_OK != aeh_addComment(&aeh, comments)) {
			DPRINT(("aeh_addComment failed\n"));
			return 1;
		}
		/* convert it back to a buf */
		if (aeh_RES_OK != aeh_writeOutputStream(&aeh, &aehbuf)) {
			DPRINT(("can't convert aeh back to aehbuf\n"));
			return 1;
		}
		DPRINT(("writing new record at pos:%d buf:\n", pos));
		dumpbuf(aehbuf.buf, aehbuf.buflen);
		nwritten = aehlog_writetobuf(&aehbuf, ninst, buf+pos, sbd_MAXLEN-pos);
		if (-1 == nwritten) {
			DPRINT(("can't convert aehbuf back to buf\n"));
			return 1;
		}
		len = pos + nwritten;
	}
	aeh_Destroy(&aeh);

	/* send the buffer */
	sbdclnt = sbdclnt_create(buf, len, argv[1], (unsigned short)port);
	if (sbdclnt == NULL) {
		DPRINT(("sbdclnt_create failed\n"));
		return 1;
	}
	while ((long)(eclock() - timeout) < 0) {
		lensent = sbdclnt_poll(sbdclnt);
		if (lensent != 0)
			break;
		Sleep(100);
	}
	sbdclnt_destroy(sbdclnt);
	if (lensent != len) {
		DPRINT(("send only %d of %d bytes!\n", lensent, len));
		return 1;
	}
	DPRINT(("send completed successfully\n"));
	return 0;
}
Ejemplo n.º 8
0
/*------------------------------------------------------------------------
 Create an instance of the bhttp module, listening on port for new
 connections.
------------------------------------------------------------------------*/
bhttp_t *bhttp_create(unsigned short port, bhttp_url2buf_t url2buf_cb, void *url2buf_context)
{
	clock_t now = eclock();
	bhttp_t *bhttp;
	struct protoent *pe;
	struct sockaddr_in addr;
	int sockin;
	int flags;

	if (!url2buf_cb)
		return NULL;
	DPRINT(("bhttp_create: creating my socket\n"));
	pe = getprotobyname("tcp");
	if (!pe) {
		DPRINT(("bhttp_create: unknown protocol:TCP\n"));
		return NULL;
	}
	if ((sockin = socket(AF_INET, SOCK_STREAM, pe->p_proto)) == -1) {
		DPRINT(("bhttp_create: socket error:%d\n", errno));
		return NULL;
	}
	flags = fcntl(sockin, F_GETFL, 0);
	if ((-1 == flags)
	||  (-1 == fcntl(sockin, F_SETFL, (flags | O_NONBLOCK)))) {
		DPRINT(("bhttp_create: fcntl(sock:%d) error:%d\n", sockin, errno));
		return NULL;
	}

	DPRINT(("bhttp_create: binding socket:%d\n", sockin));
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = htons(INADDR_ANY);
	if (bind(sockin, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		DPRINT(("bhttp_create: bind error:%d\n", errno));
		return NULL;
	}

	DPRINT(("bhttp_create: starting listen\n"));
	if (listen(sockin, 10) < 0) {
		DPRINT(("bhttp_create: listen error:%d\n", errno));
		return NULL;
	}

	bhttp = (bhttp_t *)malloc(sizeof(bhttp_t));
	if (!bhttp)
		return NULL;
	bhttp->conns = assoctab_create(sizeof(bhttp_conn_t));
	if (!bhttp->conns) {
		free(bhttp);
		return NULL;
	}
	FD_ZERO(&bhttp->rfds);
	FD_ZERO(&bhttp->wfds);
	bhttp->sockin = sockin;
	bhttp->sockmax = bhttp->sockin;
	bhttp->cursock = 0;
	bhttp->nsocks = 0;
	bhttp->t_last_poll = now;
	bhttp->url2buf_cb = url2buf_cb;
	bhttp->url2buf_context = url2buf_context;
	return bhttp;
}
Ejemplo n.º 9
0
/*------------------------------------------------------------------------
 Handle any new connections, data, or handle state changes.
 rfds and wfds should be the same fd_set*'s that were passed to select
 as it's second and third parameters.
 nsocks is the return value of select.

 Call this once after each select, regardless of whether select times out.

 Returns 0 upon success.
 Returns -1 on error; detailed error message is printed to log file if
 this is a debug build.
------------------------------------------------------------------------*/
int bhttp_poll(bhttp_t *bhttp, fd_set *rfds, fd_set *wfds, int nsocks)
{
	clock_t now;
	int sock;
	int i;

	if (!bhttp || !bhttp->conns)
		return -1;
	bhttp_assertValid(bhttp);
	assert(nsocks >= 0);
	bhttp->cursock = 0;	/* FIXME: should be min(socks) */
	bhttp->nsocks = nsocks;
	if (FD_ISSET(bhttp->sockin, rfds) && (bhttp->nsocks > 0)) {
		int newsock;
		struct sockaddr_in client_addr;
		int len = sizeof(struct sockaddr_in);

		newsock = accept(bhttp->sockin, (struct sockaddr *)&client_addr,&len);
		if (newsock == -1) {
			DPRINT(("bhttp_poll: accept error:%d on sock:%d\n", errno, bhttp->sockin));
		} else {
			int flags;

#ifdef VERBOSE
			DPRINT(("bhttp_poll: accepting connection from %s on sock:%d\n", inet_ntoa(client_addr.sin_addr), newsock));
#endif
			flags = fcntl(newsock, F_GETFL, 0);
			if ((-1 == flags)
			||  (-1 == fcntl(newsock, F_SETFL, (flags | O_NONBLOCK)))) {
				DPRINT(("bhttp_poll: fcntl error:%d on sock:%d\n", errno, newsock));
				close(newsock);
				return -1;
			} else if (-1 == bhttp_handleOpened(bhttp, newsock)) {
				DPRINT(("bhttp_poll: can't add h:%d\n", newsock));
				close(newsock);
				return -1;
			}
		}
		bhttp->nsocks--;
	}

	while ((bhttp->cursock <= bhttp->sockmax) && (bhttp->nsocks > 0)) {
		int used = FALSE;
		int len;
		int h = bhttp->cursock;
		bhttp_conn_t *pc = NULL;

		if (FD_ISSET(h, rfds)
		&&  FD_ISSET(h, &bhttp->rfds)) {

			pc = (bhttp_conn_t *)assoctab_subscript(bhttp->conns, h);
			if (!pc) {
				DPRINT(("bhttp_poll: no such handle h:%d\n", h));
				return -1;
			}
			len = bhttp_readData(pc, h);
			if (len == -1) {
				DPRINT(("bhttp_readData error\n"));
				bhttp_handleClosed(bhttp, h);
				close(h);
				/* silently fails */
			} else if (len > 0) {
				char buf[1024];
				int buflen;
				bhttp_url2buf_result_t urlResult;
#ifdef VERBOSE
				DPRINT(("bhttp_poll: h:%d finished receiving data\n", h));
#endif
				memset(&urlResult, 0, sizeof(urlResult));
				buflen = bhttp->url2buf_cb(bhttp->url2buf_context, pc->purl, buf, sizeof(buf), &urlResult);
				buf[buflen] = 0;
				/* Finished reading http header, formulate http response */
				bhttp_formatOutputBuffer(bhttp, h, urlResult.httpResultCode, urlResult.mimeType, buf);
				FD_SET(h, &bhttp->wfds);
			} else {
#ifdef VERBOSE
				DPRINT(("bhttp_poll: h:%d waiting for more data\n", h));
#endif
			}
			used = TRUE;
		}
		if (FD_ISSET(h, wfds)
		&&  FD_ISSET(h, &bhttp->wfds)) {
			if (!pc) pc = (bhttp_conn_t *)assoctab_subscript(bhttp->conns, h);
			if (!pc) {
				DPRINT(("bhttp_poll: no such handle h:%d\n", h));
				return -1;
			}
			len = bhttp_writeData(pc, h);
			if (len == -1) {
				DPRINT(("bhttp_writeData error\n"));
				bhttp_handleClosed(bhttp, h);
				close(h);
				/* silently fails */
			} else if (len > 0) {
#ifdef VERBOSE
				DPRINT(("bhttp_poll: h:%d finished sending data\n", h));
#endif
				bhttp_handleClosed(bhttp, h);
				if (-1 == close(h)) {
					DPRINT(("bhttp_poll: close error:%d\n", errno));
				}
			} else {
#ifdef VERBOSE
				DPRINT(("bhttp_poll: h:%d waiting for more data\n", h));
#endif
			}
			used = TRUE;
		}
		if (used)
			bhttp->nsocks--;
		bhttp->cursock++;
	}

	now = eclock();
	if ((long)(now - bhttp->t_last_poll) < 10 * ECLOCKS_PER_SEC)
		return 0;	/* don't poll more than once every 10s */
	bhttp->t_last_poll = now;
#ifdef VERBOSE
	DPRINT(("bhttp_poll: t:%d checking %d conns for timeouts\n", now, bhttp->conns->n_used));
#endif

	/* Iterate through handles, deleting those that have timed out,
	 * in reverse order, since deleting will change indices of later entries.
	 */
	for (i = bhttp->conns->n_used - 1; i >= 0; i--) {
		assoctab_item_t *pi;
		bhttp_conn_t *pc;
		int h;
 		pi = assoctab_getkey(bhttp->conns, i);
		if (!pi) {
			DPRINT(("bhttp_poll: assoctab_getkey(%d) returns NULL?\n", i));
			return -1;
		}
		h = pi->key;
		pc = (bhttp_conn_t *)pi->value;
		if (!pc) {
			DPRINT(("bhttp_poll: conns[%d] == NULL?\n", i));
			return -1;
		}
		if ((long)(now - pc->t_connect) > bhttp_CONN_TIMEOUT * ECLOCKS_PER_SEC) {
			DPRINT(("bhttp_poll: h:%d timed out\n", h));
			bhttp_handleClosed(bhttp, h);
			if (-1 == close(h)) {
				DPRINT(("bhttp_poll: close(%d) error:%d\n", h, errno));
				return -1;
			}
		}
	}
	return 0;
}
Ejemplo n.º 10
0
main(int argc, char **argv)
{
    dp_t *mydp;
    dp_transport_t theTransport;
    dp_result_t err;
    clock_t started;
    char *logfname;
    char *drivername;

    if (argc == 4) {
        masterServerHostname = argv[2];
        printf("We are a slave server.\n");
    } else if (argc == 3) {
        masterServerHostname = NULL;
        printf("We are a master server.\n");
    } else {
        printf("Usage: dp2t2 driver logfname [masterservername]\n");
        exit(1);
    }
    drivername = argv[1];
    logfname = argv[2];
    dp_setLogFname(logfname);

    memset(&theTransport, 0, sizeof(theTransport));
    strcpy(theTransport.fname, drivername);
    err = dpCreate(&mydp, &theTransport, NULL, NULL);
    if (err != dp_RES_OK) {
        printf("Can't create dp, err:%d\n", err);
        exit(1);
    }

    /* If we're not the master game server, log our server in as a client
     * of it.
     */
    if (masterServerHostname) {
        printf("Logging in to master game server %s\n", masterServerHostname);
        err = dpSetGameServer(mydp, masterServerHostname);
        assert(err == dp_RES_OK);
    }

    /* Whenever a variable comes in, print it. */
    dptab_setTableCallback(mydp->mysessions, print_cb, NULL);
    dptab_setTableCallback(mydp->sessions, print_cb, NULL);

    /* Wait for login requests.  If the request is ok,
     * add a subscription for the sessions table.
     */
    started = eclock();
    while ((long)(eclock() - started) < (40 * ECLOCKS_PER_SEC)) {
        dpid_t idTo;
        char pkt[512];
        size_t size;
        playerHdl_t src;

        /* Set flags so sender's address is a playerHdl_t, not a dpid_t */
        size = sizeof(pkt);
        err = dpReceive(mydp, (dpid_t *)&src, &idTo, 1, &pkt, &size);
        assert ((err == dp_RES_EMPTY) || (err == dp_RES_OK));
        if (err == dp_RES_OK) {
            dp_packetType_t id = *(short *)pkt;
            switch (id) {
            case dppt_MAKE('e','1'):
                printf("server: Got add request from h:%x.\n", src);
                addClient(mydp, src);
                /* Note: dp will call deletePeer automatically if hdl closes */
                break;
            default:
                ;
            }
        }
        if (raw_kbhit()) {
            raw_getc();
            printf("Disconnecting from upper server at user request\n");
            DPRINT(("Disconnecting from upper server at user request\n"));
            /* disconnect from the game server abruptly. */
            dpSetGameServer(mydp, NULL);
        }
    }

    err = dpDestroy(mydp, 0);
    assert(err == dp_RES_OK);

    printf("No test failed.\n");

    return 0;
}
Ejemplo n.º 11
0
/*------------------------------------------------------------------------
 Handle any new connections, data, or handle state changes.
 rfds should be the same fd_set* that was passed to select as it's 
 second parameter.

 After a select (and regardless of whether select times out), call this
 repeatedly until it returns no data or an error. 

 Returns the length of data received if any, and returns the data in buf.
 		The caller should call sbdserv_poll again, since multiple handles
		might have data.
 Returns 0 if no data is available now.
 Returns -1 on error.
------------------------------------------------------------------------*/
int sbdserv_poll(sbdserv_t *sbdserv, fd_set *rfds, char *buf)
{
	clock_t now;
	int sock;
	int i;

	if (!sbdserv || !sbdserv->conns || !buf)
		return -1;
	sbdserv_assertValid(sbdserv);
	if (FD_ISSET(sbdserv->sockin, rfds) && (sbdserv->nsocks > 0)) {
		int newsock;
		struct sockaddr_in client_addr;
		int len = sizeof(struct sockaddr_in);

		newsock = accept(sbdserv->sockin, (struct sockaddr *)&client_addr,&len);
		if (newsock == -1) {
			DPRINT(("sbdserv_poll: accept error:%d on sock:%d\n", errno, sbdserv->sockin));
		} else {
			int flags;

#ifdef VERBOSE
			DPRINT(("sbdserv_poll: accepting connection from %s on sock:%d\n", inet_ntoa(client_addr.sin_addr), newsock));
#endif
			flags = fcntl(newsock, F_GETFL, 0);
			if ((-1 == flags)
			||  (-1 == fcntl(newsock, F_SETFL, (flags | O_NONBLOCK)))) {
				DPRINT(("sbdserv_poll: fcntl error:%d on sock:%d\n", errno, newsock));
				close(newsock);
				return -1;
			} else if (-1 == sbdserv_handleOpened(sbdserv, newsock)) {
				DPRINT(("sbdserv_poll: can't add h:%d\n", newsock));
				close(newsock);
				return -1;
			}
		}
		sbdserv->nsocks--;
	}

	while ((sbdserv->cursock <= sbdserv->sockmax) && (sbdserv->nsocks > 0)) {
		if (FD_ISSET(sbdserv->cursock, rfds)
		&&  FD_ISSET(sbdserv->cursock, &sbdserv->fds)) {
			char *bufp = NULL;
			int len;

			len = sbdserv_readData(sbdserv, sbdserv->cursock, &bufp);
			if (len == -1) {
				DPRINT(("sbdserv_readData error\n"));
				sbdserv_handleClosed(sbdserv, sbdserv->cursock);
				close(sbdserv->cursock);
				/* silently fails */
			} else if (len > 0) {
#ifdef VERBOSE
				DPRINT(("sbdserv_poll: h:%d finished sending data\n", sbdserv->cursock)); 
#endif
				/* must return copy, since closing will destroy original */
				memcpy(buf, bufp, len);
				sbdserv_handleClosed(sbdserv, sbdserv->cursock);
				if (-1 == close(sbdserv->cursock)) {
					DPRINT(("sbdserv_poll: close error:%d\n", errno));
				}
				sbdserv->nsocks--;
				sbdserv->cursock++;
				return len;
			} else {
#ifdef VERBOSE
				DPRINT(("sbdserv_poll: h:%d waiting for more data\n", sbdserv->cursock));
#endif
			}
			sbdserv->nsocks--;
		}
		sbdserv->cursock++;
	}

	now = eclock();
	if ((long)(now - sbdserv->t_last_poll) < 10 * ECLOCKS_PER_SEC)
		return 0;	/* don't poll more than once every 10s */
	sbdserv->t_last_poll = now;
#ifdef VERBOSE
	DPRINT(("sbdserv_poll: t:%d checking %d conns for timeouts\n", now, sbdserv->conns->n_used));
#endif

	/* Iterate through handles, deleting those that have timed out,
	 * in reverse order, since deleting will change indices of later entries.
	 */
	for (i = sbdserv->conns->n_used - 1; i >= 0; i--) {
		assoctab_item_t *pi;
		sbdserv_conn_t *pc;
		int h;
 		pi = assoctab_getkey(sbdserv->conns, i);
		if (!pi) {
			DPRINT(("sbdserv_poll: assoctab_getkey(%d) returns NULL?\n", i));
			return -1;
		}
		h = pi->key;
		pc = (sbdserv_conn_t *)pi->value;	
		if (!pc) {
			DPRINT(("sbdserv_poll: conns[%d] == NULL?\n", i));
			return -1;
		}
		if ((long)(now - pc->t_connect) > sbdserv_CONN_TIMEOUT * ECLOCKS_PER_SEC) {
			DPRINT(("sbdserv_poll: h:%d timed out\n", h));
			sbdserv_handleClosed(sbdserv, h);
			if (-1 == close(h)) {
				DPRINT(("sbdserv_poll: close(%d) error:%d\n", h, errno));
				return -1;
			}
		}
	}
	return 0;
}
Ejemplo n.º 12
0
/*--------------------------------------------------------------------------
 Call this once before the server has initialized dp.
 Downloads the password database from the account server, which could
 potentially take a while to finish.
 Returns the socket used by servpw or -1 on error.
--------------------------------------------------------------------------*/
int servpw_init(const char *wmqDirectory, const char *PWServerAddr,
	int PWServerPort, const char *PWFile)
{
	dp_result_t err;
	int prevDBprogress = 0;
	char temppath[256];
	clock_t now = eclock();

	if (!wmqDirectory || !PWServerAddr || !PWFile) {
		printf("servpw_init: NULL parameter\n");
		return -1;
	}

	strncpy(url.host, PWServerAddr, antpget_URL_MAXLEN);
	url.host[antpget_URL_MAXLEN-1] = '\0';
	url.port = PWServerPort;
	strncpy(url.path, PWFile, antpget_URL_MAXLEN);
	url.path[antpget_URL_MAXLEN-1] = '\0';
	strncpy(localdir, wmqDirectory, 256);
	localdir[255] = '\0';

	antpget = antpget_create();
	if (!antpget) {
		printf("servpw_init: out of memory!\n");
		return -1;
	}
	sock = antpget_setHost(antpget, url.host, url.port);
	if (sock < 0) {
		printf("servpw_init: can't bind socket.\n");
		return -1;
	}
	retries = 0;
	next_retry = now;
	state = STATE_DISCONNECTED;
	bGotDB = 0;
	DBprogress = 0;
	sprintf(temppath, "%s/%s", localdir, url.path);
	if ((localfp = fopen(temppath, "wb")) == NULL) {
		printf("servpw_init: can't write to %s\n", temppath);
		return -1;
	}

	/* get the database file */
	printf("Downloading %s from %s:%d -\n", url.path, url.host, url.port);
	while (!bGotDB) {
		err = servpw_poll(now);
		if (err == dp_RES_OK) {
			for (; prevDBprogress < DBprogress; prevDBprogress++)
				printf(".");
			continue;
		} else if (err == dp_RES_AGAIN) {
			sleep(5);
			continue;
		} else if (err == dp_RES_EMPTY) {
			if (!bGotDB) {
				printf("\nservpw_init: account server: no file %s\n", url.path);
				return -1;
			}
		} else if (err == dp_RES_HOST_NOT_RESPONDING) {
			printf("\nservpw_init: Lost connection to account server!\n");
			return -1;
		} else {
			printf("\nservpw_init: antpget_poll err:%d\n", err);
			return -1;
		}
	}
	printf("done\n");
	return sock;
}
Ejemplo n.º 13
0
/*------------------------------------------------------------------------
 Prints out info gathered during timing calls to file.  If file is NULL,
  writes to "ptimer.log".  Should be called after finished with all timing
  calls.
------------------------------------------------------------------------*/
void ptimer_dumpToFile(char *file)
{
	FILE *fp;
	clock_t now;
	__int64 starttime, endtime, rdtsc_per_sec;
	ptimer_disableInterrupt();
	now = eclock();
	starttime = rdtsc();
	/* the following is kludgy; for more accuracy, make the time cycle longer */
	while ((long)(eclock() - now) < ECLOCKS_PER_SEC)
		;
	endtime = rdtsc();
	rdtsc_per_sec = endtime - starttime;
	if (!file)
		file = "ptimer.log";
	fp = fopen(file, "w");
	if (fp) {
		int i, j;
		fprintf(fp, "ticks per sec: %d\n", rdtsc_per_sec);
		for (i = 0; i < NPMAX; i++) {
			if (ptimer_data[i].desc)
				fprintf(fp, "%s:\n", ptimer_data[i].desc);
			else
				continue;
			for (j = 0; j < NPSUBMAX; j++) {
				if (ptimer_data[i].stat[j].n) {
					fprintf(fp, " element %d:\n", j);
					fprintf(fp, "  #times:%7d  avg time(us):%13.3f  max time(us):%13.3f\n",
							ptimer_data[i].stat[j].n, ((float)ptimer_data[i].stat[j].sum * 1000000) / (ptimer_data[i].stat[j].n * (float)rdtsc_per_sec), ((float)ptimer_data[i].stat[j].max * 1000000) / rdtsc_per_sec);
				}
			}
		}
	}
#if 0 /* time ptimer calls */
	{
		int i;
		for (i=0; i<100; i++) {
			ptimer_Enter(0, "foo");
			ptimer_Exit(0, i);
		}
	}
	{
	__int64 difftime;
	starttime = rdtsc();
	endtime = rdtsc();
	endtime = rdtsc();
	difftime = endtime - starttime;
	fprintf(fp, "time for rdtsc call: %I64d ticks %10.3f us\n", difftime, ((float)difftime * 1000000) / rdtsc_per_sec);
	ptimer_zeroAll();
	starttime = rdtsc();
	ptimer_Enter(0, "dummy call");
	ptimer_Exit(0, 0); 
	endtime = rdtsc();
	difftime = endtime - starttime;
	fprintf(fp, "time for firsttime ptimer enter/exit call: %I64d ticks %10.3f us\n", difftime, ((float)difftime * 1000000) / rdtsc_per_sec);
	starttime = rdtsc();
	ptimer_Enter(0, "dummy call");
	ptimer_Exit(0, 0); 
	endtime = rdtsc();
	difftime = endtime - starttime;
	fprintf(fp, "time for secondtime ptimer enter/exit call: %I64d ticks %10.3f us\n", difftime, ((float)difftime * 1000000) / rdtsc_per_sec);
	ptimer_zeroAll();
	starttime = rdtsc();
	ptimer_Enter(0, "dummy call");
	endtime = rdtsc();
	difftime = endtime - starttime;
	fprintf(fp, "time for firsttime ptimer_Enter call: %I64d ticks %10.3f us\n", difftime, ((float)difftime * 1000000) / rdtsc_per_sec);
	starttime = rdtsc();
	ptimer_Exit(0, 0); 
	endtime = rdtsc();
	difftime = endtime - starttime;
	fprintf(fp, "time for firsttime ptimer_Exit call: %I64d ticks %10.3f us\n", difftime, ((float)difftime * 1000000) / rdtsc_per_sec);
	starttime = rdtsc();
	ptimer_Enter(0, "dummy call");
	endtime = rdtsc();
	difftime = endtime - starttime;
	fprintf(fp, "time for secondtime ptimer_Enter call: %I64d ticks %10.3f us\n", difftime, ((float)difftime * 1000000) / rdtsc_per_sec);
	starttime = rdtsc();
	ptimer_Exit(0, 0); 
	endtime = rdtsc();
	difftime = endtime - starttime;
	fprintf(fp, "time for secondtime ptimer_Exit call: %I64d ticks %10.3f us\n", difftime, ((float)difftime * 1000000) / rdtsc_per_sec);
	}
#endif
	fclose(fp);
}
Ejemplo n.º 14
0
int main(int argc, char **argv)
{
	int exitCode = 0;
	dp_t *myDP;
	dp_result_t err;
	char freezefile[100];
	char kbuf[MAX_MESSAGE] = "";
	clock_t tstart = 0;
	clock_t tfinish = 0;
	int setkey;			/* last variable set */
	int sendkey;		/* last variable sent */
	int vars_received;
	
	if (argc < 2) {
		strcpy(freezefile, "freeze.dat");
	} else {
		strcpy(freezefile, *(argv + 1));
	}
	err = dpCreate(&myDP, NULL, NULL, freezefile);
	if (err != dp_RES_OK) {
		printf("pvtest: error %d thawing %s.\n", err, freezefile);
		exit(1);
	}
		
	chat_welcome(myDP);
	setkey = 0; 
	vars_received = 0;

	raw_init();
	while(1) {			/* input and receive loop */
		dpid_t idFrom;
		dpid_t idTo;
		struct {
			dp_packetType_t type PACK;
			union {
				dp_user_addPlayer_packet_t addPlayer;
				dp_user_delPlayer_packet_t delPlayer;
				unsigned char buf[dpio_MAXLEN_UNRELIABLE];
			} u PACK;
		} pkt;
		size_t pktsize;
		clock_t twait;

		if (tstart != 0) {
			/* kludge --- wait twait for player delete before quit */
			tfinish = eclock();
			if (twait < tfinish - tstart) break;
		}
		if (setkey < NUMVARS) {
			pvtest_t v;
			setkey++;
			v.key = setkey;
			v.from = my_Player[0];
			err = dpSetPlayerData(myDP, v.from, v.key, &v, sizeof(v), 0);
			if (err != dp_RES_OK) {
				printf("pvtest: error %d setting var %d\n", err, v.key);
				exit(1);
			}
			sendkey = setkey;
		}
		if (raw_kbhit()) {
			int len = strlen(kbuf);
			int ch = 0;
			if (len >= MAX_MESSAGE) {
				printf("\npvtest: Message too long. Truncating and sending.\n");
				err = chat_broadcast(myDP, kbuf);
				if (err != dp_RES_OK) {
					printf("pvtest: error %d sending message.\n", err);
				}
				kbuf[0] = '\0';
				continue;
			}
			ch = raw_getc();
			if (ch == -1) {
				/* guess kbhit was wrong */
				continue;
			}
			if (ch == 4 || ch == 17) {		/* ^D, ^Q */
				int i;
				if (my_Player[0] == lowestId) {
					twait = HOST_WAIT * ECLOCKS_PER_SEC;
				} else {
					twait = CLIENT_WAIT * ECLOCKS_PER_SEC;
				}
				printf("\nquitting .... \n");
				DPRINT(("pvtest: got quit request; deleting local players.\n"));
				for (i = 0; i < my_nPlayer; i++) {
					dpDestroyPlayer(myDP, my_Player[i]);
				}
				tstart = eclock();
				if (ch == 17) {
					exitCode = 1;			/* if stub exists, tell it to die */
				}
				continue;
			}
			if (ch == 'a' || ch == 'A') {	/* add another player variable and send it */
				pvtest_t v;
				setkey++;
				v.key = setkey;
				v.from = my_Player[0];
				err = dpSetPlayerData(myDP, v.from, v.key, &v, sizeof(v), 0);
				if (err != dp_RES_OK) {
					printf("pvtest: error %d setting var %d\n", err, v.key);
					exit(1);
				}
				sendkey = setkey;
			}
			if (ch == 'b' || ch == 'B') {	/* add another player variable but don't send it yet*/
				pvtest_t v;
				setkey++;
				v.key = setkey;
				v.from = my_Player[0];
				err = dpSetPlayerData(myDP, v.from, v.key, &v, sizeof(v), dp_PLAYERDATA_FLAG_NOFLOOD);
				if (err != dp_RES_OK) {
					printf("pvtest: error %d setting var %d\n", err, v.key);
					exit(1);
				}
			}
			if (ch == 'c' || ch == 'C') {	/* send next unsent variable */
				if (sendkey < setkey) {
					sendkey++;
					printf("pvtest: sending variable %d\n", sendkey);
					err = dpSendPlayerData(myDP, my_Player[0], sendkey, dp_ID_BROADCAST);
					if (err != dp_RES_OK) {
						printf("pvtest: error %d sending var %d\n", err, sendkey);
						exit(1);
					}
				}
			}

			putchar(ch);
			fflush(stdout);
			if (ch == '\r') {					/* ^M */
				putchar('\n');
			}
			if (ch == 8) {						/* BSp */
				if (len > 0)
					kbuf[len-1] = 0;
				continue;
			}
			if (ch != '\r' && ch != '\n') {
				/* Append to buffer. */
				kbuf[len++] = ch;
				kbuf[len] = 0;
				continue;
			}
			/* Process the keyboard buffer. */
			if (!kbuf[0])
				continue;
	
			err = chat_broadcast(myDP, kbuf);
			if (err != dp_RES_OK) {
				printf("pvtest: error %d sending message.\n", err);
			}
	
			/* Empty it. */
			kbuf[0] = 0;
		}

		/* Receive and process packets */
		pktsize = sizeof(pkt);
		err = dpReceive(myDP, &idFrom, &idTo, 0, &pkt, &pktsize);
		if (err != dp_RES_OK && err != dp_RES_EMPTY) {
			printf("pvtest: error %d receiving packet.\n", err);
			continue;
		}
		if (err == dp_RES_EMPTY) continue;
		switch (pkt.type) {
		case dp_USER_ADDPLAYER_PACKET_ID:
			printf("pvtest: Player %s joining.\n", pkt.u.addPlayer.name);
			break;
		case dp_USER_DELPLAYER_PACKET_ID:
			printf("pvtest: Player %s exiting.\n", pkt.u.delPlayer.name);
			break;
		case dp_USER_HOST_PACKET_ID:
			printf("pvtest: Host is dead. You are now host.\n");
			break;
		case CHAT_PACKET_ID:
			{
			char nameBuf[256];
			size_t size;
			err = dpGetPlayerName(myDP, idFrom, nameBuf, sizeof(nameBuf));
			if (err != dp_RES_OK) {
				printf("pvtest: chat packet from unknown id %d.\n", idFrom);
			}
			pkt.u.buf[pktsize-sizeof(dp_packetType_t)] = 0;	/* Null terminate */
			DPRINT(("%s: %s\n", nameBuf, (char *)pkt.u.buf));
			printf("%s: %s\n", nameBuf, (char *)pkt.u.buf);
			break;
			}
		case dp_SESSIONLOST_PACKET_ID:
			printf("Sorry session lost, you might as well quit\n");
			break;
		case dp_USER_PLAYERDATA_PACKET_ID:
			{
				dp_user_playerData_packet_t *pv = (dp_user_playerData_packet_t *) pkt.u.buf;
				pvtest_t *p = (pvtest_t *) (pv->data);

				printf("New value for player %d's variable %d: len %d, p->from %d, p->key %d, vars received %d\n", pv->id, pv->key, pv->len, p->from, p->key, ++vars_received);
				DPRINT(("New value for player %d's variable %d: len %d, p->from %d, p->key %d, vars received %d\n", pv->id, pv->key, pv->len, p->from, p->key, vars_received));
				assert(pv->len == sizeof(pvtest_t));
				assert(pv->key == p->key);
				assert(pv->id == p->from);
			}
			break;
		default:
			break;
		}
	}
	quit(myDP, exitCode);
	return 1;
}
Ejemplo n.º 15
0
/*-------------------------------------------------------------------------
 Run a single copy of the test.
 Return value is 0 on success.

 If childnum is > 0, this is a slave; otherwise, this is the master.

 Does the following steps:
 1. Initialize dpio and dptab
 2. Create a table
 3. Establish connections.
	a. Open a handle to address and subscribe the table from that peer.
	   Master subscribes as table2, all else as standard table.
	b. Send an "SU" packet to address requesting peer to publish the table to us
 4. Wait for a "SU" packet.
 5. publish the table to whoever sent "SU" to us.
 Loop appropriate number of times, doing:
	 6. Master sends an "IT" packet to next. On receipt of an "IT" packet,
		slaves send an "IT" packet to next. Master waits for "IT" packet.
	    Watch for iteration number in the IT packet.  If this is the time,
		freeze the dpio and dptab, spawn a replacement, and exit using the
		replacement's exit code.
	 7. If childnum == 0, this child is the master:
		c. Set a value in the table.  Use a max hop count of N.
		d. Wait until value appears in table2 (watch the callback).
		e. Print out how long it took to get there.
 Once the correct number of loops is done,
 8. If childnum == 0: Send a QQ packet to next, wait for QQ packet.
    If childnum > 0: Wait until QQ packet recieved, send QQ to next.
 9. Exit.

 N must be 2 or greater.

 For example:

 If N == 2, the launcher executes:
	dptabt wloop.dll 0 2.0.0.0          (host 1 = master)
	dptabt wloop.dll 1 1.0.0.0          (host 2 = slave)
 the sequence of events is
    host step action
    h1   #4  waits for SU
	h2   #3  subscribes to 1 from h1, sends "SU" to h1, waits for "sU"
	h1   #5  Gets "SU", publishes table 1 to h2
	h1   #6  subscribe's h2's table 1 onto table 2, sends "SU" to h2
	h2   #5  Gets "SU", publishes table 1 to h1
 and the variable's trip around the ring looks like this:
    master -> slave -> master again
 The only reason it doesn't continue on to the slave is that the
 max hop count was set to 2.
 (Interestingly, if another host connects to the master's table,
  whether or not they get a copy of the variable depends on whether
  they connect before the variable comes around again (yes), or after (no).
  This is a good reason to never use rings like this in real systems!)

 If N == 4, the launcher executes:
	dptabt wloop.dll 0 2.0.0.0          (host 1 = master)
	dptabt wloop.dll 1 3.0.0.0          (host 2 = slave)
	dptabt wloop.dll 2 4.0.0.0          (host 3 = slave)
	dptabt wloop.dll 3 1.0.0.0          (host 4 = slave)
 the sequence of events is
    host step action
    h1   #4  waits for SU
	h2   #3  subscribes to 1 from next, sends "SU" to next, waits for "SU"
	h3   #3  subscribes to 1 from next, sends "SU" to next, waits for "SU"
	h4   #3  subscribes to 1 from next, sends "SU" to next, waits for "SU"
	h1   #5  Gets "SU" from prev, publishes table 1 to prev
	h1   #6  subscribe's next's table 1 onto table 2, sends "SU" to next
	h2   #5  Gets "SU" from prev, publishes table 1 to prev
	h3   #5  Gets "SU" from prev, publishes table 1 to prev
	h4   #5  Gets "SU" from prev, publishes table 1 to prev
 and the variable's trip around the ring looks like this:
    h1 -> h2 -> h3 -> h4 -> h1 again
-------------------------------------------------------------------------*/
int
run_one_node(
	int childNum,
	char *sNextAdr,
	int loopTotal,
	int endLoopAt)
{
	dptab_t *tab;
	dp_result_t err;
	char key[10];
	char subkey[10];
	dptab_table_t *table;
	dptab_table_t *table2;
	dpio_t *dpio;
	playerHdl_t dest;
	unsigned char adrBuf[dp_MAX_ADR_LEN];
	commInitReq_t commInitReq;
	commScanAddrReq_t		scanReq;
	commScanAddrResp_t		scanResp;
	dp_transport_t dll;
	char nbuf[dpio_MAXLEN_UNRELIABLE];
	char dplogname[200];

	char fname[256];
	int startLoopAt = 0;
	int i;

	/* Set a timeout of 30 seconds */
	signal(SIGTIMER, timer_handler);
	alarm(30);

	results.thisHost = childNum;

	sprintf(fname, LOGNAME, childNum);
	if(loopTotal < 1) {	/* thawing */
		assert ((logFile = fopen(fname, "a")) != NULL);
		fprintf(logFile, "--Thawing--\n");
	} else
		assert ((logFile = fopen(fname, "w")) != NULL);
	#ifdef WIN32
		srand(GetTickCount());
	#endif

	/* 1. Initialize dpio and dptab */
	dpio_now = eclock();
	if(loopTotal < 1) {	/* thawing */
		/* Find our file */
		FILE* thawFile;
		sprintf(fname, FREEZENAME, childNum);
		printf("Node %d: Thawing from file %s.\n", childNum, fname);
		thawFile = fopen(fname, "r");
		assert (thawFile != NULL);

		/* Read everything from our file */
		fread(&startLoopAt,sizeof(int),1,thawFile);
		fread(&loopTotal,sizeof(int),1,thawFile);
		fread(&it_num,sizeof(int),1,thawFile);
		fread(&(results.n_hosts),sizeof(int),1,thawFile);
		sprintf(dplogname, "dpt%d.%d.log", childNum, startLoopAt);
		dp_setLogFname(dplogname);

		err = dpio_create(&dpio, NULL, NULL, &dpio_now, thawFile);
		assert(err == dp_RES_OK);
		err = dpio_thawHdl(dpio, &dest, thawFile);
		assert(err == dp_RES_OK);

		tab = dptab_create(dpio);
		assert(tab);
		err = dptab_thaw(tab, thawFile);
		assert(err == dp_RES_OK);
		fclose(thawFile);

		/* Re-set any callbacks */
		key[0] = 1;
		table = dptab_getTable(tab, key, 1);
		assert(table != NULL);
		err = dptab_setTableCallback(table, table_cb, NULL);
		assert(err == dp_RES_OK);
		if(childNum == 0) {
			key[0] = 2;
			table2 = dptab_getTable(tab, key, 1);
			assert(table != NULL);
			err = dptab_setTableCallback(table2, table_cb, NULL);
			assert(err == dp_RES_OK);
		}
	} else {	/* not thawing */
		sprintf(dplogname, "dpt%d.%d.log", childNum,startLoopAt);
		dp_setLogFname(dplogname);
		printf("Node %d step 1\n", childNum);

		/* Create our dpio */
		memset(&dll, 0, sizeof(dll));
		strcpy(dll.fname, results.driver);
		memset(&commInitReq, 0, sizeof(commInitReq));
		commInitReq.sessionId = childNum + 1;			/* claim our address */
		commInitReq.portnum = childNum + PORT_OFFSET;	/* claim our port */
		commInitReq.reqLen = sizeof(commInitReq_t);
		err = dpio_create(&dpio, &dll, &commInitReq, &dpio_now, NULL);
		assert(err == dp_RES_OK);

		/* Find our next-in-ring */
		scanReq.printable = sNextAdr;
		scanReq.address = adrBuf;
		scanReq.size = sizeof(adrBuf);
		if (!commScanAddr(&scanReq, &scanResp)) {
			printf("Unable to scan next host address %s, err: %d",
					scanReq.printable, scanResp.status);
			assert(FALSE);
		}
		results.packetLoss = dpio->rxDropPercent;

		/* Create our table collection (dptab) */
		tab = dptab_create(dpio);
		assert(tab);

		/* 2. Create tables */
		printf("Node %d step 2\n", childNum);
		key[0] = 1;
		err = dptab_createTable(tab, &table, key, 1, sizeof(int), NULL, NULL, table_cb, NULL);
		assert(err == dp_RES_OK);
		if(childNum == 0) {
			key[0] = 2;
			err = dptab_createTable(tab, &table2, key, 1, sizeof(int), NULL, NULL, table_cb, NULL);
			assert(err == dp_RES_OK);
		}

		/* 3. Establish connections */
		printf("Node %d step 3\n", childNum);
		/*  Open a comm handle to the partner's address */
		dest = dpio_openHdl(dpio, adrBuf, NULL, NULL);
		if (dest == PLAYER_NONE) {
			printf("Unable to connect to address %s", scanReq.printable);
			assert(FALSE);
		}
		printf("Node %d: Opening address %s returns handle %d/%x\n", childNum, scanReq.printable, dest, dest);
		if (dest == PLAYER_ME) {
			printf("Executed out of order - got handle to myself\n");
			assert(FALSE);
		}

		/* Add the next machine to the party */
		err = dptab_addPeer(tab, dest);
		/* only master should have received packet from unknown source. */
		if ((childNum == 0) && (su_src == dest))
			assert(err == dp_RES_ALREADY);
		else
			assert(err == dp_RES_OK);

		/* Let the next machine publish on top of our table */
		key[0] = 1;
		if(childNum == 0)
			err = dptab_addPublisher(tab, table2, key, 1, dest);
		else
			err = dptab_addPublisher(tab, table, key, 1, dest);
		assert(err == dp_RES_OK);

		/* Request the next machine publish table to us */
		(*(dp_packetType_t *)nbuf) = PKT_SU;
		err = dpio_put_reliable(dpio, &dest, 1, nbuf, sizeof(dp_packetType_t)+2, NULL);
		assert(err == dp_RES_OK);
		printf("Node %d sent SU to h:%x\n", childNum, dest);

		/* 4. Wait for an "SU" packet. */
		printf("Node %d step 4: waiting for su.\n", childNum);
		su_src = PLAYER_NONE;
		do {
			poll_test(dpio, tab);
		} while (su_src == PLAYER_NONE);

		/* 5. publish the table to whoever sent "SU" to us. */
		printf("Node %d step 5\n", childNum);
		err = dptab_addPeer(tab, su_src);
		if (su_src == dest)
			assert(err == dp_RES_ALREADY);
		else
			assert(err == dp_RES_OK);
		err = dptab_addSubscriber(tab, table, su_src);
		assert(err == dp_RES_OK);
	}	/* not thawing */

	for(i = startLoopAt; i < loopTotal; i++) {
		/* 6. Send an IT packet around the ring. */
		printf("Node %d step 6.%d\n", childNum, i);
		if(childNum == 0) {	/* Master sends first IT. */
			(*(dp_packetType_t *)nbuf) = PKT_IT;
			nbuf[sizeof(dp_packetType_t)] = (char) (i & 0x7F);
			err = dpio_put_reliable(dpio, &dest, 1, nbuf,
						sizeof(dp_packetType_t)+sizeof(char), NULL);
			assert(err == dp_RES_OK);
		}
		printf("Node %d waiting for IT(%d).\n", childNum, i);
		do {				/* Wait for IT */
			poll_test(dpio, tab);
		} while (((int) it_num) < (i & 0x7F));
		if(childNum != 0) {	/* Slaves send IT after getting one. */
			(*(dp_packetType_t *)nbuf) = PKT_IT;
			nbuf[sizeof(dp_packetType_t)] = (char) i;
			err = dpio_put_reliable(dpio, &dest, 1, nbuf,
						sizeof(dp_packetType_t)+sizeof(char), NULL);
			assert(err == dp_RES_OK);
		}

		/* 7. If master, set a value and wait for it to come back around. */
		if(childNum == 0) {
			printf("Node %d step 7\n", childNum);
			subkey[0] = SUBKEY_SINGLE_SMALL;
			sprintf(nbuf, "a%03d", i);
			printf("Node %d: setting variable to %s\n", childNum, nbuf);
			results.sentSingleSmallTime = dpio_now;
			err = dptab_set(tab, table, subkey, 1, nbuf, strlen(nbuf), results.n_hosts, PLAYER_ME);
			if (err != dp_RES_OK) {
				printf("Node %d: dptab_set returns err %d!\n", childNum, err);
				assert(err == dp_RES_OK);
			}
		}

		/* Freeze and spawn if it's the right iteration. */
		/* Do it here to force an xfer to be saved and restored. */
		if(i == endLoopAt) {
			FILE* freezeFile;
			int result;
			int proc;

			/* Find our file */
			sprintf(fname, FREEZENAME, childNum);
			printf("Node %d: Iteration %d, Freezing to file %s.\n", childNum, i, fname);
			freezeFile = fopen(fname, "w");
			assert (freezeFile != NULL);

			/* Write everything to our file */
			fwrite(&i,sizeof(int),1,freezeFile);
			fwrite(&loopTotal,sizeof(int),1,freezeFile);
			fwrite(&it_num,sizeof(int),1,freezeFile);
			fwrite(&(results.n_hosts),sizeof(int),1,freezeFile);

			err = dpio_freeze(dpio, freezeFile);
			assert(err == dp_RES_OK);
			err = dpio_freezeHdl(dpio, dest, freezeFile);
			assert(err == dp_RES_OK);

			err = dptab_freeze(tab, freezeFile);
			assert(err == dp_RES_OK);
			fclose(freezeFile);
			dptab_destroy(tab);
			dpio_destroy(dpio, 1);

			/* Spawn and return child's return code */
			sprintf(buf, "%d", childNum);
			proc = _spawnl(_P_NOWAIT, results.exe, results.exe, buf, fname, NULL);
			_cwait(&result, proc, 0);
			printf("Node %d.%d returned %d.\n", childNum, i, result);
			return result;
		}

		if(childNum == 0) {
			/* d. Wait until value appears in table2 (callback). */
			printf("Node %d waiting for value to appear.\n", childNum);
			results.gotSingleSmallTime = -1;
			do {
				poll_test(dpio, tab);
			} while (results.gotSingleSmallTime == -1);
		}
	}

	/* 8. Send a QQ packet around the ring. */
	printf("Node %d step 8\n", childNum);
	qq_src = PLAYER_NONE;
	if(childNum == 0) {	/* Master sends first QQ */
		(*(dp_packetType_t *)nbuf) = PKT_QQ;
		err = dpio_put_reliable(dpio, &dest, 1, nbuf, sizeof(dp_packetType_t), NULL);
		assert(err == dp_RES_OK);
	}
	/* Wait for QQ */
	printf("Node %d waiting for QQ.\n", childNum);
	do {
		poll_test(dpio, tab);
	} while (qq_src == PLAYER_NONE);
	if(childNum != 0) {	/* Slaves wait for a QQ and then send QQ */
		(*(dp_packetType_t *)nbuf) = PKT_QQ;
		err = dpio_put_reliable(dpio, &dest, 1, nbuf, sizeof(dp_packetType_t), NULL);
		assert(err == dp_RES_OK);
	}

	/* 9. Exit. */
	printf("Node %d step 9\n", childNum);
	/* Ack packets for four more seconds just in case */
	{
		clock_t start = eclock();
		while ((long)(eclock() - start) < 4 * ECLOCKS_PER_SEC) {
			dpio_now = eclock();
			dpio_update(dpio);
		}
	}
	printf("Node %d exiting\n", childNum);
	return 0;
}
Ejemplo n.º 16
0
/*-------------------------------------------------------------------------
 This is called by the dptab_handlePacket when a new variable arrives or
 an old one is deleted.
 Note the time of the callback in the result block.
-------------------------------------------------------------------------*/
int dp_PASCAL
table_cb(
	dptab_t *dptab,			/* table owner */
	dptab_table_t *table,	/* table */
	playerHdl_t src,		/* */
	playerHdl_t dest,		/* */
	char *subkey,			/* key of variable */
	int subkeylen,			/* number of bytes in subkey */
	void *buf,				/* pointer to variable */
	size_t sent,
	size_t total,
	int seconds_left,
	void *context,			/* whatever we gave it */
	dp_result_t err)		/* operation completed upon variable */
{
	clock_t now = eclock();
	printf("Node %d: table_cb: type:%d  src h:%x  dest h:%x  table:%s  key:%s\n",
				results.thisHost, err, src, dest, key2a(table->key, table->keylen),
				key2a2(subkey, subkeylen));
	if (err == dp_RES_CREATED || err == dp_RES_CHANGED) {
		/*printf("table_cb: CREATED/CHANGED: src h:%x  dest h:%x  table:%s  key:%s\n",
				src, dest, key2a(table->key, table->keylen),
				key2a2(subkey, subkeylen));*/
		if ((dest == PLAYER_ME) && (sent == total)) {
			/* Got a variable */
			switch (subkey[0]) {
			case SUBKEY_SINGLE_SMALL:
				if(table->key[0] == 2) {
					results.gotSingleSmallTime = now;
					results.singleSmallTime = ((float)now - results.sentSingleSmallTime) / ECLOCKS_PER_SEC;
					/* Move this statement to right after last measurement taken */
					writeReport(logFile, &results);
				}
				break;
			case SUBKEY_SINGLE_LARGE:
				results.gotSingleLargeTime = now;
				break;
			case SUBKEY_MULTIPLE_SMALL:
				results.gotMultipleSmallTime = now;
				break;
			default:
				;
			}
			printf("Node %d: Got variable from h:%x; table %s, subkey %s; len %d\n",
				results.thisHost,
				src,
				key2a(table->key, table->keylen),
				key2a2(subkey, subkeylen),
				total);
		}
	} else if (err == dp_RES_CLOSED) {
		/*printf("table_cb: Deleted: src h:%x  dest h:%x\n", src, dest);*/
		if (dest == PLAYER_ME) {
			switch (subkey[0]) {
			case SUBKEY_SINGLE_SMALL:
				results.gotDeleteTime = now;
				results.deleteTime = ((float)now - results.sentDeleteTime) / ECLOCKS_PER_SEC;
				break;
			default:
				;
			}
			printf("Node %d: Got delete variable from h:%x; table %s, subkey %s\n",
				results.thisHost,
				src,
				key2a(table->key, table->keylen),
				key2a2(subkey, subkeylen));
		}
	}

	(void) dptab;
	(void) buf;
	(void) seconds_left;
	(void) context;
	return TRUE;
}