Exemplo n.º 1
0
UDPSocketPair*  UDPSocketPool::CreateUDPSocketPair(UInt32 inAddr, UInt16 inPort)
{
    OSMutexLocker locker(&fMutex);
    UDPSocketPair* theElem = ConstructUDPSocketPair();
    Assert(theElem != NULL);
    if (theElem->fSocketA->Open() != OS_NoErr)
    {
        this->DestructUDPSocketPair(theElem);
        return NULL;
    }
    if (theElem->fSocketB->Open() != OS_NoErr)
    {
        this->DestructUDPSocketPair(theElem);
        return NULL;
    }
    
    // Set socket options on these new sockets
    this->SetUDPSocketOptions(theElem);
    
    //try to find an open pair of ports to bind these suckers tooo
    Bool16 foundPair = false;
    
    //If port is 0, then the caller doesn't care what port # we bind this socket to.
    //Otherwise, ONLY attempt to bind this socket to the specified port
    UInt16 startIndex = kLowestUDPPort;
    if (inPort != 0)
        startIndex = inPort;
    UInt16 stopIndex = kHighestUDPPort;
    if (inPort != 0)
        stopIndex = inPort;
        
    while ((!foundPair) && (startIndex <= kHighestUDPPort))
    {
        OS_Error theErr = theElem->fSocketA->Bind(inAddr, startIndex);
        if (theErr == OS_NoErr)
        {
            theErr = theElem->fSocketB->Bind(inAddr, startIndex+1);
            if (theErr == OS_NoErr)
            {
                foundPair = true;
                fUDPQueue.EnQueue(&theElem->fElem);
                theElem->fRefCount++;
                return theElem;
            }
        }
        //If we are looking to bind to a specific port set, and we couldn't then
        //just break it out here.
        if (inPort != 0)
            break;
        startIndex += 2;
    }
    //if we couldn't find a pair of sockets, make sure to clean up our mess
    this->DestructUDPSocketPair(theElem);
    return NULL;
}
Exemplo n.º 2
0
UDPSocketPair*  UDPSocketPool::CreateUDPSocketPair(UInt32 inAddr, UInt16 inPort)
{
   //try to find an open pair of ports to bind these suckers tooo
    OSMutexLocker locker(&fMutex);
    UDPSocketPair* theElem = NULL;
    Bool16 foundPair = false;
    UInt16 curPort = kLowestUDPPort;
    UInt16 stopPort = kHighestUDPPort -1; // prevent roll over when iterating over port nums
    UInt16 socketBPort = kLowestUDPPort + 1;
    
    //If port is 0, then the caller doesn't care what port # we bind this socket to.
    //Otherwise, ONLY attempt to bind this socket to the specified port
     if (inPort != 0)
        curPort = inPort;
     if (inPort != 0)
        stopPort = inPort;
        

    while ((!foundPair) && (curPort < kHighestUDPPort))
    {
        socketBPort = curPort +1; // make socket pairs adjacent to one another
        
        theElem = ConstructUDPSocketPair();
        Assert(theElem != NULL);
        if (theElem->fSocketA->Open() != OS_NoErr)
        {
            this->DestructUDPSocketPair(theElem);
            return NULL;
        }
        if (theElem->fSocketB->Open() != OS_NoErr)
        {
            this->DestructUDPSocketPair(theElem);
            return NULL;
        }
            
        // Set socket options on these new sockets
        this->SetUDPSocketOptions(theElem);
        
        OS_Error theErr = theElem->fSocketA->Bind(inAddr, curPort);
        if (theErr == OS_NoErr)
        {   //qtss_printf("fSocketA->Bind ok on port%u\n", curPort);
            theErr = theElem->fSocketB->Bind(inAddr, socketBPort);
            if (theErr == OS_NoErr)
            {   //qtss_printf("fSocketB->Bind ok on port%u\n", socketBPort);
                foundPair = true;
                fUDPQueue.EnQueue(&theElem->fElem);
                theElem->fRefCount++;
                return theElem;
            }
            //else qtss_printf("fSocketB->Bind failed on port%u\n", socketBPort);
         }
         //else qtss_printf("fSocketA->Bind failed on port%u\n", curPort);
 
        //If we are looking to bind to a specific port set, and we couldn't then
        //just break here.
        if (inPort != 0)
            break;
            
        if (curPort >= stopPort) //test for stop condition
            break;
            
        curPort += 2; //try a higher port pair
        
        this->DestructUDPSocketPair(theElem); //a bind failure
        theElem = NULL;
    }
    //if we couldn't find a pair of sockets, make sure to clean up our mess
    if (theElem != NULL)
        this->DestructUDPSocketPair(theElem); 
       
    return NULL;
}