223 lines
7.7 KiB
C
223 lines
7.7 KiB
C
|
/**
|
||
|
* @file StreamPeerIO.h
|
||
|
* @author Ambroz Bizjak <ambrop7@gmail.com>
|
||
|
*
|
||
|
* @section LICENSE
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions are met:
|
||
|
* 1. Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer in the
|
||
|
* documentation and/or other materials provided with the distribution.
|
||
|
* 3. Neither the name of the author nor the
|
||
|
* names of its contributors may be used to endorse or promote products
|
||
|
* derived from this software without specific prior written permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*
|
||
|
* @section DESCRIPTION
|
||
|
*
|
||
|
* Object used for communicating with a peer over TCP.
|
||
|
*/
|
||
|
|
||
|
#ifndef BADVPN_CLIENT_STREAMPEERIO_H
|
||
|
#define BADVPN_CLIENT_STREAMPEERIO_H
|
||
|
|
||
|
#include <stdint.h>
|
||
|
|
||
|
#include <cert.h>
|
||
|
#include <keyhi.h>
|
||
|
|
||
|
#include <misc/debug.h>
|
||
|
#include <base/DebugObject.h>
|
||
|
#include <base/BLog.h>
|
||
|
#include <system/BReactor.h>
|
||
|
#include <system/BConnection.h>
|
||
|
#include <structure/LinkedList1.h>
|
||
|
#include <flow/PacketProtoDecoder.h>
|
||
|
#include <flow/PacketStreamSender.h>
|
||
|
#include <flow/SinglePacketBuffer.h>
|
||
|
#include <flow/PacketProtoEncoder.h>
|
||
|
#include <flow/PacketCopier.h>
|
||
|
#include <flow/PacketPassConnector.h>
|
||
|
#include <flow/StreamRecvConnector.h>
|
||
|
#include <flow/SingleStreamSender.h>
|
||
|
#include <client/PasswordListener.h>
|
||
|
|
||
|
/**
|
||
|
* Callback function invoked when an error occurs with the peer connection.
|
||
|
* The object has entered default state.
|
||
|
* May be called from within a sending Send call.
|
||
|
*
|
||
|
* @param user value given to {@link StreamPeerIO_Init}.
|
||
|
*/
|
||
|
typedef void (*StreamPeerIO_handler_error) (void *user);
|
||
|
|
||
|
/**
|
||
|
* Object used for communicating with a peer over TCP.
|
||
|
* The object has a logical state which can be one of the following:
|
||
|
* - default state
|
||
|
* - listening state
|
||
|
* - connecting state
|
||
|
*/
|
||
|
typedef struct {
|
||
|
// common arguments
|
||
|
BReactor *reactor;
|
||
|
BThreadWorkDispatcher *twd;
|
||
|
int ssl;
|
||
|
int ssl_flags;
|
||
|
uint8_t *ssl_peer_cert;
|
||
|
int ssl_peer_cert_len;
|
||
|
int payload_mtu;
|
||
|
int sock_sndbuf;
|
||
|
BLog_logfunc logfunc;
|
||
|
StreamPeerIO_handler_error handler_error;
|
||
|
void *user;
|
||
|
|
||
|
// persistent I/O modules
|
||
|
|
||
|
// base sending objects
|
||
|
PacketCopier output_user_copier;
|
||
|
PacketProtoEncoder output_user_ppe;
|
||
|
SinglePacketBuffer output_user_spb;
|
||
|
PacketPassConnector output_connector;
|
||
|
|
||
|
// receiving objects
|
||
|
StreamRecvConnector input_connector;
|
||
|
PacketProtoDecoder input_decoder;
|
||
|
|
||
|
// connection side
|
||
|
int mode;
|
||
|
|
||
|
union {
|
||
|
// listening data
|
||
|
struct {
|
||
|
int state;
|
||
|
PasswordListener *listener;
|
||
|
PasswordListener_pwentry pwentry;
|
||
|
sslsocket *sock;
|
||
|
} listen;
|
||
|
// connecting data
|
||
|
struct {
|
||
|
int state;
|
||
|
CERTCertificate *ssl_cert;
|
||
|
SECKEYPrivateKey *ssl_key;
|
||
|
BConnector connector;
|
||
|
sslsocket sock;
|
||
|
BSSLConnection sslcon;
|
||
|
uint64_t password;
|
||
|
SingleStreamSender pwsender;
|
||
|
} connect;
|
||
|
};
|
||
|
|
||
|
// socket data
|
||
|
sslsocket *sock;
|
||
|
BSSLConnection sslcon;
|
||
|
|
||
|
// sending objects
|
||
|
PacketStreamSender output_pss;
|
||
|
|
||
|
DebugObject d_obj;
|
||
|
} StreamPeerIO;
|
||
|
|
||
|
/**
|
||
|
* Initializes the object.
|
||
|
* The object is initialized in default state.
|
||
|
* {@link BLog_Init} must have been done.
|
||
|
* {@link BNetwork_GlobalInit} must have been done.
|
||
|
* {@link BSSLConnection_GlobalInit} must have been done if using SSL.
|
||
|
*
|
||
|
* @param pio the object
|
||
|
* @param reactor reactor we live in
|
||
|
* @param twd thread work dispatcher. May be NULL if ssl_flags does not request performing SSL
|
||
|
* operations in threads.
|
||
|
* @param ssl if nonzero, SSL will be used for peer connection
|
||
|
* @param ssl_flags flags passed down to {@link BSSLConnection_MakeBackend}. May be used to
|
||
|
* request performing SSL operations in threads.
|
||
|
* @param ssl_peer_cert if using SSL, the certificate we expect the peer to have
|
||
|
* @param ssl_peer_cert_len if using SSL, the length of the certificate
|
||
|
* @param payload_mtu maximum packet size as seen from the user. Must be >=0.
|
||
|
* @param sock_sndbuf socket SO_SNDBUF option. Specify <=0 to not set it.
|
||
|
* @param user_recv_if interface to use for submitting received packets. Its MTU
|
||
|
* must be >=payload_mtu.
|
||
|
* @param logfunc function which prepends the log prefix using {@link BLog_Append}
|
||
|
* @param handler_error handler function invoked when a connection error occurs
|
||
|
* @param user value to pass to handler functions
|
||
|
* @return 1 on success, 0 on failure
|
||
|
*/
|
||
|
int StreamPeerIO_Init (
|
||
|
StreamPeerIO *pio,
|
||
|
BReactor *reactor,
|
||
|
BThreadWorkDispatcher *twd,
|
||
|
int ssl,
|
||
|
int ssl_flags,
|
||
|
uint8_t *ssl_peer_cert,
|
||
|
int ssl_peer_cert_len,
|
||
|
int payload_mtu,
|
||
|
int sock_sndbuf,
|
||
|
PacketPassInterface *user_recv_if,
|
||
|
BLog_logfunc logfunc,
|
||
|
StreamPeerIO_handler_error handler_error,
|
||
|
void *user
|
||
|
) WARN_UNUSED;
|
||
|
|
||
|
/**
|
||
|
* Frees the object.
|
||
|
*
|
||
|
* @param pio the object
|
||
|
*/
|
||
|
void StreamPeerIO_Free (StreamPeerIO *pio);
|
||
|
|
||
|
/**
|
||
|
* Returns the interface for sending packets to the peer.
|
||
|
* The OTP warning handler may be called from within Send calls
|
||
|
* to the interface.
|
||
|
*
|
||
|
* @param pio the object
|
||
|
* @return interface for sending packets to the peer
|
||
|
*/
|
||
|
PacketPassInterface * StreamPeerIO_GetSendInput (StreamPeerIO *pio);
|
||
|
|
||
|
/**
|
||
|
* Starts an attempt to connect to the peer.
|
||
|
* On success, the object enters connecting state.
|
||
|
* On failure, the object enters default state.
|
||
|
*
|
||
|
* @param pio the object
|
||
|
* @param addr address to connect to
|
||
|
* @param password identification code to send to the peer
|
||
|
* @param ssl_cert if using SSL, the client certificate to use. This object does not
|
||
|
* take ownership of the certificate; it must remain valid until
|
||
|
* the object is reset.
|
||
|
* @param ssl_key if using SSL, the private key to use. This object does not take
|
||
|
* ownership of the key; it must remain valid until the object is reset.
|
||
|
* @return 1 on success, 0 on failure
|
||
|
*/
|
||
|
int StreamPeerIO_Connect (StreamPeerIO *pio, BAddr addr, uint64_t password, CERTCertificate *ssl_cert, SECKEYPrivateKey *ssl_key) WARN_UNUSED;
|
||
|
|
||
|
/**
|
||
|
* Starts an attempt to accept a connection from the peer.
|
||
|
* The object enters listening state.
|
||
|
*
|
||
|
* @param pio the object
|
||
|
* @param listener {@link PasswordListener} object to use for accepting a connection.
|
||
|
* The listener must have SSL enabled if and only if this object has
|
||
|
* SSL enabled. The listener must be available until the object is
|
||
|
* reset or {@link StreamPeerIO_handler_up} is called.
|
||
|
* @param password will return the identification code the peer should send when connecting
|
||
|
*/
|
||
|
void StreamPeerIO_Listen (StreamPeerIO *pio, PasswordListener *listener, uint64_t *password);
|
||
|
|
||
|
#endif
|