Exemple #1
0
uint32_t UDPRead(HSOCKET hSocket, uint8_t * pbRead, uint16_t cbRead, IPSTATUS * pStatus)
{
    UDPSOCKET *     pSocket     = (UDPSOCKET *) hSocket;

    uint32_t cb = 0;

    if(pSocket != NULL)
    {
        SMGR *  pSMGR = alloca(pSocket->cbRxSMGR);

        if(pSMGR != NULL && (SMGRRead((HSMGR) &pSocket->smgrRxBuff, 0, pSMGR, pSocket->cbRxSMGR) == pSocket->cbRxSMGR))
        {
            cb = UDPPeekSMGR(pSocket, (HSMGR) pSMGR, 0, pbRead, cbRead, pStatus);

            // if this is the whole datagram
            // note, the > part should never happen, cb should always
            // be cb <= pSocket->cbNextDataGram and this condition
            // should be cb == pSocket->cbNextDataGram; but should somehow
            // > happen, this will offer some correction
            if(cb >= pSocket->cbNextDataGram)
            {
                // move the begining to the next datagram
                SMGRMoveEnd((HSMGR) pSMGR, cb + sizeof(uint16_t), SMGRAtBegining);

                // read the next 2 bytes for the datagarm size if it exists
                if(SMGRRead((HSMGR) pSMGR, 0, &pSocket->cbNextDataGram, sizeof(uint16_t)) != sizeof(uint16_t))
                {
                    pSocket->cbNextDataGram = 0;
                }
            }

            // otherwise it is a partial datagram read
            else
            {
                // move the begining to after what we read, but leave room to
                // write the remaining datagram size
                SMGRMoveEnd((HSMGR) pSMGR, cb, SMGRAtBegining);

                // update the remaining datagram size
                pSocket->cbNextDataGram -= cb;
                SMGRWrite((HSMGR) pSMGR, 0, &pSocket->cbNextDataGram, sizeof(uint16_t));
            }

            // save away the table that is stored on the stack
            // this should not fail! It is a fixed size and already allocated
            SMGRWrite((HSMGR) &pSocket->smgrRxBuff, 0, pSMGR, pSocket->cbRxSMGR);
        }
    }

    return(cb);
}
Exemple #2
0
/*****************************************************************************
  Function:
	uint32_t TCPPeekSMGR(TCPSOCKET * pSocket, HSMGR pSMGR, uint8_t * pbRead, uint16_t cbRead, IPSTATUS * pStatus)

  Description:
        Reads bytes out of the receive buffer but does not move the unread pointer,
        peek or receive will return the same data.

  Parameters:
	pSocket:        The socket to read the bytes from
        pSMGR:          pointer to an open stream
        pbRead:         A buffer to receive the data
        cbRead:         Max size of the buffer to receive the data
        pStatus:        A pointer to a status variable to recieve the state of the socket as a status

  Returns:
        Number of bytes read

  ***************************************************************************/
