TCP/TCPConnection.h
author morrowa
Tue Jun 23 12:46:40 2009 -0700 (2009-06-23)
changeset 53 e9f209a24d53
parent 26 cb9cdf247239
permissions -rw-r--r--
Connections opened by listeners now close correctly.
jens@0
     1
//
jens@0
     2
//  TCPConnection.h
jens@0
     3
//  MYNetwork
jens@0
     4
//
jens@0
     5
//  Created by Jens Alfke on 5/18/08.
jens@0
     6
//  Copyright 2008 Jens Alfke. All rights reserved.
jens@0
     7
//
jens@0
     8
jens@0
     9
#import "TCPEndpoint.h"
jens@8
    10
#import <Security/Security.h>
jens@0
    11
@class IPAddress;
jens@33
    12
@class TCPReader, TCPWriter, TCPListener, MYBonjourService;
jens@0
    13
@protocol TCPConnectionDelegate;
jens@0
    14
jens@0
    15
jens@0
    16
typedef enum {
jens@0
    17
    kTCP_Disconnected = -1,
jens@0
    18
    kTCP_Closed,
jens@0
    19
    kTCP_Opening,
jens@0
    20
    kTCP_Open,
jens@0
    21
    kTCP_Closing
jens@0
    22
} TCPConnectionStatus;
jens@0
    23
jens@0
    24
jens@0
    25
/** A generic class that manages a TCP socket connection.
jens@0
    26
    It creates a TCPReader and a TCPWriter to handle I/O.
jens@2
    27
    TCPConnection itself mostly deals with SSL setup and opening/closing the socket.
jens@2
    28
    (The SSL related methods are inherited from TCPEndpoint.) */
jens@0
    29
@interface TCPConnection : TCPEndpoint
jens@0
    30
{
jens@0
    31
    @private
jens@0
    32
    TCPListener *_server;
jens@0
    33
    IPAddress *_address;
jens@0
    34
    BOOL _isIncoming, _checkedPeerCert;
jens@0
    35
    TCPConnectionStatus _status;
jens@0
    36
    TCPReader *_reader;
jens@0
    37
    TCPWriter *_writer;
jens@0
    38
    NSError *_error;
jens@16
    39
    NSTimeInterval _openTimeout;
jens@0
    40
}
jens@0
    41
jens@0
    42
/** Initializes a TCPConnection to the given IP address.
jens@0
    43
    Afer configuring settings, you should call -open to begin the connection. */
jens@0
    44
- (id) initToAddress: (IPAddress*)address;
jens@0
    45
jens@7
    46
/** Initializes a TCPConnection to the given NSNetService's address and port.
jens@7
    47
    If the service's address cannot be resolved, nil is returned. */
jens@7
    48
- (id) initToNetService: (NSNetService*)service;
jens@7
    49
jens@33
    50
/** Initializes a TCPConnection to the given MYBonjourService's address and port.
jens@33
    51
    If the service's address cannot be resolved, nil is returned. */
jens@33
    52
- (id) initToBonjourService: (MYBonjourService*)service;
jens@33
    53
jens@0
    54
/** Initializes a TCPConnection from an incoming TCP socket.
jens@0
    55
    You don't usually need to call this; TCPListener does it automatically. */
jens@0
    56
- (id) initIncomingFromSocket: (CFSocketNativeHandle)socket listener: (TCPListener*)listener;
jens@0
    57
jens@16
    58
/** Timeout for waiting to open a connection. (Default is zero, meaning the OS default timeout.) */
jens@16
    59
@property NSTimeInterval openTimeout;
jens@16
    60
jens@0
    61
/** The delegate object that will be called when the connection opens, closes or receives messages. */
jens@0
    62
@property (assign) id<TCPConnectionDelegate> delegate;
jens@0
    63
jens@0
    64
/** The certificate(s) of the connected peer, if this connection uses SSL.
jens@0
    65
    The items in the array are SecCertificateRefs; use the Keychain API to work with them. */
jens@0
    66
