jens@0: // jens@0: // IPAddress.h jens@0: // MYNetwork jens@0: // jens@0: // Created by Jens Alfke on 1/4/08. jens@0: // Copyright 2008 Jens Alfke. All rights reserved. jens@0: // jens@0: jens@0: #import jens@0: jens@0: jens@2: /** Represents an Internet Protocol address and port number (similar to a sockaddr_in). jens@0: IPAddress itself only remembers the raw 32-bit IPv4 address; the subclass HostAddress jens@0: also remembers the DNS host-name. */ jens@0: @interface IPAddress : NSObject jens@0: { jens@32: @private jens@0: UInt32 _ipv4; // In network byte order (big-endian), just like struct in_addr jens@0: UInt16 _port; // native byte order jens@0: } jens@0: jens@0: /** Initializes an IPAddress from a host name (which may be a DNS name or dotted-quad numeric form) jens@0: and port number. jens@0: If the hostname is not in dotted-quad form, an instance of the subclass HostAddress will jens@0: be returned instead. */ jens@0: - (id) initWithHostname: (NSString*)hostname port: (UInt16)port; jens@0: jens@49: /** Creates an IPAddress from a host name (which may be a DNS name or dotted-quad numeric form) jens@49: and port number. jens@49: If the hostname is not in dotted-quad form, an instance of the subclass HostAddress will jens@49: be returned instead. */ jens@49: + (IPAddress*) addressWithHostname: (NSString*)hostname port: (UInt16)port; jens@49: jens@0: /** Initializes an IPAddress from a raw IPv4 address (in network byte order, i.e. big-endian) jens@0: and port number (in native byte order) */ jens@0: - (id) initWithIPv4: (UInt32)ipv4 port: (UInt16)port; jens@0: jens@0: /** Initializes an IPAddress from a raw IPv4 address (in network byte order, i.e. big-endian). jens@0: The port number defaults to zero. */ jens@0: - (id) initWithIPv4: (UInt32)ipv4; jens@0: jens@0: /** Initializes an IPAddress from a BSD struct sockaddr. */ jens@0: - (id) initWithSockAddr: (const struct sockaddr*)sockaddr; jens@0: jens@59: /** Initializes an IPAddress from NSData containing a BSD struct sockaddr. */ jens@59: - (id) initWithData: (NSData*)data; jens@59: jens@26: /** Returns the IP address of this host (plus the specified port number). jens@26: If multiple network interfaces are active, the main one's address is returned. */ jens@26: + (IPAddress*) localAddressWithPort: (UInt16)port; jens@26: jens@2: /** Returns the IP address of this host (with a port number of zero). jens@0: If multiple network interfaces are active, the main one's address is returned. */ jens@0: + (IPAddress*) localAddress; jens@0: jens@0: /** Returns the address of the peer that an open socket is connected to. jens@0: (This calls getpeername.) */ jens@0: + (IPAddress*) addressOfSocket: (CFSocketNativeHandle)socket; jens@0: jens@0: /** Returns YES if the two objects have the same IP address, ignoring port numbers. */ jens@0: - (BOOL) isSameHost: (IPAddress*)addr; jens@0: jens@0: /** The raw IPv4 address, in network (big-endian) byte order. */ jens@0: @property (readonly) UInt32 ipv4; // raw address in network byte order jens@0: jens@0: /** The address as a dotted-quad string, e.g. @"10.0.1.1". */ jens@0: @property (readonly) NSString* ipv4name; jens@0: jens@0: /** The address as a DNS hostname or else a dotted-quad string. jens@0: (IPAddress itself always returns dotted-quad; HostAddress returns the hostname it was jens@0: initialized with.) */ jens@0: @property (readonly) NSString* hostname; // dotted-quad string, or DNS name if I am a HostAddress jens@0: jens@0: /** The port number, or zero if none was specified, in native byte order. */ jens@0: @property (readonly) UInt16 port; jens@0: jens@59: /** The address as an NSData object containing a struct sockaddr. */ jens@59: @property (readonly) NSData* asData; jens@59: jens@0: /** Is this IP address in a designated private/local address range, such as 10.0.1.X? jens@0: If so, the address is not globally meaningful outside of the local subnet. */ jens@0: @property (readonly) BOOL isPrivate; // In a private/local addr range like 10.0.1.X? jens@0: @end jens@0: jens@0: jens@0: jens@0: /** A subclass of IPAddress that remembers the DNS hostname instead of a raw address. jens@0: An instance of HostAddress looks up its ipv4 address on the fly by calling gethostbyname. */ jens@0: @interface HostAddress : IPAddress jens@0: { jens@32: @private jens@0: NSString *_hostname; jens@0: } jens@0: jens@0: - (id) initWithHostname: (NSString*)hostname port: (UInt16)port; jens@0: jens@32: /** Initializes a HostAddress from a host name, plus a sockaddr struct and a port number. jens@32: (The port number overrides any port specified in the sockaddr struct.) */ jens@28: - (id) initWithHostname: (NSString*)hostname jens@28: sockaddr: (const struct sockaddr*)sockaddr jens@28: port: (UInt16)port; jens@28: jens@0: @end jens@0: jens@0: jens@0: jens@0: /** An IPAddress that can keep track of statistics on when it was last sucessfully used jens@0: and the number of successful attempts. This is useful when keeping a cache of recent jens@0: addresses for a peer that doesn't have a stable address. */ jens@0: @interface RecentAddress : IPAddress jens@0: { jens@32: @private jens@0: CFAbsoluteTime _lastSuccess; jens@0: UInt32 _successes; jens@0: } jens@0: jens@0: /** Initializes a RecentAddress from an IPAddress. (You can also initialize RecentAddress using jens@0: any inherited initializer method.) */ jens@0: - (id) initWithIPAddress: (IPAddress*)addr; jens@0: jens@0: /** The absolute time that -noteSuccess or -noteSeen was last called. */ jens@0: @property (readonly) CFAbsoluteTime lastSuccess; jens@0: jens@0: /** The number of times that -noteSuccess has been called. */ jens@0: @property (readonly) UInt32 successes; jens@0: jens@0: /** Call this to indicate that the address was successfully used to connect to the desired peer. jens@0: Returns YES if the state of the object has changed and it should be re-archived. */ jens@0: - (BOOL) noteSuccess; jens@0: jens@0: /** Call this to indicate that you have received evidence that this address is currently being jens@0: used by this peer. Unlike -noteSuccess it doesn't increment -successes, and only returns jens@0: YES (to indicate a persistent change) once every 18 hours (to avoid making the client jens@0: save its cache too often.) */ jens@0: - (BOOL) noteSeen; jens@0: jens@0: @end