コード例 #1
0
void TCPServer::periodicTask(void)
{
    FFLL *      pffllServer = NULL;

    // look at all of the server objects
    while((pffllServer = (FFLL *) FFNext(&_ffptPeriodTask, pffllServer)) != NULL)
    {
        FFLL *      pffllSocket = NULL;
        TCPServer&  tcpServer = *((TCPServer *) (pffllServer->_this));      // for syntax sake

        if(ILIsIPSetup(tcpServer._pDEIPcK->_pLLAdp, NULL))
        {
            while((pffllSocket = (FFLL *) FFNext(&tcpServer._ffptSockets, pffllSocket)) != NULL)
            {
                TCPSocket& tcpSocket = *((TCPSocket *) (pffllSocket->_this));   // for syntax sake

                // start listening on available sockets
                if(tcpSocket._classState == ipsNotInitialized && tcpSocket._socket.tcpState < tcpInvalid)
                {
                    // get this listening
                    if(TCPOpenWithSocket(tcpSocket._pDEIPcK->_pLLAdp, &tcpSocket._socket, tcpSocket._hPMGR, &IPListen, portListen, tcpServer._listeningPort, NULL) == &tcpSocket._socket)
                    {
                        if(tcpSocket._socket.tcpState == tcpListen)
                        {
                            tcpSocket._classState = ipsListening;
                        }
                    }
                }
            }
        }
    }
}
コード例 #2
0
/***	bool TCPServer::getListeningEndPoint(IPEndPoint *pListeningEP)
**
**	Synopsis:   
**      Gets the endpoint that the server is listening on.
**      This is both the IP and port the server is on.
**
**	Parameters:
**      pLocalEP  A pointer to an IPEndPoint to receive the local endpoint information.
**
**	Return Values:
**      true    The local endpoint was returned.
**      false   The local endpoint is not known, usually because the connection was not set up yet.
**
**	Errors:
**      None
**
**  Notes:
**
**      If false is returned, then *pLocalEP will be garbage.
**
*/
bool TCPServer::getListeningEndPoint(IPEndPoint& epLocal)
{
    if(_pDEIPcK != NULL && ILIsIPSetup(_pDEIPcK->_pLLAdp, NULL))
    {
        ILGetMyIP(_pDEIPcK->_pLLAdp, &epLocal.ip);
        epLocal.port = _listeningPort;
        return(true);
    }

    return(false);
}
コード例 #3
0
ファイル: DNS.c プロジェクト: Digilent/vivado-library
// Notes on dnsNSMax and cDhcpNS. You would think that we should only cycle through cDhcpNS as this is the number
// DNS servers given to us by DHCP, however, sometimes DHCP does not give us good DNS servers and for the
// SNTP server to work, we need a good DNS server. So we continue to check the default, pre initialized google DNS
// servers after the DHCP DNS servers are checked first. If we get a lot of DNS servers from DHCP, then ultimately
// all of the pre installed google servers will be overwritten in the dnsNSMax list, but if we got a lot of DNS servers
// the assumption is that they are good ones. In particular, I found that Verizon did not give me very good DNS servers, they
// could not resolve the SNTP time servers.
static void DNSStateMachine(const LLADP * pLLAdp)
{
    IPSTATUS    status      = ipsSuccess;

    if(pLLAdp == NULL || pLLAdp->pDNSMem == NULL || !ILIsIPSetup(pLLAdp, NULL))
    {
        return;
    }

    switch(pLLAdp->pDNSMem->dnsState)
    {
        case dnsSend:
            if(pLLAdp->pDNSMem->dnsNSMax == 0)
            {
                pLLAdp->pDNSMem->dnsState = dnsReady;
                pLLAdp->pDNSMem->cTry = 0;
                break;
            }
            else if(pLLAdp->pDNSMem->cTry >= (pLLAdp->pDNSMem->dnsNSMax * DNSMINTRY))
            {
                if(pLLAdp->pDNSMem->iDNSCur == pLLAdp->pDNSMem->iDNSWorks)
                {
                    pLLAdp->pDNSMem->iDNSWorks = DNSiInvalid;
                }
                pLLAdp->pDNSMem->iDNSCur = DNSiInvalid;
                pLLAdp->pDNSMem->dnsState = dnsReady;
                pLLAdp->pDNSMem->cTry = 0;
                break;
            }
            else if(pLLAdp->pDNSMem->iDNSWorks < pLLAdp->pDNSMem->dnsNSMax)
            {
                pLLAdp->pDNSMem->iDNSCur = pLLAdp->pDNSMem->iDNSWorks;
            }
            else if(pLLAdp->pDNSMem->iDNSCur >= pLLAdp->pDNSMem->dnsNSMax)
            {
                pLLAdp->pDNSMem->iDNSCur = 0;
            }
            else
            {
                pLLAdp->pDNSMem->iDNSCur = (pLLAdp->pDNSMem->iDNSCur + 1) % pLLAdp->pDNSMem->dnsNSMax;
            }

            // set this up for an attempt to get the IP address
            memcpy(&pLLAdp->pDNSMem->socket.s.ipRemote, &pLLAdp->pDNSMem->dnsNS[pLLAdp->pDNSMem->iDNSCur], ILIPSize(pLLAdp));

            // fall thru on success

        case dnsReadySend:

            // clear the current IP address
            memset(&pLLAdp->pDNSMem->ip, 0, sizeof(IPv4or6));

            // just make this unique for this pass
            pLLAdp->pDNSMem->dnsDG.dnsHdr.ID++;

            // set my timers and counts
            pLLAdp->pDNSMem->cTry++;
            pLLAdp->pDNSMem->tTimeout = dnsWaitForRetry;
            pLLAdp->pDNSMem->tStart = SYSGetMilliSecond();

            // send out the DNS datagram
            UDPSend(&pLLAdp->pDNSMem->socket, (uint8_t *) &pLLAdp->pDNSMem->dnsDG, pLLAdp->pDNSMem->cbDNSDG, &status);

            // see if it went out.
            if(IsIPStatusAnError(status))
            {
                pLLAdp->pDNSMem->dnsState = dnsReady;
                pLLAdp->pDNSMem->cTry = 0;
            }
            else
            {
                pLLAdp->pDNSMem->dnsState = dnsWaiting;
            }
            break;

        case dnsWaiting:
            {
                uint16_t cbDG = UDPAvailable(&pLLAdp->pDNSMem->socket) ;
                IPSTATUS status;

                if(cbDG > sizeof(DNSHDR))
                {
                    // we need some space for the datagram
                    uint8_t     rgbDNSDG[DNSMAXUDPSIZE];
                    DNSDG *     pDNSDG  = (DNSDG *) rgbDNSDG;
                    uint8_t *   pEnd    = NULL;
                    uint8_t *   pCName  = NULL;
                    DNSRR *     pDNSRRA = NULL;

                    // read the DNS datagram
                    cbDG = UDPRead(&pLLAdp->pDNSMem->socket, rgbDNSDG, DNSMAXUDPSIZE, &status);

                    // There are some servers setting this and they should not! RFC 6195 2.1 and I need to ignore it
                    // Plus this is used internally to determine if we are in machine or network order. This is in network order right now.
                    pDNSDG->dnsHdr.Z = 0;

                    // now put in machine order.
                    cbDG = ExDNSDG(pDNSDG, cbDG);
                    pEnd = rgbDNSDG + cbDG;
                    
                    // if this is not a my response, keep waiting
                    // remember the ID is not exchanged, so network and machine order will have the same ID
                    if(!pDNSDG->dnsHdr.QR || pDNSDG->dnsHdr.ID != pLLAdp->pDNSMem->dnsDG.dnsHdr.ID)
                    {
                        break;
                    }

                    // ops and error occured, jump to finish with error
                    // go to the error state with no address found
                    if(pDNSDG->dnsHdr.RCODE != DNSRCODENoError)
                    {
                        // this is a failure case; go to the next DNS server
                        pLLAdp->pDNSMem->dnsState = dnsSend;
                        break;
                    }
                    
                    // get the canonical name for what we are looking for
                    // the first record is the question which has the name we used.
                    // we need to use the one in this datagram because we do memory range
                    // checking and if we use the QR we sent, it would be out of the memory range
                    pCName = DNSFindCName(pDNSDG, DNSRRAN, pDNSDG->rrRecords, pEnd);

                    // now find the A record
                    pDNSRRA = DNSFindRR(pDNSDG, NULL, DNSRRAN, DNSTYPEA, DNSCLASSIN, pCName, pEnd);

                    // if we got the A record we are done
                    if( pDNSRRA != NULL                                             &&
                        ((ILIsIPv6(pLLAdp)  &&  pDNSRRA->RDLENGTH == sizeof(IPv6))  ||
                         (!ILIsIPv6(pLLAdp) &&  pDNSRRA->RDLENGTH == sizeof(IPv4))  )   )
                    {
                        // copy in our result
                        memcpy(&pLLAdp->pDNSMem->ip, pDNSRRA->RDATA, pDNSRRA->RDLENGTH);

                        // say we are done
                        pLLAdp->pDNSMem->dnsState = dnsReady;
                        pLLAdp->pDNSMem->cTry = 0;

                        // We got an IP so we know this DNS server can work, remember that
                        if(pLLAdp->pDNSMem->iDNSCur < pLLAdp->pDNSMem->dnsNSMax)
                        {
                            pLLAdp->pDNSMem->iDNSWorks = pLLAdp->pDNSMem->iDNSCur;
                        }

                        // get out we found it and are done.
                        break;
                    }

                    // by default we will go to the next well know sever unless we pick up a better NS to go to
                    pLLAdp->pDNSMem->dnsState = dnsSend;

                    // we did not find anything, so update our DNS request to use the new CName
                    if(pCName != pDNSDG->rrRecords)
                    {
                        // make the new DNS packet with the CName instead of what we were using
                        uint16_t cbMax = DNSCreateIPv4QueryDN(pLLAdp, rgbDNSDG, pCName, pEnd, &pLLAdp->pDNSMem->dnsDG);
                        pLLAdp->pDNSMem->cbDNSDG = ExDNSDG(&pLLAdp->pDNSMem->dnsDG, cbMax);
                    }

                    // Didn't find an A record
                    // But maybe there is a name server we should try.
                    // If we asked for recursion and go it, no sense working the issue ourselves.
                    // likewise if there are now NS with IP addresses, no sense working the issue
                    if(!(pDNSDG->dnsHdr.RD && pDNSDG->dnsHdr.RA) && pDNSDG->dnsHdr.NSCOUNT > 0 && pDNSDG->dnsHdr.ARCOUNT > 0)
                    {
                        // this DNS server gave us something, so remember it
                        if(pLLAdp->pDNSMem->iDNSCur < pLLAdp->pDNSMem->dnsNSMax)
                        {
                            pLLAdp->pDNSMem->iDNSWorks = pLLAdp->pDNSMem->iDNSCur;
                        }

                        pDNSRRA = DNSFindNSARR(pDNSDG, pCName, pEnd, DNSTYPEA);

                        // if this looks like a good IP address to try, lets contact that name server
                        if(pDNSRRA != NULL && pDNSRRA->RDLENGTH == sizeof(IPv4))
                        {
                            // say were are not using one of our well known DNS servers
                            pLLAdp->pDNSMem->iDNSCur = DNSiInvalid;
                            
                            // Put the IP in our socket
                            memcpy(&pLLAdp->pDNSMem->socket.s.ipRemote, pDNSRRA->RDATA, pDNSRRA->RDLENGTH);
                            pLLAdp->pDNSMem->dnsState = dnsReadySend;
                        }
                    }

                    else if(pLLAdp->pDNSMem->iDNSWorks == pLLAdp->pDNSMem->iDNSCur)
                    {
                        pLLAdp->pDNSMem->iDNSWorks = DNSiInvalid;
                    }

                }
                else if((SYSGetMilliSecond() - pLLAdp->pDNSMem->tStart) >= pLLAdp->pDNSMem->tTimeout)
                {
                    pLLAdp->pDNSMem->dnsState = dnsWaitTry;
                }
            }
            break;

        case dnsWaitTry:

            if(pLLAdp->pDNSMem->iDNSWorks == pLLAdp->pDNSMem->iDNSCur)
            {
                pLLAdp->pDNSMem->iDNSWorks = DNSiInvalid;
            }
            
            if((pLLAdp->pDNSMem->cTry % DNSMINTRY) == 0)
            {
                pLLAdp->pDNSMem->dnsState = dnsSend;                
            }
            else
            {
                pLLAdp->pDNSMem->dnsState = dnsReadySend;
            }

            break;

        case dnsReady:
            pLLAdp->pDNSMem->cTry = 0;
            break;

        // noting to do here, either we have something in the DNS memory IP or not.
        case dnsRedirect:
        case dnsUninit:
        default:
            break;
    }
}
コード例 #4
0
ファイル: DNS.c プロジェクト: Digilent/vivado-library
// This is not a URL, this must be a domain nume such as www.foo.bar.com with an optional . at the end.
bool DNSResolve(const LLADP * pLLAdp, uint8_t const * const pchDomainName, uint32_t cchDomanName, void * pIPvX, IPSTATUS * pStatus)
{
    IPSTATUS    status = ipsSuccess;

    // see if we are initialized
    if(pLLAdp == NULL)
    {
        status = ipsAdaptorMustBeSpecified;
    }
    else if( !ILIsIPSetup(pLLAdp, &status) )
    {
        // do nothing, I got the status
    }
    else if(pLLAdp->pDNSMem == NULL || pLLAdp->pDNSMem->dnsState == dnsUninit)
    {
        status = ipsDNSIsNotInitialized;
    }
    else if(pchDomainName == NULL)
    {
        status = ipsDomainNameIsNULL;
    }
    else if(pIPvX == NULL)
    {
        status = ipsIPIsNULL;
    }

    // we are currently processing a DNS reqeust
    else if(pLLAdp->pDNSMem->dnsState != dnsReady)
    {
        // this is not the one we are working on!
        if(pLLAdp->pDNSMem->pchDomainName != pchDomainName)
        {
            status = ipsDNSIsInUse;
        }

        // this is the one we are working on, check to see if it is done.
        else
        {
            // go into the state machine.
            status = ipsDNSIsResolving;
        }
    }

    // we are done, see if we got it or not
    else if(pLLAdp->pDNSMem->pchDomainName == pchDomainName && pLLAdp->pDNSMem->cchDomainName == cchDomanName && strncmp((char *) pLLAdp->pDNSMem->pchDomainName, (char *) pchDomainName, cchDomanName) == 0)
    {
        if(ILIsIPv6(pLLAdp))
        {
            // have no idea
            if(memcmp(&pLLAdp->pDNSMem->ip.ipv6, &IPv6NONE, sizeof(IPv6)) == 0)
            {
                status = ipsDNSFailedToResolve;
            }
            // got it
            else
            {
                memcpy(pIPvX, &pLLAdp->pDNSMem->ip.ipv6, sizeof(IPv6));
            }
        }
        // IPv4
        else
        {
            // have no idea
            if(pLLAdp->pDNSMem->ip.ipv4.u32 == IPv4NONE.u32)
            {
                status = ipsDNSFailedToResolve;
            }
            // got it
            else
            {
                memcpy(pIPvX, &pLLAdp->pDNSMem->ip.ipv4, sizeof(IPv4));
            }
        }
    }

    // if we are ready, but he is asking for something else, start a new request.
    // check to see if the domain name starts with a number; as in IP address
    // TODO: IPv6 support
    else if(isdigit(*pchDomainName))
    {
        uint32_t i = 0;
        uint32_t j = 0;
        uint32_t k = 0;
        uint8_t const * pch = pchDomainName;
        
        if(ILIsIPv6(pLLAdp))
        {
            // TODO: do IPv6 support
        }
        else
        {    
            for(i=0; i<4; i++)
            {
                for(j=0, k=0; j<3 && isdigit(*pch); j++, pch++)
                {
                    k *= 10;
                    k += (*pch - '0');                    
                }
                
                if((i<3 && *pch == '.') || (i == 3 && (*pch == '/' || *pch == '\0')))
                {
                    ((IPv4 *) pIPvX)->u8[i] = (uint8_t) k;
                    pch++;
                }

                // if is clearly not an IP address
                // try it as a domain name
                else
                {
                    DNSStartIPv4Request(pLLAdp, pchDomainName, cchDomanName, &status);
                    break;
                }
            }
        
            if(status == ipsSuccess)
            {
                // pretend we got the IP
                pLLAdp->pDNSMem->ip.ipv4.u32 = ((IPv4 *) pIPvX)->u32;
                pLLAdp->pDNSMem->pchDomainName = pchDomainName;
                pLLAdp->pDNSMem->cchDomainName = cchDomanName;
            }
            else
            {
                memcpy(pIPvX, &IPv4NONE, sizeof(IPv4));
            }
        }
    }

    // otherwise we need to go look it up.
    else
    {
        DNSStartIPv4Request(pLLAdp, pchDomainName, cchDomanName, &status);
    }

    AssignStatusSafely(pStatus, status);
    return(status == ipsSuccess);
}