@property (readonly) NSArray *peerSSLCerts;
jens@0
    67
jens@0
    68
/** Connection's current status */
jens@0
    69
@property (readonly) TCPConnectionStatus status;
jens@0
    70
jens@0
    71
/** Opens the connection. This happens asynchronously; wait for a delegate method to be called.
jens@0
    72
    You don't need to open incoming connections received via a TCPListener. */
jens@0
    73
- (void) open;
jens@0
    74
jens@0
    75
/** Closes the connection, after waiting for all in-progress messages to be sent or received.
jens@0
    76
    This happens asynchronously; wait for a delegate method to be called.*/
jens@0
    77
- (void) close;
jens@0
    78
jens@0
    79
/** Closes the connection, like -close, but if it hasn't closed by the time the timeout
jens@0
    80
    expires, it will disconnect the socket. */
jens@0
    81
- (void) closeWithTimeout: (NSTimeInterval)timeout;
jens@0
    82
jens@0
    83
/** Closes all open TCPConnections. */
jens@0
    84
+ (void) closeAllWithTimeout: (NSTimeInterval)timeout;
jens@0
    85
jens@0
    86
/** Blocks until all open TCPConnections close. You should call +closeAllWithTimeout: first. */
jens@0
    87
+ (void) waitTillAllClosed;
jens@0
    88
jens@0
    89
/** The IP address of the other peer. */
jens@7
    90
@property (readonly,retain) IPAddress *address;
jens@0
    91
jens@0
    92
/** The TCPListener that created this incoming connection, or nil */
jens@0
    93
@property (readonly) TCPListener *server;
jens@0
    94
jens@0
    95
/** Is this an incoming connection, received via a TCPListener? */
jens@0
    96
@property (readonly) BOOL isIncoming;
jens@0
    97
jens@0
    98
/** The fatal error, if any, 
jens@0
    99
    that caused the connection to fail to open or to disconnect unexpectedly. */
jens@0
   100
@property (readonly) NSError *error;
jens@0
   101
jens@0
   102
/** The actual security level of this connection. 
jens@0
   103
    Value is nil or one of the security level constants from NSStream.h,
jens@0
   104
    such as NSStreamSocketSecurityLevelTLSv1. */
jens@0
   105
@property (readonly) NSString* actualSecurityLevel;
jens@0
   106
jens@0
   107
jens@0
   108
@property (readonly) TCPReader *reader;
jens@0
   109
@property (readonly) TCPWriter *writer;
jens@0
   110
jens@0
   111
jens@0
   112
// protected:
jens@0
   113
- (Class) readerClass;
jens@0
   114
- (Class) writerClass;
jens@18
   115
- (void) _beginClose;
jens@19
   116
- (void) _unclose;
jens@0
   117
jens@0
   118
@end
jens@0
   119
jens@0
   120
jens@0
   121
jens@2
   122
/** The delegate messages sent by TCPConnection.
jens@2
   123
    All methods are optional. */
jens@0
   124
@protocol TCPConnectionDelegate <NSObject>
jens@0
   125
@optional
jens@0
   126
/** Called after the connection successfully opens. */
jens@0
   127
- (void) connectionDidOpen: (TCPConnection*)connection;
jens@0
   128
/** Called after the connection fails to open due to an error. */
jens@0
   129
- (void) connection: (TCPConnection*)connection failedToOpen: (NSError*)error;
jens@0
   130
/** Called when the identity of the peer is known, if using an SSL connection and the SSL
jens@0
   131
    settings say to check the peer's certificate.
jens@0
   132
    This happens, if at all, after the -connectionDidOpen: call. */
jens@0
   133
- (BOOL) connection: (TCPConnection*)connection authorizeSSLPeer: (SecCertificateRef)peerCert;
jens@26
   134
/** Called after the connection closes.
jens@26
   135
    You can check the connection's error property to see if it was normal or abnormal. */
jens@0
   136
- (void) connectionDidClose: (TCPConnection*)connection;
jens@0
   137
@end