channel.h 9.01 KB
Newer Older
1 2 3 4 5 6
/*
	belle-sip - SIP (RFC3261) library.
    Copyright (C) 2010  Belledonne Communications SARL

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation, either version 2 of the License, or
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BELLE_SIP_CHANNEL_H
#define BELLE_SIP_CHANNEL_H

#ifndef WIN32
#include <sys/types.h>
#include <sys/socket.h>
#else

#endif

28
#define belle_sip_network_buffer_size 65535
29
#define belle_sip_send_network_buffer_size 16384
30 31 32 33 34 35

typedef enum belle_sip_channel_state{
	BELLE_SIP_CHANNEL_INIT,
	BELLE_SIP_CHANNEL_RES_IN_PROGRESS,
	BELLE_SIP_CHANNEL_RES_DONE,
	BELLE_SIP_CHANNEL_CONNECTING,
36
	BELLE_SIP_CHANNEL_RETRY,
37
	BELLE_SIP_CHANNEL_READY,
jehan's avatar
jehan committed
38 39
	BELLE_SIP_CHANNEL_ERROR,
	BELLE_SIP_CHANNEL_DISCONNECTED
40 41
}belle_sip_channel_state_t;

Simon Morlat's avatar
Simon Morlat committed
42
const char * belle_sip_channel_state_to_string(belle_sip_channel_state_t state);
43

44
/**
45 46
* belle_sip_channel_t is an object representing a single communication channel ( socket or file descriptor),
* unlike the belle_sip_listening_point_t that can owns several channels for TCP or TLS (incoming server child sockets or
47 48 49 50
* outgoing client sockets).
**/
typedef struct belle_sip_channel belle_sip_channel_t;

51
BELLE_SIP_DECLARE_INTERFACE_BEGIN(belle_sip_channel_listener_t)
Simon Morlat's avatar
Simon Morlat committed
52
void (*on_state_changed)(belle_sip_channel_listener_t *l, belle_sip_channel_t *, belle_sip_channel_state_t state);
53 54
void (*on_message_headers)(belle_sip_channel_listener_t *l, belle_sip_channel_t *obj, belle_sip_message_t *msg);
void (*on_message)(belle_sip_channel_listener_t *l, belle_sip_channel_t *obj, belle_sip_message_t *msg);
55
void (*on_sending)(belle_sip_channel_listener_t *l, belle_sip_channel_t *obj, belle_sip_message_t *msg);
jehan's avatar
jehan committed
56
int (*on_auth_requested)(belle_sip_channel_listener_t *l, belle_sip_channel_t *obj, const char* distinghised_name);
57 58
BELLE_SIP_DECLARE_INTERFACE_END

Simon Morlat's avatar
Simon Morlat committed
59
#define BELLE_SIP_CHANNEL_LISTENER(obj) BELLE_SIP_INTERFACE_CAST(obj,belle_sip_channel_listener_t)
jehan's avatar
jehan committed
60 61

typedef enum input_stream_state {
62 63 64
	WAITING_MESSAGE_START,
	MESSAGE_AQUISITION,
	BODY_AQUISITION
jehan's avatar
jehan committed
65 66
}input_stream_state_t;

67 68 69 70 71 72
typedef enum output_stream_state{
	OUTPUT_STREAM_IDLE,
	OUTPUT_STREAM_SENDING_HEADERS,
	OUTPUT_STREAM_SENDING_BODY
}output_stream_state_t;

jehan's avatar
jehan committed
73 74
typedef struct belle_sip_channel_input_stream{
	input_stream_state_t state;
75
	char buff[belle_sip_network_buffer_size];
jehan's avatar
jehan committed
76 77
	char* read_ptr;
	char* write_ptr;
jehan's avatar
jehan committed
78
	belle_sip_message_t *msg;
79 80 81
	int content_length;
	int chuncked_mode;
	int chunk_size;
82
	int chunk_read_size;
jehan's avatar
jehan committed
83 84 85
}belle_sip_channel_input_stream_t;

typedef struct belle_sip_stream_channel belle_sip_stream_channel_t;
jehan's avatar
jehan committed
86
typedef struct belle_sip_tls_channel belle_sip_tls_channel_t;
Simon Morlat's avatar
Simon Morlat committed
87

