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; }
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; }