static uint32_t TCPPeekSMGR(TCPSOCKET * pSocket, HSMGR pSMGR, uint16_t index, uint8_t * pbRead, uint16_t cbRead, IPSTATUS * pStatus)
{
    int32_t    cb = 0;
    IPSTATUS status = ipsSuccess;

    if(pSocket == NULL)
    {
        status = ipsSocketNULL;
    }
    else if(pbRead == NULL || cbRead == 0)
    {
        status =  ipsBufferNotDefined;
    }
    else if(pSocket->s.portRemote == portListen || pSocket->s.portRemote == portInvalid)
    {
        status =  ipsSocketNotResolved;
    }
    else if(pSMGR == NULL)
    {
        status = ipsNoSMGRGiven;
    }
    else
    {
        cb = SMGRRead((HSMGR) pSMGR, index, pbRead, min((SMGRcbStream(pSMGR) - index), cbRead));
    }

    AssignStatusSafely(pStatus, status);
    return(cb);
}
Exemple #3
0
static uint32_t UDPPeekSMGR(UDPSOCKET * pSocket, HSMGR pSMGR, uint16_t index, uint8_t * pbRead, uint16_t cbRead, IPSTATUS * pStatus)
{
    uint32_t    cb = 0;

    if(pSocket == NULL)
    {
        AssignStatusSafely(pStatus, ipsSocketNULL);
        return(0);
    }
    else if(pbRead == NULL || cbRead == 0)
    {
        AssignStatusSafely(pStatus, ipsBufferNotDefined);
        return(0);
    }
    else if(pSocket->s.portRemote == portListen || pSocket->s.portRemote == portInvalid)
    {
        AssignStatusSafely(pStatus, ipsSocketNotResolved);
        return(0);
    }

    cb = min((pSocket->cbNextDataGram - index), cbRead);
    if(cb > 0 && SMGRRead((HSMGR) pSMGR, (sizeof(uint16_t) + index), pbRead, cb) == cb)
    {
        return(cb);
    }

    return(0);
}
Exemple #4
0
void UDPClose(HSOCKET hSocket)
{
    UDPSOCKET *     pSocket     = (UDPSOCKET *) hSocket;
    UDPSOCKET *     pSocketCur  = NULL;

    // loop thru all listening sockets looking for this one
    while((pSocketCur = FFNext(&g_ffptListeningUDPSockets, pSocketCur)) != NULL)
    {
        // see if we found it
        if(pSocket == pSocketCur)
        {
            SMGR *      pSMGR = alloca(pSocket->cbRxSMGR);

            // remove it from the listening list
            FFRemove(&g_ffptListeningUDPSockets, pSocket);

            if(pSMGR != NULL && (SMGRRead((HSMGR) &pSocket->smgrRxBuff, 0, pSMGR, pSocket->cbRxSMGR) == pSocket->cbRxSMGR))
            {
                // free the datastream
                SMGRFree((HSMGR) pSMGR);
                // don't need to write back because these pages are all getting freed as well
            }

            // free what is in the socket as well
            // this is why we don't have to write back
            SMGRFree((HSMGR) &pSocket->smgrRxBuff);

            // clear the socket
            IPSReleaseSocket((TCPSOCKET *) pSocket);
            return;
        }
    }

    return;
}
Exemple #5
0
uint32_t UDPPeekIdx(HSOCKET hSocket, uint32_t index, uint8_t * pbRead, uint16_t cbRead, IPSTATUS * pStatus)
{
    UDPSOCKET *     pSocket     = (UDPSOCKET *) hSocket;

    if(pSocket != NULL)
    {
        SMGR *  pSMGR = alloca(pSocket->cbRxSMGR);

        if(pSMGR != NULL && (SMGRRead((HSMGR) &pSocket->smgrRxBuff, 0, pSMGR, pSocket->cbRxSMGR) == pSocket->cbRxSMGR))
        {
            // because we are only READing, no need to update the stream tables
            return(UDPPeekSMGR(pSocket, (HSMGR) pSMGR, index, pbRead, cbRead, pStatus));
        }
    }

    return(0);
}
Exemple #6
0
/*****************************************************************************
  Function:
	uint32_t TCPPeek(SOCKET *  pSocket, void * pv, uint32_t cb, IPSTATUS * pStatus)

  Description:
        Reads bytes out of the receive buffer but does not move the unread pointer,
        peek or receive will return the same data.

  Parameters:
	hSocket:        The socket to read the bytes from
        index:          Number of bytes in to start the peek
        pbRead:         A buffer to receive the data
        cbRead:         Max size of the buffer to receive the data
        pStatus:        A pointer to a status variable to recieve the state of the socket as a status

  Returns:
        Number of bytes read

  ***************************************************************************/
uint32_t TCPPeekIdx(HSOCKET hSocket, uint32_t index, void * pbRead, uint32_t cbRead, IPSTATUS * pStatus)
{
    TCPSOCKET *     pSocket     = (TCPSOCKET *) hSocket;
    IPSTATUS        status      = ipsSocketNULL;

    if(pSocket != NULL && pSocket->cbRxSMGR > 0)
    {
        SMGR *  pSMGR = (SMGR*)alloca(pSocket->cbRxSMGR);

        if(SMGRRead((HSMGR) &pSocket->smgrRxTxBuff, 0, pSMGR, pSocket->cbRxSMGR) == pSocket->cbRxSMGR)
        {
            // because we are only READing, no need to update the stream tables
            return(TCPPeekSMGR(pSocket, (HSMGR) pSMGR, (uint16_t) index, (u8*)pbRead, cbRead, pStatus));
        }
        status = ipsFailedToReadStreamBuffer;
    }

    AssignStatusSafely(pStatus, status);
    return(0);
}
Exemple #7
0
void UDPDiscard(HSOCKET hSocket)
{
    UDPSOCKET *     pSocket     = (UDPSOCKET *) hSocket;

    if(pSocket != NULL)
    {
        SMGR *  pSMGR = alloca(pSocket->cbRxSMGR);

        if(pSMGR != NULL && (SMGRRead((HSMGR) &pSocket->smgrRxBuff, 0, pSMGR, pSocket->cbRxSMGR) == pSocket->cbRxSMGR))
        {
            uint32_t iEnd = SMGRcbStream(pSMGR);

            SMGRMoveEnd((HSMGR) pSMGR, iEnd, SMGRAtBegining);

            // save away the table that is stored on the stack
            // this should not fail! It is a fixed size and already allocated
            SMGRWrite((HSMGR) &pSocket->smgrRxBuff, 0, pSMGR, pSocket->cbRxSMGR);
        }
    }
}
Exemple #8
0
/*****************************************************************************
  Function:
	uint32_t TCPRead(SOCKET *  pSocket, void * pv, uint32_t cb, IPSTATUS * pStatus)

  Description:
        Reads bytes out of the receive buffer. We call this receive instead of read because RFC 793 calls it receive.

  Parameters:
	pSocket:        The socket to read the bytes from
        pv:             A buffer to receive the data
        cb:             Max size of the buffer to receive the data
        pStatus:        A pointer to a status variable to recieve the state of the socket as a status

  Returns:
        Number of bytes read

  ***************************************************************************/
