#include <CoreFoundation/CoreFoundation.h>Go to the source code of this file.
Typedefs | |
| typedef enum PMProtocol | PMProtocol |
| typedef enum PMResult | PMResult |
| typedef enum PMRouterType | PMRouterType |
| typedef void(* | PMInitializeCallback )(PMResult result, void *context) |
| typedef void(* | PMGetPublicIPCallback )(CFStringRef ipAddress, void *context) |
| typedef void(* | PMAddPortMapCallback )(PMResult result, int publicPort, int privatePort, PMProtocol protocol, void *context) |
| typedef void(* | PMRemovePortMapCallback )(PMResult result, int publicPort, int privatePort, PMProtocol protocol, void *context) |
Enumerations | |
| enum | PMProtocol { kPMUDP_Protocol, kPMTCP_Protocol } |
| enum | PMResult { kPMSuccessful = 0, kPMInitializationError, kPMNotInitializedError, kPMNoRouterFoundError, kPMPortMappingError, kPMPortMappingInUseError, kPMNoSuchPortMappingError, kPMUnexpectedResult, kPMPortMappingDisabledError, kPMSamePortValuesRequired } |
| enum | PMRouterType { kPMUnknownRouter, kPMUPnPRouterType, kPMNAT_PMPRouterType } |
Functions | |
| PMResult | PMInitialize () |
| Initializes this port mapping library. | |
| void | PMInitializeAsync (PMInitializeCallback callback, CFRunLoopRef runLoop, void *context) |
| Initializes this port mapping library asynchronously. | |
| PMResult | PMAddPortMapping (int publicPort, int privatePort, PMProtocol protocol) |
| Asks the router to forward a port. | |
| void | PMAddPortMappingAsync (int publicPort, int privatePort, PMProtocol protocol, PMAddPortMapCallback callback, CFRunLoopRef runLoop, void *context) |
| Asks the router to forward a port asynchronously. | |
| PMResult | PMRemovePortMapping (int publicPort, int privatePort, PMProtocol protocol) |
| Asks the router to remove a port mapping. | |
| void | PMRemovePortMappingAsync (int publicPort, int privatePort, PMProtocol protocol, PMRemovePortMapCallback callback, CFRunLoopRef runLoop, void *context) |
| Asks the router to remove a port mapping asynchronously. | |
| CFStringRef | PMGetPublicIPAddress () |
| Asks the router for its Public IP. | |
| void | PMGetPublicIPAddressAsync (PMGetPublicIPCallback callback, CFRunLoopRef runLoop, void *context) |
| Asks the router for its Public IP asynchronously. | |
| CFStringRef | PMGetRouterName () |
| Returns the name of the router. | |
| PMRouterType | PMGetRouterType () |
| Returns the router type. | |
| void | PMSetRemoveAtExit (int flag) |
| Sets the remove at exit flag. | |
UPnP is Microsoft's and Intel's attempt to bring automatic plug-in play to network devices. Under their system network devices would broadcast, respond to searches, and through a http, XML, and SOAP a network application is suppose to interrogate the device to figure out what it does, and how to configure it. It works, but is rather complex and most implementations are rather flaky...
Apple looked at UPnP and thought MS and Intel are insane and never even looked back at UPnP, and have just recently made up their own protocol called NAT-PMP (http://files.dns-sd.org/draft-nat-port-mapping.txt ). It is a much simpler protocol, and is faster since it doesn't have the multiple back and forths, and the overhead of a SOAP call. The downside is that it is only supported in the Airport Express, and Airport Extreme base stations whose firmware has been updated to V6.2 (Which came with the Airport 4.2 update). By default the port mapping is disabled, and the user must enable it for this library to work properly (although it can still get the public IP address).
In general usage pattern is this:
All of the operations that require some network access have async versions that will execute the operation on a background thread, and then optionally notify the caller, either on their run loop, or the thread that we used to execute the operation. All of the async operations will be executed on the same background thread, so issuing two add port maps at the same time will cause the second add operation to be run after the first one completes. This way you can issue an add, and immediately a remove, and the remove will not start until the add has finished.
The only tricky part is with initializing the library. We haven't set up the locks yet, so it is not safe to call the initialization functions from two different threads at the same time. So make sure you either call PMInitialize() or PMInitializeAsync() from a single thread, before sending any more add or remove messages. It is perfectly safe to call the async initialize, and the async add function, before the async initialization has completed. The async add will be queued and executed after the initialization has completed. If the initialization failed, then the add will also fail with a kPMNotInitializedError. If you try to call a synchronous function while the async initializer is running it will fail and you will get a kPMNotInitializedError result.
The port maps that are inserted are set to expire after an hour. The library runs a refresh thread, that will update the expiration times every half hour. This way, if your program unexpectedly quits, the port map will eventually go away. While all NAT-PMP devices support expiration times (they don't actually allow you to use an infinite timeout), not all UPnP devices support expiration times, and those routers should default to inserting an infinite port mapping.
By default the Port Mapping lib will automatically remove any port mappings you added when your application exists. If you do not want this to happen you can disable it by calling PMSetRemoveAtExit() and pass in a 0.
If the user switches their default interface, or switches from wired to wireless, or their IP address, all of the port mappings you added have become invalid. Currently you have to detect this change and reinitialize the library by calling PMInitialize().
|
|
Callback is invoked when the PMAddPortMapAsync function finishes.
|
|
|
Callback is invoked when the PMGetPublicIPAsync function finishes.
|
|
|
Callback is invoked when the PMInitializeAsync function finishes.
|
|
|
The different networking protocols. |
|
|
Callback is invoked when the PMRemovePortMapAsync function finishes.
|
|
|
Result codes |
|
|
This library will support multiple port mapping types and these enums can be used to identify what type the router is. |
|
|
The different networking protocols. |
|
|
|
This library will support multiple port mapping types and these enums can be used to identify what type the router is. |
|
||||||||||||||||
|
Asks the router to forward a port. Sends a request to the router to map the given public port to the given private port on this computer. Not all routers support having a different public and private port, in which case this should return a kPMPortMappingInUseError;
|
|
||||||||||||||||||||||||||||
|
Asks the router to forward a port asynchronously. Sends a request to the router to map the given public port to the given private port on this computer on a background thread and notifies the callback when it has completed.
|
|
|
Asks the router for its Public IP. Asks the router to return its public or external IP address. The IP address is cached after the first call.
|
|
||||||||||||||||
|
Asks the router for its Public IP asynchronously. Asks the router to return its public or external IP address. The IP address is cached after the first call. The work is done on a background thread and the callback is notified when we are finished.
|
|
|
Returns the name of the router. Returns the name of the router. This really only works with the UPnP routers.
|
|
|
Returns the router type.
|
|
|
Initializes this port mapping library. This function will try to find a compatible router and sets up some globals. Currently only UPnP routers and NAT-PMP routers are supported. This function sets some global variables so it is NOT fully thread safe. It can be called by any thread, but two threads should not call this function at the same time. If the network configuration changes, you need to recall this method so that we can figure out how to talk to the new router. This will also clear any history we have about the port mappings that you have added.
|
|
||||||||||||||||
|
Initializes this port mapping library asynchronously. This function executes the PMInitialize() function on a background thread and notifies the callback when it has completed.
|
|
||||||||||||||||
|
Asks the router to remove a port mapping. Sends a request to the router to remove the port mapping identified by the given public port and the given private port. A call to remove the port mapping should match what was used when calling PMAddPortMapping().
|
|
||||||||||||||||||||||||||||
|
Asks the router to remove a port mapping asynchronously. Sends a request to the router to remove the port mapping identified by the given public port and the given private port. A call to remove the port mapping should match what was used when calling PMAddPortMapping(). The actual work of this function will be executed on a background thread and the callback will be notified when it is finished.
|
|
|
Sets the remove at exit flag. If this flag is set then we will try to remove any port mappings added when the program exits. If you want the port mapping to last longer, then set this to 0.
|
1.3.4