Пример #1
0
static void rpc2_ProcessPacket(int fd)
{
    RPC2_PacketBuffer *pb = NULL;
    struct timeval tv;
    int rc;

    /* We are guaranteed that there is a packet in the socket
       buffer at this point */
    RPC2_AllocBuffer(RPC2_MAXPACKETSIZE - sizeof(RPC2_PacketBuffer), &pb);
    assert(pb != NULL);
    assert(pb->Prefix.LE.Queue == &rpc2_PBList);

    if (rpc2_RecvPacket(fd, pb) < 0) {
        say(9, RPC2_DebugLevel, "Recv error, ignoring.\n");
        RPC2_FreeBuffer(&pb);
        return;
    }

#ifdef RPC2DEBUG
    if (RPC2_DebugLevel > 9) {
        fprintf(rpc2_tracefile, "Packet received from ");
        rpc2_printaddrinfo(pb->Prefix.PeerAddr, rpc2_tracefile);
        if (pb->Prefix.sa && pb->Prefix.sa->decrypt)
            fprintf(rpc2_tracefile, " (secure)");
        fprintf(rpc2_tracefile, "\n");
    }
#endif

    if (pb->Prefix.LengthOfPacket < (ssize_t)sizeof(struct RPC2_PacketHeader)) {
        /* avoid memory reference errors */
        BOGUS(pb, "Runt packet\n");
        return;
    }

    rc = LUA_fail_delay(pb->Prefix.PeerAddr, pb, 0, &tv);
    if (rc == -1) {
        say(9, RPC2_DebugLevel, "Dropping incoming packet\n");
        RPC2_FreeBuffer(&pb);
        return;
    }
    if (rc && rpc2_DelayedRecv(pb, &tv)) {
        return;
    } /* delay */

    DispatchPacket(pb);
}
Пример #2
0
static RPC2_PacketBuffer *ShrinkPacket(RPC2_PacketBuffer *pb)
{
    RPC2_PacketBuffer *pb2 = NULL;
    size_t len = pb->Prefix.LengthOfPacket - sizeof(struct RPC2_PacketHeader);

    if (pb->Prefix.LengthOfPacket > MEDIUMPACKET)
        return pb;

    RPC2_AllocBuffer(len, &pb2);
    if (!pb2)
        return pb;

    pb2->Prefix.PeerAddr       = pb->Prefix.PeerAddr;
    pb->Prefix.PeerAddr        = NULL;
    pb2->Prefix.sa             = pb->Prefix.sa;
    pb2->Prefix.RecvStamp      = pb->Prefix.RecvStamp;
    pb2->Prefix.LengthOfPacket = pb->Prefix.LengthOfPacket;
    memcpy(&pb2->Header, &pb->Header, pb->Prefix.LengthOfPacket);
    RPC2_FreeBuffer(&pb);
    return (pb2);
}
Пример #3
0
static void SendBusy(struct CEntry *ce, int doEncrypt)
{
    RPC2_PacketBuffer *pb;
    unsigned int delta;

    rpc2_Sent.Busies++;

    RPC2_AllocBuffer(0, &pb);
    rpc2_InitPacket(pb, ce, 0);

    delta                = TSDELTA(rpc2_MakeTimeStamp(), ce->RequestTime);
    pb->Header.TimeStamp = (unsigned int)ce->TimeStampEcho + delta;
    pb->Header.SeqNumber = ce->NextSeqNumber - 1;
    pb->Header.Opcode    = RPC2_BUSY;

    rpc2_htonp(pb);
    if (doEncrypt)
        rpc2_ApplyE(pb, ce);

    rpc2_XmitPacket(pb, ce->HostInfo->Addr, 1);
    RPC2_FreeBuffer(&pb);
}
Пример #4
0
/* Sends a NAK packet for remoteHandle on (whichHost, whichPort) pair */
static void SendNak(RPC2_PacketBuffer *pb)
{
    RPC2_PacketBuffer *nakpb;
    RPC2_Handle remoteHandle = pb->Header.LocalHandle;

    if (pb->Header.Opcode == RPC2_NAKED)
        return;

    say(1, RPC2_DebugLevel, "Sending NAK\n");
    RPC2_AllocBuffer(0, &nakpb);
    rpc2_InitPacket(nakpb, NULL, 0);
    nakpb->Prefix.sa           = pb->Prefix.sa;
    nakpb->Header.RemoteHandle = remoteHandle;
    nakpb->Header.LocalHandle  = -1; /* "from SocketListener" */
    nakpb->Header.Opcode       = RPC2_NAKED;

    rpc2_htonp(nakpb);
    /* use the same security association on which we received the packet
     * we're currently nak-ing */
    rpc2_XmitPacket(nakpb, pb->Prefix.PeerAddr, 1);
    RPC2_FreeBuffer(&nakpb);
    rpc2_Sent.Naks++;
}
Пример #5
0
long VENUS_GetMsg(RPC2_Handle _cid, RPC2_Integer *arg)
{
    char *_ptr;
    long _length, _rpc2val, _code;
    RPC2_PacketBuffer *_rspbuffer = NULL;
    struct timeval _timestart, _timeend;
    RPC2_PacketBuffer *_reqbuffer = NULL;
    struct timeval *_timeout;
    char *_EOB;
    int opengate = 0;

    /* START_ELAPSE */
    coda_CallCount[1].countent++;
    if (coda_ElapseSwitch) {
	gettimeofday(&_timestart, NULL);
	opengate = 1;
    }

    _length = 0;
    _rpc2val = RPC2_AllocBuffer(_length, &_reqbuffer);
    if (_rpc2val != RPC2_SUCCESS) return _rpc2val;
    _EOB = (char *)_reqbuffer + _reqbuffer->Prefix.BufferSize;

    /* Avoid compiler warnings */
    _ptr = NULL;

    /* Generate RPC2 call */
    _reqbuffer->Header.Opcode = GetMsg_OP;
    _rspbuffer = NULL;
    _timeout = NULL;
    _rpc2val = RPC2_MakeRPC(_cid, _reqbuffer, NULL, &_rspbuffer, _timeout, coda_EnqueueRequest);
    RPC2_FreeBuffer(&_reqbuffer);
    if (_rpc2val != RPC2_SUCCESS) {
	RPC2_FreeBuffer(&_rspbuffer);
	return _rpc2val;
    }
    if (_rspbuffer->Header.ReturnCode == RPC2_INVALIDOPCODE) {
	RPC2_FreeBuffer(&_rspbuffer);
	return RPC2_INVALIDOPCODE;
    }

    /* Unpack arguments */
    _ptr = (char *)_rspbuffer->Body;
     _EOB = (char *)_rspbuffer + _rspbuffer->Prefix.LengthOfPacket + 
			sizeof(struct RPC2_PacketBufferPrefix);
    if ( (char *)_ptr + 4 > _EOB)
	goto bufferoverflow;
    *arg = ntohl(*(RPC2_Integer *) _ptr);
    _ptr += 4;
    _code = _rspbuffer->Header.ReturnCode;
    RPC2_FreeBuffer(&_rspbuffer);

    /* END_ELAPSE */
    if (opengate) {
	gettimeofday(&_timeend, NULL);
	coda_CallCount[1].tsec += _timeend.tv_sec - _timestart.tv_sec;
	coda_CallCount[1].tusec += _timeend.tv_usec - _timestart.tv_usec;
	if (coda_CallCount[1].tusec < 0) {
	    coda_CallCount[1].tusec += 1000000;
	    coda_CallCount[1].tsec--;
	} else if (coda_CallCount[1].tusec >= 1000000) {
	    coda_CallCount[1].tusec -= 1000000;
	    coda_CallCount[1].tsec++;
	}
	coda_CallCount[1].counttime++;
    }
    coda_CallCount[1].countexit++;

    return _code;

bufferoverflow:
    fprintf(stderr,"%s:%d Buffer overflow in (un)marshalling !\n",__FILE__,__LINE__);
    RPC2_FreeBuffer(&_rspbuffer);
    return RPC2_BADDATA;
}
Пример #6
0
static void ClientBody(void *arg)
{
    RPC2_Handle thisconn;
    RPC2_Integer thisopcode;
    RPC2_PacketBuffer *request, *reply;
    long retcode, rpctime = 0;
    struct timeval t1, t2;
    char myprivatefile[256];
    char myhashmark;
    RPC2_BindParms bp;
    SE_Descriptor sed;


#define MakeTimedCall(whichse)\
	if (VerboseFlag) gettimeofday(&t1, 0);\
	retcode = RPC2_MakeRPC(ConnVector[thisconn].ConnHandle, request, whichse, &reply, NULL, 0);\
	if (VerboseFlag) gettimeofday(&t2, 0);\
	if (VerboseFlag) rpctime = ((t2.tv_sec - t1.tv_sec)*1000) + ((t2.tv_usec - t1.tv_usec)/1000);


    memset(&sed, 0, sizeof(SE_Descriptor));
    sed.Tag = SMARTFTP;

    strcpy(myprivatefile, MakeName(LWP_Name()));
    myhashmark = NextHashMark++;

    LWP_DispatchProcess();	/* initial courtesy to parent */
    
    RPC2_AllocBuffer(1000, &request);
    reply = NULL;


    ClientsReady++;
    LWP_WaitProcess((char *)&ClientsReady);	/* wait for main() to tap me on shoulder */

    while(1)
	{
	if (reply) RPC2_FreeBuffer(&reply);

	RanDelay(MaxThinkTime);
	SelectParms(&thisconn, &thisopcode);
	ConnVector[thisconn].Status = BUSY;
	request->Header.Opcode = thisopcode;
	
	if (VerboseFlag)
	    fprintf(stderr, "Making request %d to %s for %s\n",
		    thisopcode,
		    ConnVector[thisconn].RemoteHost.Value.Name,
		    ConnVector[thisconn].NameBuf);

	switch(thisopcode)
	    {
	    case 1: /* return Unix epoch time */
		{
		request->Header.BodyLength = 0;
		MakeTimedCall(NULL);
		if (retcode == RPC2_SUCCESS)
		    {
		    if (VerboseFlag)
			fprintf(stderr, "Time on %s is %s (%ld msecs)\n",
				ConnVector[thisconn].RemoteHost.Value.Name,
				reply->Body, rpctime);
		    break;
		    }
		else HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode));
		}

	    case 2: /* square the input integer */
	    {
		uint32_t *op = (uint32_t *)request->Body;
		uint32_t x = (uint32_t)random() % 100;

		op[0] = htonl(x);
		request->Header.BodyLength = sizeof(uint32_t);

		MakeTimedCall(NULL);
		if (retcode == RPC2_SUCCESS)
		    {
		    if (VerboseFlag) {
			uint32_t *ip = (uint32_t *)reply->Body;
			fprintf(stderr, " %s says square of %u is %u (%ld msecs)\n",
				ConnVector[thisconn].RemoteHost.Value.Name, x,
				ntohl(ip[0]), rpctime);
		    }
		    break;
		    }
		else HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode));
		break;
	    }

	    case 3: /* cube the input integer */
	    {
		uint32_t *op = (uint32_t *)request->Body;
		uint32_t x = (uint32_t)random() % 100;

		op[0] = htonl(x);
		request->Header.BodyLength = sizeof(uint32_t);

		MakeTimedCall(NULL);
		if (retcode == RPC2_SUCCESS)
		    {
		    if (VerboseFlag) {
			uint32_t *ip = (uint32_t *)reply->Body;
			fprintf(stderr, "%s says cube of %d is %u (%ld msecs)\n",
				ConnVector[thisconn].RemoteHost.Value.Name, x,
				ntohl(ip[0]), rpctime);
		    }
		    break;
		    }
		else HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode));
		break;
	    }

	    case 4: /* Return your machine name */
		{
		request->Header.BodyLength = 0;
		MakeTimedCall(NULL);
		if (retcode == RPC2_SUCCESS)
		    {
		    if (VerboseFlag)
			fprintf(stderr, "%s says its name is \"%s\" (%ld msecs)\n",
				ConnVector[thisconn].RemoteHost.Value.Name,
				reply->Body, rpctime);
		    break;
		    }
		else HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode));
		break;
		}

	    case 5: /* Fetch a random file */
		{
		if (AvoidBulk)
		     {
		     ConnVector[thisconn].Status = SFREE;
		     continue;
		     }
		request->Header.BodyLength = 0;
		sed.Value.SmartFTPD.TransmissionDirection = SERVERTOCLIENT;
		sed.Value.SmartFTPD.FileInfo.ByName.ProtectionBits = 0644;
		sed.Value.SmartFTPD.SeekOffset = 0;
		sed.Value.SmartFTPD.Tag = FILEBYNAME;
		strcpy(sed.Value.SmartFTPD.FileInfo.ByName.LocalFileName, myprivatefile);
		if (VerboseFlag)
		    sed.Value.SmartFTPD.hashmark = myhashmark;
		else sed.Value.SmartFTPD.hashmark = 0;
		MakeTimedCall(&sed);
		if (retcode != RPC2_SUCCESS)
		    {
		    HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode));
		    break;		    
		    }
		else
		    if (VerboseFlag)
			fprintf(stderr, "%ld bytes transferred\n",
				sed.Value.SmartFTPD.BytesTransferred);

		break;
		}

	    case 6: /* Store a random file */
	    {
		uint32_t randval;
		if (AvoidBulk)
		     {
		     ConnVector[thisconn].Status = SFREE;
		     continue;
		     }
		request->Header.BodyLength = 0;
		sed.Value.SmartFTPD.TransmissionDirection = CLIENTTOSERVER;
		sed.Value.SmartFTPD.SeekOffset = 0;
		sed.Value.SmartFTPD.Tag = FILEBYNAME;
		randval = (uint32_t)random();
		strcpy(sed.Value.SmartFTPD.FileInfo.ByName.LocalFileName,
		       SysFiles[randval % SysFileCount]);
		if (VerboseFlag)
		    sed.Value.SmartFTPD.hashmark = myhashmark;
		else sed.Value.SmartFTPD.hashmark = 0;
		MakeTimedCall(&sed);
		if (retcode !=  RPC2_SUCCESS)
		{
		    HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode));
		    break;
		}
		else
		    if (VerboseFlag)
			fprintf(stderr, "%ld bytes transferred\n",
				sed.Value.SmartFTPD.BytesTransferred);
		break;
	    }

	    case 7:   /* Unbind */
		{
		request->Header.BodyLength = 0;
		MakeTimedCall(NULL);
		if (retcode == RPC2_SUCCESS)
		    {
		    if (VerboseFlag)
			fprintf(stderr, "Unbound connection to %s for %s after %ld calls\n",
				ConnVector[thisconn].RemoteHost.Value.Name,
				ConnVector[thisconn].Identity.SeqBody,
				ConnVector[thisconn].CallsMade);
		    assert(RPC2_Unbind(ConnVector[thisconn].ConnHandle) == RPC2_SUCCESS);
		    }
		else
		    {HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode));}
		ConnVector[thisconn].Status = UNBOUND;
		break;
		}


	    case 8:	/* Rebind */
		{
		bp.SecurityLevel = ConnVector[thisconn].SecurityLevel;
		bp.EncryptionType = RPC2_XOR;
		bp.SideEffectType = SMARTFTP;
		bp.ClientIdent = &ConnVector[thisconn].Identity;
		bp.SharedSecret = &ConnVector[thisconn].Password;
		retcode = RPC2_NewBinding(&ConnVector[thisconn].RemoteHost,
					  &PortId, &SubsysId, &bp,
					  &ConnVector[thisconn].ConnHandle);
		if (retcode < RPC2_ELIMIT)
		    {
		    HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode));
		    }
		else
		    {
		    if (VerboseFlag)
			fprintf(stderr, "Rebound connection to %s for %s\n",
				ConnVector[thisconn].RemoteHost.Value.Name,
				ConnVector[thisconn].Identity.SeqBody);
		    }
		break;
		}



	    case 999: /* Quit */
		{
		}

	    default: /* unknown opcode */
		printf("Arrrgggghhh .... bogus opcode\n"); abort();
		break;
	    }
	
	if (ConnVector[thisconn].Status == BUSY) ConnVector[thisconn].Status = SFREE;
	if (retcode == RPC2_CONNBUSY) continue; /* you didn't really do it */

	/* Indicate progress  */
	ConnVector[thisconn].CallsMade++;
	if(ConnVector[thisconn].CallsMade % Announce == 1)
	    {
	    struct CVEntry *ce = &ConnVector[thisconn];
	    printf("\n%ld successful calls to %s for %s at %s", ce->CallsMade,
		ce->RemoteHost.Value.Name, ce->NameBuf, TimeNow());
	    PrintStats();
	    }
	else
	    {
	    int xx;
	    xx = (1.0*Announce)/100.0 + 0.5; /* ceiling */
	    if (xx == 0 || ConnVector[thisconn].CallsMade % xx == 1)
		printf("%c", myhashmark);
	    }
	
	}

}
Пример #7
0
static void WorkerBody(void *arg)
{
    long i, rc;
    RPC2_RequestFilter reqfilter;
    RPC2_PacketBuffer *InBuff, *OutBuff;
    RPC2_Handle workercid;
    char myprivatefile[256];
    char myhashmark;
    SE_Descriptor sed;


    memset(&sed, 0, sizeof(SE_Descriptor));
    sed.Tag = SMARTFTP;

    strcpy(myprivatefile, MakeName(LWP_Name()));
    myhashmark = NextHashMark++;

    LWP_DispatchProcess();	/* initial courtesy to parent */

    reqfilter.FromWhom = ONESUBSYS;
    reqfilter.ConnOrSubsys.SubsysId = SUBSYS_SRV;
    assert(reqfilter.ConnOrSubsys.SubsysId != -1);
    reqfilter.OldOrNew = OLD;

    RPC2_AllocBuffer(1000, &OutBuff);
    InBuff = NULL;

    while (1)
	{
	RanDelay(MaxComputeTime);

	if (InBuff != NULL) RPC2_FreeBuffer(&InBuff);
	i = RPC2_GetRequest(&reqfilter, &workercid, &InBuff, NULL, NULL, 0, NULL);
	if (i != RPC2_SUCCESS)
	    {
	    printf("\n%s: GetRequest failed (%s) at %s", MYNAME, RPC2_ErrorMsg(i), TimeNow());
	    DumpAndQuit(0);
	    }
	
	switch(InBuff->Header.Opcode)
	    {
	    case 1: /* return Unix epoch time */
		{
		strcpy((char *)OutBuff->Body, TimeNow());
		OutBuff->Header.ReturnCode = RPC2_SUCCESS;
		OutBuff->Header.BodyLength = sizeof(struct RPC2_PacketHeader) + strlen((char *)OutBuff->Body) + 1;
		break;
		}
		
	    case 2: /* square the input integer */
		{
		uint32_t *ip = (uint32_t *)InBuff->Body;
		uint32_t *op = (uint32_t *)OutBuff->Body;
		uint32_t x = ntohl(*ip);

		*op = htonl(x * x);
		OutBuff->Header.ReturnCode = RPC2_SUCCESS;
		OutBuff->Header.BodyLength = sizeof(RPC2_Integer);
		break;
		}
	    
	    case 3: /* cube the input integer */
		{
		uint32_t *ip = (uint32_t *)InBuff->Body;
		uint32_t *op = (uint32_t *)OutBuff->Body;
		uint32_t x = ntohl(*ip);

		*op = htonl(x*x*x);
		OutBuff->Header.ReturnCode = RPC2_SUCCESS;
		OutBuff->Header.BodyLength = sizeof(RPC2_Integer);
		break;
		}

	    case 4: /* Return your machine name */
		{
		gethostname((char *)OutBuff->Body, 100);
		OutBuff->Header.ReturnCode = RPC2_SUCCESS;
		OutBuff->Header.BodyLength = strlen((char *)OutBuff->Body) + 1;
		break;
		}

	    case 5: /* Fetch a random file */
	    {
		uint32_t randval;
		if (VerboseFlag) sed.Value.SmartFTPD.hashmark = myhashmark;
		else sed.Value.SmartFTPD.hashmark = 0;
		randval = (uint32_t)random();
		strcpy(sed.Value.SmartFTPD.FileInfo.ByName.LocalFileName,
		       SysFiles[randval % SysFileCount]);
		sed.Value.SmartFTPD.TransmissionDirection = SERVERTOCLIENT;
		sed.Value.SmartFTPD.SeekOffset = 0;
		sed.Value.SmartFTPD.Tag = FILEBYNAME;

		if ((rc = RPC2_InitSideEffect(workercid, &sed)) != RPC2_SUCCESS)
		    {
		    BulkErr(workercid, &sed, rc, InBuff->Header.Opcode);
		    assert(RPC2_Unbind(workercid) == RPC2_SUCCESS);
		    continue;
		    }
		if ((rc = RPC2_CheckSideEffect(workercid, &sed, SE_AWAITLOCALSTATUS)) != RPC2_SUCCESS)
			{
			BulkErr(workercid, &sed, rc, InBuff->Header.Opcode);
			assert(RPC2_Unbind(workercid) == RPC2_SUCCESS);
			continue;
			}
		else
		    if (VerboseFlag)
			fprintf(stderr, "%ld bytes transferred\n",
				sed.Value.SmartFTPD.BytesTransferred);
		OutBuff->Header.ReturnCode = (long)sed.LocalStatus;
		OutBuff->Header.BodyLength = 0;
		break;
	    }

	    case 6: /* Store a random file */
		{
		if (VerboseFlag) sed.Value.SmartFTPD.hashmark = myhashmark;
		else sed.Value.SmartFTPD.hashmark = 0;
		strcpy(sed.Value.SmartFTPD.FileInfo.ByName.LocalFileName, myprivatefile);
		sed.Value.SmartFTPD.FileInfo.ByName.ProtectionBits = 0644;
		sed.Value.SmartFTPD.TransmissionDirection = CLIENTTOSERVER;
		sed.Value.SmartFTPD.SeekOffset = 0;
		sed.Value.SmartFTPD.Tag = FILEBYNAME;
		
		if ((rc = RPC2_InitSideEffect(workercid, &sed)) != RPC2_SUCCESS)
			{
			BulkErr(workercid, &sed, rc, InBuff->Header.Opcode);
			}
		if ((rc = RPC2_CheckSideEffect(workercid, &sed, SE_AWAITLOCALSTATUS)) != RPC2_SUCCESS)
			{
			BulkErr(workercid, &sed, rc, InBuff->Header.Opcode);
			}
		else
		    if (VerboseFlag)
			fprintf(stderr, "%ld bytes transferred\n",
				sed.Value.SmartFTPD.BytesTransferred);
		OutBuff->Header.ReturnCode = (long)sed.LocalStatus;
		OutBuff->Header.BodyLength = 0;
		break;
		}

	    case 7:	/* Unbind */
		{
		OutBuff->Header.ReturnCode = RPC2_SUCCESS;
		OutBuff->Header.BodyLength = 0;
		break;
		}

	    case 999: /* Quit */
		{
		OutBuff->Header.ReturnCode = RPC2_SUCCESS;
		OutBuff->Header.BodyLength = 0;
		break;
		}

	    default: /* unknown opcode */
		OutBuff->Header.ReturnCode = RPC2_FAIL;
		OutBuff->Header.BodyLength = 1 + strlen("Get your act together");
		strcpy((char *)OutBuff->Body, "Get your act together");
	    break;
	    }


	i = RPC2_SendResponse(workercid, OutBuff);
	if (i != RPC2_SUCCESS) 
	    {
	    printf ("\n%s: response for opcode %d on connection %#x  failed (%s) at %s", 
		MYNAME,	InBuff->Header.Opcode, workercid,
		RPC2_ErrorMsg(i), TimeNow());
	    DumpAndQuit(InBuff->Header.Opcode);
	    }
	if (InBuff->Header.Opcode == 7)
	    assert(RPC2_Unbind(workercid) == RPC2_SUCCESS);
	}
}