uint32_t TCPRead(HSOCKET hSocket, void * pbRead, uint32_t cbRead, IPSTATUS * pStatus)
{
    TCPSOCKET *     pSocket     = (TCPSOCKET *) hSocket;
    IPSTATUS        status      = ipsSocketNULL;
    uint32_t cb = 0;

    if(pSocket != NULL && pSocket->cbRxSMGR > 0)
    {
        SMGR *  pSMGR = (SMGR*)alloca(pSocket->cbRxSMGR);

        if(SMGRRead((HSMGR) &pSocket->smgrRxTxBuff, 0, pSMGR, pSocket->cbRxSMGR) == pSocket->cbRxSMGR)
        {
            cb = TCPPeekSMGR(pSocket, (HSMGR) pSMGR, 0, (u8*)pbRead, cbRead, &status);

            if(cb > 0)
            {
                // move the begining to after what we read
                SMGRMoveEnd((HSMGR) pSMGR, cb, SMGRAtBegining);

                // apply the read bytes to our base
                pSocket->rcvIRS += cb;

                // and now fix up to the base
                pSocket->rcvNXT -= cb;
                pSocket->rcvUP  -= cb;
//                pSocket->rcvSeqAhead -= cb;
            }

            // save away the table that is stored on the stack
            // this should not fail! It is a fixed size and already allocated
            SMGRWrite((HSMGR) &pSocket->smgrRxTxBuff, 0, pSMGR, pSocket->cbRxSMGR);
        }
        else
        {
            status = ipsFailedToReadStreamBuffer;
        }
    }

    AssignStatusSafely(pStatus, status);
    return(cb);
}
Exemple #9
0
/*****************************************************************************
  Function:
	uint32_t TCPSend(SOCKET *  pSocket, const void * pv, uint32_t cb, IPSTATUS * pStatus)

  Description:
         Stuff data into the socket to be sent on the next regularly scheduled send. Because of congestion
         control, this may take up to a fraction of a second to send. If you want it to go out immediately
         then call TCPFlush on the socket immediately after this call.

  Parameters:
	pSocket:        The socket to send the data on

        pv:             a pointer to a buffer of data to send

        cbReq:          The number of bytes to send.

        pStatus:        A pointer to a status variable to recieve the state of the send

  Returns:
        Number of bytes actually sent, could be less than requested if the socket is full.

  ***************************************************************************/