88 89
struct belle_sip_channel{
	belle_sip_source_t base;
90
	belle_sip_stack_t *stack;
Simon Morlat's avatar
Simon Morlat committed
91
	belle_sip_listening_point_t *lp; /*the listening point that owns this channel*/
92
	belle_sip_channel_state_t state;
93
	belle_sip_list_t *listeners;
Simon Morlat's avatar
Simon Morlat committed
94
	int ai_family;
95
	char *peer_cname;
96 97
	char *peer_name;
	int peer_port;
98 99
	char *local_ip;
	int local_port;
100 101
	char *public_ip;
	int public_port;
102
	belle_sip_resolver_context_t* resolver_ctx;
103
	struct addrinfo *peer_list;
104
	struct addrinfo *current_peer;
105
	belle_sip_list_t *outgoing_messages;
106 107 108 109 110
	belle_sip_message_t *cur_out_message;
	output_stream_state_t out_state;
	uint8_t *ewouldblock_buffer;
	size_t ewouldblock_size;
	size_t ewouldblock_offset;
jehan's avatar
jehan committed
111
	belle_sip_channel_input_stream_t input_stream;
112
	belle_sip_list_t* incoming_messages;
113
	belle_sip_source_t *inactivity_timer;
114
	uint64_t last_recv_time;
Simon Morlat's avatar
Simon Morlat committed
115
	int simulated_recv_return; /* used to simulate network error. 0= no data (disconnected) >0= do nothing -1= network error*/
116 117
	unsigned long bg_task_id;
	unsigned long recv_bg_task_id;
118 119
	unsigned char force_close; /* when channel is intentionnaly disconnected, in order to prevent looping notifications*/
	unsigned char learnt_ip_port;
120
	unsigned char has_name; /*set when the name of the peer is known, which is not the case of inboud connections*/
Simon Morlat's avatar
Simon Morlat committed
121
	unsigned char about_to_be_closed;
122
	unsigned char srv_overrides_port; /*set when this channel was connected to destination port provided by SRV resolution*/
123 124 125 126
};

#define BELLE_SIP_CHANNEL(obj)		BELLE_SIP_CAST(obj,belle_sip_channel_t)

jehan's avatar
jehan committed
127

128
BELLE_SIP_BEGIN_DECLS
Ghislain MARY's avatar
Ghislain MARY committed
129

130
void belle_sip_channel_add_listener(belle_sip_channel_t *chan, belle_sip_channel_listener_t *l);
131

132 133
void belle_sip_channel_remove_listener(belle_sip_channel_t *obj, belle_sip_channel_listener_t *l);

134
int belle_sip_channel_matches(const belle_sip_channel_t *obj, const belle_sip_hop_t *hop, const struct addrinfo *addr);
135

jehan's avatar
jehan committed
136
void belle_sip_channel_resolve(belle_sip_channel_t *obj);
137

jehan's avatar
jehan committed
138
void belle_sip_channel_connect(belle_sip_channel_t *obj);
139

Simon Morlat's avatar
Simon Morlat committed
140 141
void belle_sip_channel_prepare(belle_sip_channel_t *obj);

142
void belle_sip_channel_close(belle_sip_channel_t *obj);
143 144 145 146
/**
 *
 * returns number of send byte or <0 in case of error
 */
147 148 149
int belle_sip_channel_send(belle_sip_channel_t *obj, const void *buf, size_t buflen);

int belle_sip_channel_recv(belle_sip_channel_t *obj, void *buf, size_t buflen);
jehan's avatar
jehan committed
150 151
/*only used by channels implementation*/
void belle_sip_channel_set_ready(belle_sip_channel_t *obj, const struct sockaddr *addr, socklen_t slen);
152
void belle_sip_channel_init(belle_sip_channel_t *obj, belle_sip_stack_t *stack, const char *bindip,int localport, const char *peer_cname, const char *peername, int peer_port);
153
void belle_sip_channel_init_with_addr(belle_sip_channel_t *obj, belle_sip_stack_t *stack, const struct sockaddr *peer_addr, socklen_t addrlen);
Simon Morlat's avatar
Simon Morlat committed
154
void belle_sip_channel_set_socket(belle_sip_channel_t *obj, belle_sip_socket_t sock, belle_sip_source_func_t datafunc);
jehan's avatar
jehan committed
155
/*end of channel implementations*/
jehan's avatar
jehan committed
156
/**
Simon Morlat's avatar
Simon Morlat committed
157
 * Get a received message from the receive queue. This caller takes the ownership of the message.
jehan's avatar
jehan committed
158 159
 */
belle_sip_message_t* belle_sip_channel_pick_message(belle_sip_channel_t *obj);
160 161 162

