Add even more of the source
This should be about everything needed to build so far?
This commit is contained in:
parent
af3619d4fa
commit
849723c9cf
547 changed files with 149239 additions and 0 deletions
152
CommonUtilitiesLib/UDPSocketPool.cpp
Normal file
152
CommonUtilitiesLib/UDPSocketPool.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: UDPSocketPool.cpp
|
||||
|
||||
Contains: Object that creates & maintains UDP socket pairs in a pool.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "UDPSocketPool.h"
|
||||
|
||||
UDPSocketPair* UDPSocketPool::GetUDPSocketPair(UInt32 inIPAddr, UInt16 inPort,
|
||||
UInt32 inSrcIPAddr, UInt16 inSrcPort)
|
||||
{
|
||||
OSMutexLocker locker(&fMutex);
|
||||
if ((inSrcIPAddr != 0) || (inSrcPort != 0))
|
||||
{
|
||||
for (OSQueueIter qIter(&fUDPQueue); !qIter.IsDone(); qIter.Next())
|
||||
{
|
||||
//If we find a pair that is a) on the right IP address, and b) doesn't
|
||||
//have this source IP & port in the demuxer already, we can return this pair
|
||||
UDPSocketPair* theElem = (UDPSocketPair*)qIter.GetCurrent()->GetEnclosingObject();
|
||||
if ((theElem->fSocketA->GetLocalAddr() == inIPAddr) &&
|
||||
((inPort == 0) || (theElem->fSocketA->GetLocalPort() == inPort)))
|
||||
{
|
||||
//check to make sure this source IP & port is not already in the demuxer.
|
||||
//If not, we can return this socket pair.
|
||||
if ((theElem->fSocketB->GetDemuxer() == NULL) ||
|
||||
((!theElem->fSocketB->GetDemuxer()->AddrInMap(0, 0)) &&
|
||||
(!theElem->fSocketB->GetDemuxer()->AddrInMap(inSrcIPAddr, inSrcPort))))
|
||||
{
|
||||
theElem->fRefCount++;
|
||||
return theElem;
|
||||
}
|
||||
//If port is specified, there is NO WAY a socket pair can exist that matches
|
||||
//the criteria (because caller wants a specific ip & port combination)
|
||||
else if (inPort != 0)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
//if we get here, there is no pair already in the pool that matches the specified
|
||||
//criteria, so we have to create a new pair.
|
||||
return this->CreateUDPSocketPair(inIPAddr, inPort);
|
||||
}
|
||||
|
||||
void UDPSocketPool::ReleaseUDPSocketPair(UDPSocketPair* inPair)
|
||||
{
|
||||
OSMutexLocker locker(&fMutex);
|
||||
inPair->fRefCount--;
|
||||
if (inPair->fRefCount == 0)
|
||||
{
|
||||
fUDPQueue.Remove(&inPair->fElem);
|
||||
this->DestructUDPSocketPair(inPair);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue