* Refactored MYPortMapper to use a new abstract base class MYDNSService; that way I can re-use it later for implementing Bonjour.
* Fixed issue #1: a memory leak in BLIPProperties, reported by codechemist.
5 // Created by Jens Alfke on 1/4/08.
6 // Copyright 2008 Jens Alfke. All rights reserved.
9 #import "MYDNSService.h"
13 /* MYPortMapper attempts to make a particular network port on this computer publicly reachable
14 for incoming connections, by "opening a hole" through a Network Address Translator
15 (NAT) or firewall that may be in between the computer and the public Internet.
17 The port mapping may fail if:
18 * the NAT/router/firewall does not support either the UPnP or NAT-PMP protocols;
19 * the device doesn't implement the protocols correctly (this happens);
20 * the network administrator has disabled port-mapping;
21 * there is a second layer of NAT/firewall (this happens in some ISP networks.)
23 The PortMapper is asynchronous. It will take a nonzero amount of time to set up the
24 mapping, and the mapping may change in the future as the network configuration changes.
25 To be informed of changes, either use key-value observing to watch the "error" and
26 "publicAddress" properties, or observe the MYPortMapperChangedNotification.
29 * Start a network service that listens for incoming connections on a port
31 * When the MYPortMapper reports the public address and port of the mapping, you somehow
32 notify other peers of that address and port, so they can connect to you.
33 * When the MYPortMapper reports changes, you (somehow) notify peers of the changes.
34 * When closing the network service, close the MYPortMapper object too.
36 @interface MYPortMapper : MYDNSService
39 UInt16 _localPort, _desiredPublicPort;
40 BOOL _mapTCP, _mapUDP;
41 IPAddress *_publicAddress, *_localAddress;
44 /** Initializes a PortMapper that will map the given local (private) port.
45 By default it will map TCP and not UDP, and will not suggest a desired public port,
46 but this can be configured by setting properties before opening the PortMapper. */
47 - (id) initWithLocalPort: (UInt16)localPort;
49 /** Initializes a PortMapper that will not map any ports.
50 This is useful if you just want to find out your public IP address.
51 (For a simplified, but synchronous, convenience method for this, see
52 +findPublicAddress.) */
53 - (id) initWithNullMapping;
55 /** Should the TCP or UDP port, or both, be mapped? By default, TCP only.
56 These properties have no effect if changed while the PortMapper is open. */
57 @property BOOL mapTCP, mapUDP;
59 /** You can set this to the public port number you'd like to get.
60 It defaults to 0, which means "no preference".
61 This property has no effect if changed while the PortMapper is open. */
62 @property UInt16 desiredPublicPort;
64 /** Blocks till the PortMapper finishes opening. Returns YES if it opened, NO on error.
65 It's not usually a good idea to use this, as it will lock up your application
66 until a response arrives from the NAT. Listen for asynchronous notifications instead.
67 If called when the PortMapper is closed, it will call -open for you.
68 If called when it's already open, it just returns YES. */
69 - (BOOL) waitTillOpened;
71 /** The known public IPv4 address/port, once it's been determined.
72 This property is KV observable. */
73 @property (readonly,retain) IPAddress* publicAddress;
75 /** The current local address/port, as of the time the port mapping was last updated.
76 The address part is of the main interface; the port is the specified local port.
77 This property is KV observable. */
78 @property (readonly,retain) IPAddress* localAddress;
80 /** Returns YES if a non-null port mapping is in effect:
81 that is, if the public address differs from the local one. */
82 @property (readonly) BOOL isMapped;
85 // UTILITY CLASS METHOD:
87 /** Determine the main interface's public IP address, without mapping any ports.
88 This method internally calls -waitTillOpened, so it may take a nontrivial amount
89 of time (and will crank the runloop while it waits.)
90 If you want to do this asynchronously, you should instead create a new
91 MYPortMapper instance using -initWithNullMapping. */
92 + (IPAddress*) findPublicAddress;
97 /** This notification is posted asynchronously when the status of a PortMapper
98 (its error, publicAddress or publicPort) changes. */
99 extern NSString* const MYPortMapperChangedNotification;