uint32_t TCPWrite(HSOCKET hSocket, const void * pv, uint32_t cbReq, IPSTATUS * pStatus)
{
    TCPSOCKET * pSocket = (TCPSOCKET *) hSocket;
    uint32_t    cb      = 0;

    if(pSocket == NULL)
    {
        AssignStatusSafely(pStatus, ipsSocketNULL);
        return(0);
    }

    // we can only write data if we are in the established state
    if(TCPIsEstablished(pSocket, pStatus))
    {
        SMGR *  pSMGR = (SMGR*)alloca(pSocket->cbTxSMGR);

        if(cbReq > 0 && pSMGR != NULL && (SMGRRead((HSMGR) &pSocket->smgrRxTxBuff, pSocket->cbRxSMGR, pSMGR, pSocket->cbTxSMGR) == pSocket->cbTxSMGR))
        {

            // This may seem like an odd place to do this, but I will update the sndUNA pointers here
            // I do this here instead of in the ACK processing because I do not want to take the time to open up the
            // stream in the ACK process, I just want to update the sndUNA pointer and move on. The downside of this is that
            // we may hold some pages longer than we need, but before I take MORE memory in the write, I will free those pages
            // which is why I will do that here before we WRITE our data below.
            TCPScaleSndIndexes(pSocket, pSMGR);

            // after we have scaled our pointers and potentially released some memory, we can
            // write as much data as we can to the stream
            cb  = SMGRWrite((HSMGR) pSMGR, SMGRcbStream(pSMGR), pv, cbReq);
            pSocket->sndEND += cb;

            // save away the table that is stored on the stack
            // this should not fail! It is a fixed size and already allocated
            SMGRWrite((HSMGR) &pSocket->smgrRxTxBuff, pSocket->cbRxSMGR, pSMGR, pSocket->cbTxSMGR);
        }
    }

    return(cb);
}
Exemple #10
0
uint32_t TCPAddRxDataToSocket(TCPSOCKET * pSocket, uint32_t seqNbr, uint8_t * pb, uint32_t cb)
{
    SMGR *      pSMGR = (SMGR*)alloca(pSocket->cbRxSMGR);
    uint32_t    rcvNXT = pSocket->rcvNXT + SEQBOUNDARY;

    // seqNbr is tricky, it has been normalized to rcvIRS
    // and may be very close to rcvUNR which is typically 0
    // so if seqNbr is < rcvNXT it could be less than rcvUNR, or an unsigned less than 0
    // or for an unsigned, very large; which would give us a false large seqNbr.
    // the MAX segment we can get is 64K, so as long as we scale this down so at least seqNbr + 64K < 2^^32, we can do a compare
    // and see if seqNbr < rcvNXT reliably. SEQBOUNDARY is 0x80000000 which is half way into the linear uint32_t range
    // scale seqNbr and rcvNXT and we can do a reliable < check.
    // Rip off data we have already received
    seqNbr += SEQBOUNDARY;
    if(seqNbr < rcvNXT)
    {
        pb += (rcvNXT - seqNbr);
        cb -= (rcvNXT - seqNbr);
    }

    // get our stream pointer
    if(cb > 0 && pSMGR != NULL && (SMGRRead((HSMGR) &pSocket->smgrRxTxBuff, 0, pSMGR, pSocket->cbRxSMGR) == pSocket->cbRxSMGR))
    {
        // write as much data as we can to the stream
        cb  = SMGRWrite((HSMGR) pSMGR, SMGRcbStream(pSMGR), pb, cb);

        // add the bytes written to our rcvNXT pointer
        pSocket->rcvNXT += cb;

        // save away the table that is stored on the stack
        // this should not fail! It is a fixed size and already allocated
        SMGRWrite((HSMGR) &pSocket->smgrRxTxBuff, 0, pSMGR, pSocket->cbRxSMGR);

        return(cb);
    }

    return(0);
}
Exemple #11
0
/*****************************************************************************
  Function:
	void TCPDiscard(SOCKET *  pSocket)

  Description:
        Discards all unread bytes in the sockets receive buffer.

  Parameters:
	hSocket:        The socket to clear the receive buffer from

  Returns:
        None

  ***************************************************************************/
