Commit 45f88e5b authored by Simon Morlat's avatar Simon Morlat
Browse files

implement better channel lifecycle, cleanups

parent 38bf8cc2
......@@ -510,7 +510,7 @@ void belle_sip_provider_set_transaction_terminated(belle_sip_provider_t *p, bell
belle_sip_channel_t * belle_sip_provider_get_channel(belle_sip_provider_t *p, const char *name, int port, const char *transport);
void belle_sip_provider_add_dialog(belle_sip_provider_t *prov, belle_sip_dialog_t *dialog);
void belle_sip_provider_remove_dialog(belle_sip_provider_t *prov, belle_sip_dialog_t *dialog);
void belle_sip_provider_release_channel(belle_sip_provider_t *p, belle_sip_channel_t *chan);
typedef struct listener_ctx{
belle_sip_listener_t *listener;
......
......@@ -34,7 +34,7 @@ const char *belle_sip_channel_state_to_string(belle_sip_channel_state_t state){
case BELLE_SIP_CHANNEL_ERROR:
return "ERROR";
case BELLE_SIP_CHANNEL_DISCONNECTED:
return "BELLE_SIP_CHANNEL_DISCONNECTED";
return "DISCONNECTED";
}
return "BAD";
}
......@@ -194,9 +194,11 @@ void belle_sip_channel_process_data(belle_sip_channel_t *obj,unsigned int revent
return;
} else if (num == 0) {
channel_set_state(obj,BELLE_SIP_CHANNEL_DISCONNECTED);
belle_sip_channel_close(obj);
} else {
belle_sip_error("Receive error on channel [%p]",obj);
channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
belle_sip_channel_close(obj);
}
return;
}
......@@ -244,6 +246,7 @@ const char *belle_sip_channel_get_local_address(belle_sip_channel_t *obj, int *p
int belle_sip_channel_is_reliable(const belle_sip_channel_t *obj){
return BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->reliable;
}
const char * belle_sip_channel_get_transport_name_lower_case(const belle_sip_channel_t *obj){
const char* transport = belle_sip_channel_get_transport_name(obj);
if (strcasecmp("udp",transport)==0) return "udp";
......@@ -255,6 +258,7 @@ const char * belle_sip_channel_get_transport_name_lower_case(const belle_sip_cha
return transport;
}
}
const char * belle_sip_channel_get_transport_name(const belle_sip_channel_t *obj){
return BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->transport;
}
......@@ -267,6 +271,10 @@ int belle_sip_channel_recv(belle_sip_channel_t *obj, void *buf, size_t buflen){
return BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->channel_recv(obj,buf,buflen);
}
void belle_sip_channel_close(belle_sip_channel_t *obj){
BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->close(obj);
}
const struct addrinfo * belle_sip_channel_get_peer(belle_sip_channel_t *obj){
return obj->peer;
}
......@@ -300,6 +308,7 @@ static void _send_message(belle_sip_channel_t *obj, belle_sip_message_t *msg){
int ret=belle_sip_channel_send(obj,buffer,len);
if (ret==-1){
channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
belle_sip_channel_close(obj);
}else{
belle_sip_message("channel %p: message sent: \n%s",obj,buffer);
}
......
......@@ -105,6 +105,8 @@ void belle_sip_channel_connect(belle_sip_channel_t *obj);
void belle_sip_channel_prepare(belle_sip_channel_t *obj);
void belle_sip_channel_close(belle_sip_channel_t *obj);
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);
......@@ -143,6 +145,7 @@ BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_channel_t,belle_sip_source_t)
int (*connect)(belle_sip_channel_t *obj, const struct sockaddr *, socklen_t socklen);
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);
void (*close)(belle_sip_channel_t *obj);
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
......
......@@ -28,6 +28,7 @@ static void belle_sip_provider_uninit(belle_sip_provider_t *p){
static void channel_state_changed(belle_sip_channel_listener_t *obj, belle_sip_channel_t *chan, belle_sip_channel_state_t state){
belle_sip_io_error_event_t ev;
if (state == BELLE_SIP_CHANNEL_ERROR || state == BELLE_SIP_CHANNEL_DISCONNECTED) {
belle_sip_provider_release_channel(ev.source,chan);
ev.transport=belle_sip_channel_get_transport_name(chan);
ev.source=(belle_sip_provider_t*)obj;
ev.port=chan->peer_port;
......
......@@ -30,16 +30,12 @@
/*************TCP********/
struct belle_sip_stream_channel{
belle_sip_channel_t base;
};
static void stream_channel_uninit(belle_sip_stream_channel_t *obj){
belle_sip_fd_t sock = belle_sip_source_get_fd((belle_sip_source_t*)obj);
if (sock!=-1)
close_socket(sock);
belle_sip_main_loop_remove_source(obj->base.stack->ml,(belle_sip_source_t*)obj);
if (sock!=-1) stream_channel_close((belle_sip_channel_t*)obj);
}
int stream_channel_send(belle_sip_channel_t *obj, const void *buf, size_t buflen){
......@@ -47,7 +43,7 @@ int stream_channel_send(belle_sip_channel_t *obj, const void *buf, size_t buflen
int err;
err=send(sock,buf,buflen,0);
if (err==-1){
belle_sip_fatal("Could not send stream packet on channel [%p]: %s",obj,strerror(errno));
belle_sip_error("Could not send stream packet on channel [%p]: %s",obj,strerror(errno));
return -errno;
}
return err;
......@@ -56,14 +52,23 @@ int stream_channel_send(belle_sip_channel_t *obj, const void *buf, size_t buflen
int stream_channel_recv(belle_sip_channel_t *obj, void *buf, size_t buflen){
belle_sip_fd_t sock = belle_sip_source_get_fd((belle_sip_source_t*)obj);
int err;
err=recv(sock,buf,buflen,MSG_DONTWAIT);
if (err==-1 && errno!=EWOULDBLOCK){
err=recv(sock,buf,buflen,0);
if (err==-1){
belle_sip_error("Could not receive stream packet: %s",strerror(errno));
return -errno;
}
return err;
}
void stream_channel_close(belle_sip_channel_t *obj){
belle_sip_fd_t sock = belle_sip_source_get_fd((belle_sip_source_t*)obj);
if (sock!=-1){
close_socket(sock);
belle_sip_main_loop_remove_source(obj->stack->ml,(belle_sip_source_t*)obj);
obj->base.fd=-1;
}
}
int stream_channel_connect(belle_sip_channel_t *obj, const struct sockaddr *addr, socklen_t socklen){
int err;
int tmp;
......@@ -86,9 +91,6 @@ int stream_channel_connect(belle_sip_channel_t *obj, const struct sockaddr *addr
return 0;
}
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_stream_channel_t,belle_sip_channel_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_stream_channel_t);
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_stream_channel_t)=
......@@ -104,7 +106,8 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_stream_channel_t)=
1, /*is_reliable*/
stream_channel_connect,
stream_channel_send,
stream_channel_recv
stream_channel_recv,
stream_channel_close,
}
};
int finalize_stream_connection (belle_sip_fd_t fd, struct sockaddr *addr, socklen_t* slen) {
......
......@@ -20,6 +20,14 @@
#define STREAM_CHANNEL_H_
#include "channel.h"
struct belle_sip_stream_channel{
belle_sip_channel_t base;
};
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_stream_channel_t,belle_sip_channel_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
void stream_channel_close(belle_sip_channel_t *obj);
int stream_channel_connect(belle_sip_channel_t *obj, const struct sockaddr *addr, socklen_t socklen);
/*return 0 if succeed*/
int finalize_stream_connection (belle_sip_fd_t fd, struct sockaddr *addr, socklen_t* slen);
......
......@@ -25,14 +25,13 @@
#include "stream_channel.h"
#ifdef HAVE_GNUTLS
#include <gnutls/gnutls.h>
#else if HAVE_OPENSSL
#elif HAVE_OPENSSL
#include "openssl/ssl.h"
#endif
/*************tls********/
struct belle_sip_tls_channel{
belle_sip_channel_t base;
belle_sip_tls_listening_point_t* lp;
belle_sip_stream_channel_t base;
int socket_connected;
#ifdef HAVE_OPENSSL
SSL *ssl;
......@@ -44,20 +43,19 @@ struct belle_sip_tls_channel{
struct sockaddr_storage ss;
};
static void tls_channel_uninit(belle_sip_tls_channel_t *obj){
belle_sip_fd_t sock = belle_sip_source_get_fd((belle_sip_source_t*)obj);
static void tls_channel_close(belle_sip_tls_channel_t *obj){
#ifdef HAVE_GNUTLS
gnutls_bye (obj->session, GNUTLS_SHUT_RDWR);
gnutls_deinit (obj->session);
gnutls_certificate_free_credentials (obj->xcred);
#endif
if (sock!=-1)
close_socket(sock);
stream_channel_close((belle_sip_channel_t*)obj);
}
belle_sip_main_loop_remove_source(obj->base.stack->ml,(belle_sip_source_t*)obj);
belle_sip_object_unref(obj->lp);
static void tls_channel_uninit(belle_sip_tls_channel_t *obj){
belle_sip_fd_t sock = belle_sip_source_get_fd((belle_sip_source_t*)obj);
if (sock!=-1)
tls_channel_close(obj);
}
static int tls_channel_send(belle_sip_channel_t *obj, const void *buf, size_t buflen){
......@@ -73,7 +71,12 @@ static int tls_channel_send(belle_sip_channel_t *obj, const void *buf, size_t bu
}
static ssize_t tls_channel_pull_func(gnutls_transport_ptr_t obj, void* buff, size_t bufflen) {
return stream_channel_recv((belle_sip_channel_t *)obj, buff,bufflen);
int err=recv(
belle_sip_source_get_fd((belle_sip_source_t *)obj),buff,bufflen,0);
if (err==-1 && get_socket_error()!=EWOULDBLOCK){
belle_sip_error("tls_channel_pull_func: %s",belle_sip_get_socket_error_string());
}
return err;
}
static int tls_channel_recv(belle_sip_channel_t *obj, void *buf, size_t buflen){
belle_sip_tls_channel_t* channel = (belle_sip_tls_channel_t*)obj;
......@@ -90,7 +93,7 @@ int tls_channel_connect(belle_sip_channel_t *obj, const struct sockaddr *addr, s
return stream_channel_connect(obj,addr,socklen);
}
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_tls_channel_t,belle_sip_channel_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_tls_channel_t,belle_sip_stream_channel_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_tls_channel_t);
......@@ -99,16 +102,19 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_tls_channel_t)=
{
{
{
BELLE_SIP_VPTR_INIT(belle_sip_tls_channel_t,belle_sip_channel_t,FALSE),
(belle_sip_object_destroy_t)tls_channel_uninit,
NULL,
NULL
},
"TLS",
1, /*is_reliable*/
tls_channel_connect,
tls_channel_send,
tls_channel_recv
{
BELLE_SIP_VPTR_INIT(belle_sip_tls_channel_t,belle_sip_stream_channel_t,FALSE),
(belle_sip_object_destroy_t)tls_channel_uninit,
NULL,
NULL
},
"TLS",
1, /*is_reliable*/
tls_channel_connect,
tls_channel_send,
tls_channel_recv,
(void (*)(belle_sip_channel_t*))tls_channel_close
}
}
};
......@@ -127,6 +133,7 @@ static int process_data(belle_sip_channel_t *obj,unsigned int revents){
}
belle_sip_source_set_events((belle_sip_source_t*)channel,BELLE_SIP_EVENT_READ|BELLE_SIP_EVENT_ERROR);
channel->socket_connected=1;
belle_sip_message("Connected at TCP level.");
}
/*connected, now establishing TLS connection*/
#if HAVE_GNUTLS
......@@ -142,7 +149,7 @@ static int process_data(belle_sip_channel_t *obj,unsigned int revents){
belle_sip_channel_set_ready(obj,(struct sockaddr*)&channel->ss,addrlen);
return BELLE_SIP_CONTINUE;
}
#else if HAVE_OPENSSL
#elif HAVE_OPENSSL
if (!channel->ssl) {
channel->ssl=SSL_new(channel->lp->ssl_context);
if (!channel->ssl) {
......@@ -181,6 +188,7 @@ static int process_data(belle_sip_channel_t *obj,unsigned int revents){
channel_process_queue(obj);
return BELLE_SIP_STOP;
}
belle_sip_channel_t * belle_sip_channel_new_tls(belle_sip_tls_listening_point_t *lp,const char *bindip, int localport, const char *dest, int port){
belle_sip_tls_channel_t *obj=belle_sip_object_new(belle_sip_tls_channel_t);
belle_sip_channel_t* channel=(belle_sip_channel_t*)obj;
......@@ -217,7 +225,6 @@ belle_sip_channel_t * belle_sip_channel_new_tls(belle_sip_tls_listening_point_t
,socket(AF_INET, SOCK_STREAM, 0)
,(belle_sip_source_func_t)process_data
,bindip,localport,dest,port);
belle_sip_object_ref(obj->lp=lp);
return (belle_sip_channel_t*)obj;
error:
belle_sip_error("Cannot create tls channel to [%s://%s:%i]",belle_sip_channel_get_transport_name(channel),channel->peer_name,channel->peer_port);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment