Beispiel #1
0
static boolean getOurAck(struct rudp *ru, struct timeval *startTv, struct sockaddr_in *sai)
/* Wait for acknowledgement to the message we just sent.
 * The set should be zeroed out. Only wait for up to
 * ru->timeOut microseconds.   Prints a message and returns FALSE
 * if there's a problem.   */
{
struct rudpHeader head;
int readSize;
int timeOut = ru->timeOut;
struct sockaddr_in retFrom;
unsigned int retFromSize = sizeof(retFrom);

for (;;)
    {
    /* Set up select with our time out. */
    int dt;
    struct timeval tv;

    if (readReadyWait(ru->socket, timeOut))
	{
	/* Read message and if it's our ack return true.   */
	readSize = recvfrom(ru->socket, &head, sizeof(head), 0, 
		    (struct sockaddr*)&retFrom, &retFromSize);
	if (readSize >= sizeof(head) && head.type == rudpAck && head.id == ru->lastId)
	    {
	    if ((sai->sin_addr.s_addr==retFrom.sin_addr.s_addr) &&
		(sai->sin_port==retFrom.sin_port))
		{
		gettimeofday(&tv, NULL);
		dt = timeDiff(startTv, &tv);
		rudpAddRoundTripTime(ru, dt);
		return TRUE;
		}
	    else
		{
		char retFromDottedQuad[17];
		char saiDottedQuad[17];
		internetIpToDottedQuad(ntohl(retFrom.sin_addr.s_addr), retFromDottedQuad);
		internetIpToDottedQuad(ntohl(sai->sin_addr.s_addr), saiDottedQuad);
		warn("rudp: discarding mistaken ack from %s:%d by confirming recipient ip:port %s:%d"
		    , retFromDottedQuad, retFrom.sin_port
		    , saiDottedQuad, sai->sin_port
		    );
		}
	    }
	}

    /* If we got to here then we did get a message, but it's not our
     * ack.  We ignore the message and loop around again,  but update
     * our timeout so that we won't keep getting other people's messages
     * forever. */
    gettimeofday(&tv, NULL);
    timeOut = ru->timeOut - timeDiff(startTv, &tv);
    if (timeOut <= 0)
	return FALSE;
    }
}
void doRun(char *line, struct sockaddr_in *hubIp)
/* Execute command. */
{
char *jobMessage = cloneString(line);
static char *args[1024];
int argCount;
char hubDottedQuad[17];

nextRandom();
if (line == NULL)
    warn("Executing nothing...");
else if (!internetIpToDottedQuad(ntohl(hubIp->sin_addr.s_addr), hubDottedQuad))
    warn("Can't convert ipToDottedQuad");
else
    {
    struct runJobMessage rjm;
    if (parseRunJobMessage(line, &rjm))
	{
	int jobId = atoi(rjm.jobIdString);
	if (findRunningJob(jobId) == NULL && findFinishedJob(jobId) == NULL)
	    {
	    if (busyProcs < maxProcs)
		{
		int childPid;
		argCount = chopLine(rjm.command, args);
		if (argCount >= ArraySize(args))
		    warn("Too many arguments to run");
		else
		    {
		    args[argCount] = NULL;
		    if ((childPid = forkOrDie()) == 0)
			{
			/* Do JOB_ID substitutions */
			struct subText *st = subTextNew("$JOB_ID", rjm.jobIdString);
			int i;
			rjm.in = subTextString(st, rjm.in);
			rjm.out = subTextString(st, rjm.out);
			rjm.err = subTextString(st, rjm.err);
			for (i=0; i<argCount; ++i)
			    args[i] = subTextString(st, args[i]);

			execProc(hubDottedQuad, rjm.jobIdString, rjm.reserved,
			    rjm.user, rjm.dir, rjm.in, rjm.out, rjm.err, rjm.ram,
			    args[0], args);
			exit(0);
			}
		    else
			{
			struct job *job;
			AllocVar(job);
			job->jobId = atoi(rjm.jobIdString);
			job->pid = childPid;
			job->startMessage = jobMessage;
			jobMessage = NULL;	/* No longer own memory. */
			job->node = dlAddValTail(jobsRunning, job);
			++busyProcs;
			}
		    }
		}
	    else
		{
		warn("Trying to run when busy.");
		}
	    }
	else
	    {
	    warn("Duplicate run-job %d\n", jobId);
	    }
	}
    }
freez(&jobMessage);
}
Beispiel #3
0
int rudpReceiveTimeOut(struct rudp *ru, void *messageBuf, int bufSize, 
	struct sockaddr_in *retFrom, int timeOut)