int belle_sip_channel_queue_message(belle_sip_channel_t *obj, belle_sip_message_t *msg);

163 164
int belle_sip_channel_is_reliable(const belle_sip_channel_t *obj);

165
const char * belle_sip_channel_get_transport_name(const belle_sip_channel_t *obj);
jehan's avatar
jehan committed
166
const char * belle_sip_channel_get_transport_name_lower_case(const belle_sip_channel_t *obj);
167
char *belle_sip_channel_get_public_ip_port(belle_sip_channel_t *obj);
168

169 170
const struct addrinfo * belle_sip_channel_get_peer(belle_sip_channel_t *obj);

171 172
const char *belle_sip_channel_get_local_address(belle_sip_channel_t *obj, int *port);

Simon Morlat's avatar
Simon Morlat committed
173 174 175 176 177 178 179
/*
 * Returns a sip-uri suitable for using in record-route.
 * If the channel is not natted, it will return the listening port of the listening point corresponding to the channel.
**/
belle_sip_uri_t *belle_sip_channel_create_routable_uri(belle_sip_channel_t *chan);


Simon Morlat's avatar
Simon Morlat committed
180 181
#define belle_sip_channel_get_state(chan) ((chan)->state)

jehan's avatar
jehan committed
182 183
void channel_set_state(belle_sip_channel_t *obj, belle_sip_channel_state_t state);

Simon Morlat's avatar
Simon Morlat committed
184
/*just invokes the listeners to process data*/
jehan's avatar
jehan committed
185
int belle_sip_channel_process_data(belle_sip_channel_t *obj,unsigned int revents);
186

Simon Morlat's avatar
Simon Morlat committed
187 188 189
/*this function is to be used only in belle_sip_listening_point_clean_channels()*/
void belle_sip_channel_force_close(belle_sip_channel_t *obj);

Simon Morlat's avatar
Simon Morlat committed
190
/*this function is for transactions to report that a channel seems non working because a timeout occured for example.
191 192 193 194
 It results in the channel possibly entering error state, so that it gets cleaned. Next transactions will re-open a new one and
 get a better chance of receiving an answer.
 Returns TRUE if the channel enters error state, 0 otherwise (channel is given a second chance) */
int belle_sip_channel_notify_timeout(belle_sip_channel_t *obj);
Simon Morlat's avatar
Simon Morlat committed
195

196
BELLE_SIP_END_DECLS
Ghislain MARY's avatar
Ghislain MARY committed
197 198


199
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_channel_t,belle_sip_source_t)
200 201
	const char *transport;
	int reliable;
202
	int (*connect)(belle_sip_channel_t *obj, const struct addrinfo *ai);
203 204
	int (*channel_send)(belle_sip_channel_t *obj, const void *buf, size_t buflen);
	int (*channel_recv)(belle_sip_channel_t *obj, void *buf, size_t buflen);
205
	void (*close)(belle_sip_channel_t *obj);
206 207
BELLE_SIP_DECLARE_CUSTOM_VPTR_END

Simon Morlat's avatar
Simon Morlat committed
208
/*
jehan's avatar
jehan committed
209
 * tls client certificate authentication. might be relevant for both tls and dtls channels.Only implemented in tls channel for now
Simon Morlat's avatar
Simon Morlat committed
210 211 212 213
 */
void belle_sip_tls_channel_set_client_certificates_chain(belle_sip_tls_channel_t *obj, belle_sip_certificates_chain_t* cert_chain);
void belle_sip_tls_channel_set_client_certificate_key(belle_sip_tls_channel_t *obj, belle_sip_signing_key_t* key);

Simon Morlat's avatar
Simon Morlat committed
214
belle_sip_channel_t *belle_sip_channel_find_from_list_with_addrinfo(belle_sip_list_t *l, const belle_sip_hop_t *hop, const struct addrinfo *addr);
Simon Morlat's avatar
Simon Morlat committed
215
belle_sip_channel_t *belle_sip_channel_find_from_list(belle_sip_list_t *l, int ai_family, const belle_sip_hop_t *hop);
Simon Morlat's avatar
Simon Morlat committed
216

Simon Morlat's avatar
Simon Morlat committed
217
#define BELLE_SIP_TLS_CHANNEL(obj)		BELLE_SIP_CAST(obj,belle_sip_tls_channel_t)
218

Simon Morlat's avatar
Simon Morlat committed
219 220 221 222 223 224
struct belle_tls_verify_policy{
	belle_sip_object_t base;
	char *root_ca;
	int exception_flags;
};

225
#endif