void TCPDiscard(HSOCKET hSocket)
{
    TCPSOCKET *     pSocket     = (TCPSOCKET *) hSocket;

    if(pSocket != NULL && pSocket->cbRxSMGR > 0)
    {
        SMGR *  pSMGR = (SMGR*)alloca(pSocket->cbRxSMGR);

        if(SMGRRead((HSMGR) &pSocket->smgrRxTxBuff, 0, pSMGR, pSocket->cbRxSMGR) == pSocket->cbRxSMGR)
        {
            uint32_t iEnd = SMGRcbStream(pSMGR);

            // clear the stream by moving to the end
            SMGRMoveEnd((HSMGR) pSMGR, iEnd, SMGRAtBegining);

            // pretend like we read it
            // apply the read bytes to our base
            pSocket->rcvIRS += pSocket->rcvNXT;

            // and now fix up to the base
            pSocket->rcvNXT = 0;
            pSocket->rcvUP  = 0;
            
//            if(pSocket->rcvSeqAhead >= pSocket->rcvNXT)
//            {
//                pSocket->rcvSeqAhead -= pSocket->rcvNXT;
//            }
//            else
//            {
//                pSocket->rcvSeqAhead = 0;
//            }

            // save away the table that is stored on the stack
            // this should not fail! It is a fixed size and already allocated
            SMGRWrite((HSMGR) &pSocket->smgrRxTxBuff, 0, pSMGR, pSocket->cbRxSMGR);
        }
    }
}
Exemple #12
0
static uint32_t UDPProcessRx(IPSTACK * pIpStack, UDPSOCKET * pSocket)
{
    SMGR *      pSMGR = alloca(pSocket->cbRxSMGR);
    uint32_t    cbRet = 0;

    if(pIpStack->cbPayload > 0 && pSMGR != NULL && (SMGRRead((HSMGR) &pSocket->smgrRxBuff, 0, pSMGR, pSocket->cbRxSMGR) == pSocket->cbRxSMGR))
    {
        uint32_t iEnd = SMGRcbStream(pSMGR);

        // put in the size prefex
        uint32_t cbWritten = SMGRWrite((HSMGR) pSMGR, iEnd, &pIpStack->cbPayload, sizeof(uint16_t));

        // put in the data
        cbWritten += SMGRWrite((HSMGR) pSMGR, iEnd + cbWritten, pIpStack->pPayload, pIpStack->cbPayload);

        // check to see that we wrote everything.
        if(cbWritten == (pIpStack->cbPayload + sizeof(uint16_t)))
        {
            if(pSocket->cbNextDataGram == 0)
            {
                pSocket->cbNextDataGram = pIpStack->cbPayload;
            }
            cbRet = pIpStack->cbPayload;
        }

        // we failed to save, so discard the datagram and put the stream back to where it was
        else
        {
            SMGRMoveEnd((HSMGR) pSMGR, iEnd, SMGRAtEnding);
        }

        // save away the table that is stored on the stack
        // this should not fail! It is a fixed size and already allocated
        SMGRWrite((HSMGR) &pSocket->smgrRxBuff, 0, pSMGR, pSocket->cbRxSMGR);
    }

    return(cbRet);
}
Exemple #13
0
void TCPResetSocket(TCPSOCKET *  pSocket)
{
    if(pSocket == NULL || pSocket->smgrRxTxBuff.pPMGR == NULL)
    {
        return;
    }

    // fixup the seq nbr generator to make sure we don't reissue seqnbr less than before in time
    TCPFixupSeqNumber(pSocket->s.pLLAdp, pSocket->sndISS + pSocket->sndNXT);

    // clean up the socket if we were not listening
    if(pSocket->tcpState != tcpSynReceivedWhileListening)
    {
        uint16_t    cb      = pSocket->cbRxSMGR + pSocket->cbTxSMGR;
        SMGR *      pSMGR   = (SMGR*)alloca(cb);

        // remove it from the listening list
        FFRemove(&g_ffptActiveTCPSockets, pSocket);

        // this works
//        pSocket->sndISS = 0;
//          pSocket->tcpState = tcpUnassigned;
//        pSocket->fSocketOpen = false;
        
        // if this does not pass, we will have a memory leak
        // the alloca should always work.
        // this frees the Rx and Tx socket buffers
        if(SMGRRead((HSMGR) &pSocket->smgrRxTxBuff, 0, pSMGR, cb) == cb)
        {
            SMGRFree((HSMGR) pSMGR);
            SMGRFree((HSMGR) (((uint8_t *) pSMGR) + pSocket->cbRxSMGR));
        }

        // free the pointer to the RxTx streams.
        SMGRFree((HSMGR) &pSocket->smgrRxTxBuff);

        // release it back to the global pool if we got it from there
        IPSReleaseSocket(pSocket);

        // clean the socket
        // I am assuming this will not break us anywhere.
        memset(pSocket, 0, sizeof(TCPSOCKET));

        return;
    }

    // if we were listening, go back to listening
    // restore the socket to the listening state
    pSocket->s.portRemote = portListen;
    memset(&pSocket->s.ipRemote, 0, sizeof(IPv4or6));
    memset(&pSocket->s.macRemote, 0, sizeof(MACADDR));
    pSocket->tcpState   = tcpListen;
    pSocket->sndISS     = 0;

    // initalize the socket info
    pSocket->sndISS         = TCPGetSeqNumber(pSocket->s.pLLAdp);
    pSocket->sndNXT         = 0;
    pSocket->sndUNA         = 0;
    pSocket->sndEND         = 0;
    pSocket->sndWND         = 0;
    pSocket->sndPSH         = 0;
//    pSocket->sndWL2     = 0;
    pSocket->sndUP          = 0;
    pSocket->sndRTTComplete = 0;
    
    pSocket->rcvIRS         = 0;
    // pSocket->rcvUNR     = 0;
    pSocket->rcvNXT         = 0;
    pSocket->rcvUP          = 0;
//    pSocket->rcvSeqAhead = 0;

    pSocket->fGotFin        = false;
    pSocket->fSocketOpen    = false;

    // Jacobson rule
    pSocket->RTTsa      = RTTsaINIT;
    pSocket->RTTsv      = RTTsvINIT;
    pSocket->tRTO_SET   = RTO(pSocket);
    pSocket->tRTOCur    = pSocket->tRTO_SET;

}