PortMapper/MYPortMapper.h
author Jens Alfke <jens@mooseyard.com>
Fri Jul 24 14:06:28 2009 -0700 (2009-07-24)
changeset 63 5e4855a592ee
parent 26 cb9cdf247239
permissions -rw-r--r--
* The BLIPConnection receivedRequest: delegate method now returns BOOL. If the method returns NO (or if the method isn't implemented in the delegate), that means it didn't handle the message at all; an error will be returned to the sender.
* If the connection closes unexpectedly due to an error, then the auto-generated responses to pending requests will contain that error. This makes it easier to display a meaningful error message in the handler for the request.
     1 //
     2 //  MYPortMapper.m
     3 //  MYNetwork
     4 //
     5 //  Created by Jens Alfke on 1/4/08.
     6 //  Copyright 2008 Jens Alfke. All rights reserved.
     7 //
     8 
     9 #import "MYDNSService.h"
    10 @class IPAddress;
    11 
    12 
    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.
    16  
    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.)
    22  
    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.
    27  
    28     Typical usage is to:
    29     * Start a network service that listens for incoming connections on a port
    30     * Open a MYPortMapper
    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.
    35 */ 
    36 @interface MYPortMapper : MYDNSService
    37 {
    38     @private
    39     UInt16 _localPort, _desiredPublicPort;
    40     BOOL _mapTCP, _mapUDP;
    41     IPAddress *_publicAddress, *_localAddress;
    42 }
    43 
    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;
    48 
    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;
    54 
    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;
    58 
    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;
    63 
    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;
    70 
    71 /** The known public IPv4 address/port, once it's been determined.
    72     This property is KV observable. */
    73 @property (readonly,retain) IPAddress* publicAddress;
    74 
    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;
    79 
    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;
    83 
    84 
    85 // UTILITY CLASS METHOD:
    86 
    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;
    93 
    94 @end
    95 
    96 
    97 /** This notification is posted asynchronously when the status of a PortMapper
    98     (its error, publicAddress or publicPort) changes. */
    99 extern NSString* const MYPortMapperChangedNotification;