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; }
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; }
// this will free the socket if it can't open it TCPSOCKET * TCPInitSocket(const LLADP * pLLAdp, TCPSOCKET * pSocketOpen, HPMGR hPMGR, const void * pIPvXDest, uint16_t portRemote, uint16_t portLocal, IPSTATUS * pStatus) { IPSTATUS status = ipsSuccess; SMGR * pSMGR = NULL; uint32_t cb = 0; uint32_t cPages = 0; if(pSocketOpen == NULL) { AssignStatusSafely(pStatus, ipsSocketNULL); return(NULL); } else if(hPMGR == NULL) { AssignStatusSafely(pStatus, ipsNoPMGRGiven); } // find a port if(portLocal == portDynamicallyAssign) { portLocal = GetEphemeralPort(&g_ffptActiveTCPSockets, &g_nextTCPEphemeralPort); } // get the sequence number // we have to get this BEFORE we memset the socket // as the timewait may be the socket we are clearing. // also, if we are listening, we can only assign the sequence number // when we now our remote port and IP as to not duplicate and to watch seq numbers. if(portRemote != portListen) { SKTPORTPAIR portPair; // remote, local portPair.portRemote = portRemote; portPair.portLocal = portLocal; // worry about the 2MSL timewait issue, get an appropriate sequence number if(TCPIsInUse(pLLAdp, portPair.portPair, pIPvXDest)) { AssignStatusSafely(pStatus, ipsPortPairAndIPAlreadyActive); return(NULL); } } // build the stream manager to point to the page handler // first build the stream to the RxStream and TxStream // Rx is the 1st pSocketOpen->hPMGR = hPMGR; // calculate the size of the 2 embedded streams and how to partition the socket stream, stream // the Rx is the first indirect stream follwed by the Tx indirect stream in the socket stream cb = (1 << ((PMGR *) hPMGR)->pf2PerPage); cPages = ((PMGR *) hPMGR)->cPages; pSocketOpen->cbRxSMGR = GetSMGRSize(min(((cTCPRXPages * cb) - sizeof(SMGR)), cPages)); pSocketOpen->cbTxSMGR = GetSMGRSize(min(((cTCPTXPages * cb) - sizeof(SMGR)), cPages)); cb = pSocketOpen->cbRxSMGR + pSocketOpen->cbTxSMGR; if(SMGRInit(&pSocketOpen->smgrRxTxBuff, cbMAXTCPSreamRecord, hPMGR) != (HSMGR) &pSocketOpen->smgrRxTxBuff) { status = ispOutOfMemory; } else if((pSMGR = (SMGR*)alloca(cb)) == NULL) { status = ispOutOfMemory; } else if(SMGRInit(pSMGR, pSocketOpen->cbRxSMGR, hPMGR) == NULL || SMGRInit((SMGR *) (((uint8_t *) pSMGR) + pSocketOpen->cbRxSMGR), pSocketOpen->cbTxSMGR, hPMGR) == NULL) { status = ispOutOfMemory; } else if(SMGRWrite(&pSocketOpen->smgrRxTxBuff, 0, pSMGR, cb) != cb) { status = ispOutOfMemory; } AssignStatusSafely(pStatus, status); if(IsIPStatusAnError(status)) { SMGRFree((HSMGR) pSMGR); SMGRFree((HSMGR) (((uint8_t *) pSMGR) + pSocketOpen->cbRxSMGR)); SMGRFree((HSMGR) &pSocketOpen->smgrRxTxBuff); IPSReleaseSocket(pSocketOpen); return(NULL); } // make the socket pSocketOpen->tcpState = tcpAllocated; pSocketOpen->s.portLocal = portLocal; pSocketOpen->s.portRemote = portRemote; pSocketOpen->s.pLLAdp = pLLAdp; memcpy(&pSocketOpen->s.ipRemote, pIPvXDest, ILIPSize(pLLAdp)); // get a new seq nbr pSocketOpen->sndISS = TCPGetSeqNumber(pLLAdp); // max I will allow to come in. RFC 1122 4.2.2.6 pSocketOpen->cbLocalMSS = min((PMGRMaxAlloc(hPMGR) >> 2), (uint16_t) (LLGetMTUR(pLLAdp) - 20)); // Jacobson rule pSocketOpen->RTTsa = RTTsaINIT; pSocketOpen->RTTsv = RTTsvINIT; pSocketOpen->tRTO_SET = RTO(pSocketOpen); pSocketOpen->tRTOCur = pSocketOpen->tRTO_SET; return(pSocketOpen); }
HSOCKET UDPOpenWithSocket(const LLADP * pLLAdp, UDPSOCKET * pSocket, HPMGR hPMGR, const void * pIPvXDest, uint16_t portRemote, uint16_t portLocal, IPSTATUS * pStatus) { // uint32_t portPair = 0; IPSTATUS status = ipsSuccess; SMGR * pSMGR = NULL; uint32_t cb = 0; if(pLLAdp == NULL) { status = ipsAdaptorMustBeSpecified; } else if(pSocket == NULL) { status = ipsSocketNULL; } else if(hPMGR == NULL) { status = ipsNoPMGRGiven; } else if(pIPvXDest == NULL) { status = ipsIPAddressIsNull; } // get the local port else if(portLocal == portDynamicallyAssign) { portLocal = GetEphemeralPort(&g_ffptListeningUDPSockets, &g_nextUDPEphemeralPort); } AssignStatusSafely(pStatus, status); if(IsIPStatusAnError(status)) { return(NULL); } // build the stream manager to point to the page handler // first build the stream to the RxStream pSocket->hPMGR = hPMGR; if(SMGRInit(&pSocket->smgrRxBuff, cbMAXUDPSreamRecord, hPMGR) != (HSMGR) &pSocket->smgrRxBuff) { status = ispOutOfMemory; } else if((pSMGR = alloca((cb = GetSMGRSize(((PMGR *) hPMGR)->cPages)))) == NULL) { status = ispOutOfMemory; } else if(SMGRInit(pSMGR, cb, hPMGR) == NULL) { status = ispOutOfMemory; } else if(SMGRWrite(&pSocket->smgrRxBuff, 0, pSMGR, cb) != cb) { status = ispOutOfMemory; } AssignStatusSafely(pStatus, status); if(IsIPStatusAnError(status)) { SMGRFree((HSMGR) pSMGR); SMGRFree((HSMGR) &pSocket->smgrRxBuff); return(NULL); } pSocket->s.pLLAdp = pLLAdp; pSocket->s.portRemote = portRemote; pSocket->s.portLocal = portLocal; memcpy(&pSocket->s.ipRemote, pIPvXDest, ILIPSize(pLLAdp)); pSocket->cbRxSMGR = cb; // put on the listening list. FFInPacket(&g_ffptListeningUDPSockets, pSocket); // return the socket return(pSocket); }