/* Read message into buffer of given size.  Returns actual size read on
 * success. On failure prints a warning, sets errno, and returns -1. 
 * Also returns ip address of message source. If timeOut is nonzero,
 * it represents the timeout in milliseconds.  It will set errno to
 * ETIMEDOUT in this case.*/
{
char inBuf[udpEthMaxSize];
struct rudpHeader *head = (struct rudpHeader *)inBuf;
struct rudpHeader ackHead;
struct sockaddr_in sai;
socklen_t saiSize = sizeof(sai);
int readSize, err;
assert(bufSize <= rudpMaxSize);
ru->receiveCount += 1;
for (;;)
    {
    if (timeOut != 0)
	{
	if (!readReadyWait(ru->socket, timeOut))
	    {
	    warn("rudpReceive timed out\n");
	    errno = ETIMEDOUT;
	    return -1;
	    }
	}
    readSize = recvfrom(ru->socket, inBuf, sizeof(inBuf), 0, 
	(struct sockaddr*)&sai, &saiSize);
    if (retFrom != NULL)
	*retFrom = sai;
    if (readSize < 0)
	{
	if (errno == EINTR)
	    continue;
	warn("recvfrom error: %s", strerror(errno));
	ru->failCount += 1;
	return readSize;
	}
    if (readSize < sizeof(*head))
	{
	warn("rudpRecieve truncated message");
	continue;
	}
    if (head->type != rudpData)
	{
	if (head->type != rudpAck)
	    warn("skipping non-data message %d in rudpReceive", head->type);
	continue;
	}
    ackHead = *head;
    ackHead.type = rudpAck;
    err = sendto(ru->socket, &ackHead, sizeof(ackHead), 0, 
	(struct sockaddr *)&sai, sizeof(sai));
    if (err < 0)
	{
	warn("problem sending ack in rudpRecieve: %s", strerror(errno));
	}
    readSize -= sizeof(*head);
    if (readSize > bufSize)
	{
	warn("read more bytes than have room for in rudpReceive");
	readSize = bufSize;
	}
    memcpy(messageBuf, head+1, readSize);

    /* check for duplicate packet */
    if (!ru->recvHash)
	{ /* take advantage of new auto-expanding hashes */
	ru->recvHash = newHashExt(4, FALSE);  /* do not use local mem in hash */
	ru->recvList = newDlList();
	ru->recvCount = 0;
	}
    char hashKey[64];
    char saiDottedQuad[17];
    internetIpToDottedQuad(ntohl(sai.sin_addr.s_addr), saiDottedQuad);
    safef(hashKey, sizeof(hashKey), "%s-%d-%d-%d" 
    	, saiDottedQuad 
        , head->pid              
        , head->connId
        , head->id
      );		    
    if (hashLookup(ru->recvHash, hashKey))
	{
	warn("duplicate packet filtered out: %s", hashKey);
	continue;
	}
    long now = time(NULL);
    struct packetSeen *p;
    AllocVar(p);
    AllocVar(p->node);
    p->node->val = p;
    p->recvHashKey = hashStoreName(ru->recvHash, hashKey);
    p->lastChecked = now;
    dlAddTail(ru->recvList, p->node);
    ++ru->recvCount;
   
    sweepOutOldPacketsSeen(ru, now);

    ru->lastIdReceived = head->id;
    break;
    }
return readSize;
}