Commit e17f7cb6 authored by Simon Morlat's avatar Simon Morlat

- improve tcp and tls channels so that they can work with ipv6

- fix bug when displaying incoming message (garbage past write pointer was shown)
parent 3541f3b4
......@@ -53,6 +53,8 @@ void belle_sip_stack_main(belle_sip_stack_t *stack);
void belle_sip_stack_sleep(belle_sip_stack_t *stack, unsigned int milliseconds);
int belle_sip_stack_get_transport_timeout(const belle_sip_stack_t *stack);
void belle_sip_hop_free(belle_sip_hop_t *hop);
/**
......
......@@ -489,6 +489,7 @@ struct belle_sip_stack{
belle_sip_object_t base;
belle_sip_main_loop_t *ml;
belle_sip_timer_config_t timer_config;
int transport_timeout;
int tx_delay; /*used to simulate network transmission delay, for tests*/
};
......
......@@ -125,7 +125,7 @@ static void belle_sip_channel_input_stream_reset(belle_sip_channel_input_stream_
input_stream->state=WAITING_MESSAGE_START;
input_stream->msg=NULL;
}
static size_t belle_sip_channel_input_stream_get_buff_lenght(belle_sip_channel_input_stream_t* input_stream) {
static size_t belle_sip_channel_input_stream_get_buff_length(belle_sip_channel_input_stream_t* input_stream) {
return MAX_CHANNEL_BUFF_SIZE - (input_stream->write_ptr-input_stream->read_ptr);
}
......@@ -138,16 +138,16 @@ void belle_sip_channel_process_data(belle_sip_channel_t *obj,unsigned int revent
int content_length;
if (revents) {
num=belle_sip_channel_recv(obj,obj->input_stream.write_ptr,belle_sip_channel_input_stream_get_buff_lenght(&obj->input_stream)-1);
num=belle_sip_channel_recv(obj,obj->input_stream.write_ptr,belle_sip_channel_input_stream_get_buff_length(&obj->input_stream)-1);
/*write ptr is only incremented if data were acquired from the transport*/
obj->input_stream.write_ptr+=num;
/*first null terminate the read buff*/
*obj->input_stream.write_ptr='\0';
}
else
num=obj->input_stream.write_ptr-obj->input_stream.read_ptr;
if (num>0){
/*first null terminate the buff*/
obj->input_stream.write_ptr[num]='\0';
if (obj->input_stream.state == WAITING_MESSAGE_START) {
......@@ -227,7 +227,7 @@ void belle_sip_channel_process_data(belle_sip_channel_t *obj,unsigned int revent
}
void belle_sip_channel_init(belle_sip_channel_t *obj, belle_sip_stack_t *stack, int fd, belle_sip_source_func_t process_data,const char *bindip,int localport,const char *peername, int peer_port){
void belle_sip_channel_init(belle_sip_channel_t *obj, belle_sip_stack_t *stack,const char *bindip,int localport,const char *peername, int peer_port){
obj->peer_name=belle_sip_strdup(peername);
obj->peer_port=peer_port;
obj->peer=NULL;
......@@ -236,12 +236,13 @@ void belle_sip_channel_init(belle_sip_channel_t *obj, belle_sip_stack_t *stack,
obj->local_ip=belle_sip_strdup(bindip);
obj->local_port=localport;
if (process_data) {
belle_sip_fd_source_init((belle_sip_source_t*)obj,(belle_sip_source_func_t)process_data,obj,fd,BELLE_SIP_EVENT_READ|BELLE_SIP_EVENT_ERROR,-1);
}
belle_sip_channel_input_stream_reset(&obj->input_stream,0);
}
void belle_sip_channel_set_fd(belle_sip_channel_t *obj, int fd, belle_sip_source_func_t datafunc){
belle_sip_fd_source_init((belle_sip_source_t*)obj, datafunc, obj, fd, BELLE_SIP_EVENT_READ|BELLE_SIP_EVENT_WRITE, belle_sip_stack_get_transport_timeout(obj->stack));
}
void belle_sip_channel_add_listener(belle_sip_channel_t *obj, belle_sip_channel_listener_t *l){
obj->listeners=belle_sip_list_append(obj->listeners,
belle_sip_object_weak_ref(l,
......@@ -441,7 +442,7 @@ void belle_sip_channel_resolve(belle_sip_channel_t *obj){
void belle_sip_channel_connect(belle_sip_channel_t *obj){
channel_set_state(obj,BELLE_SIP_CHANNEL_CONNECTING);
if(BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->connect(obj,obj->peer->ai_addr,obj->peer->ai_addrlen)) {
if(BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->connect(obj,obj->peer)) {
belle_sip_error("Cannot connect to [%s://%s:%i]",belle_sip_channel_get_transport_name(obj),obj->peer_name,obj->peer_port);
channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
channel_process_queue(obj);
......
......@@ -112,7 +112,8 @@ int belle_sip_channel_send(belle_sip_channel_t *obj, const void *buf, size_t buf
int belle_sip_channel_recv(belle_sip_channel_t *obj, void *buf, size_t buflen);
/*only used by channels implementation*/
void belle_sip_channel_set_ready(belle_sip_channel_t *obj, const struct sockaddr *addr, socklen_t slen);
void belle_sip_channel_init(belle_sip_channel_t *obj, belle_sip_stack_t *stack, int fd, belle_sip_source_func_t process_data, const char *bindip,int localport,const char *peername, int peer_port);
void belle_sip_channel_init(belle_sip_channel_t *obj, belle_sip_stack_t *stack, const char *bindip,int localport,const char *peername, int peer_port);
void belle_sip_channel_set_fd(belle_sip_channel_t *obj, int fd, belle_sip_source_func_t datafunc);
/*end of channel implementations*/
/**
* pickup last received message. This method take the ownership of the message.
......@@ -142,7 +143,7 @@ void belle_sip_channel_process_data(belle_sip_channel_t *obj,unsigned int revent
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_channel_t,belle_sip_source_t)
const char *transport;
int reliable;
int (*connect)(belle_sip_channel_t *obj, const struct sockaddr *, socklen_t socklen);
int (*connect)(belle_sip_channel_t *obj, const struct addrinfo *ai);
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);
......
......@@ -51,6 +51,7 @@ belle_sip_stack_t * belle_sip_stack_new(const char *properties){
stack->timer_config.T1=500;
stack->timer_config.T2=4000;
stack->timer_config.T4=5000;
stack->transport_timeout=30000;
#ifdef HAVE_OPENSSL
SSL_library_init();
SSL_load_error_strings();
......@@ -71,6 +72,10 @@ const belle_sip_timer_config_t *belle_sip_stack_get_timer_config(const belle_sip
return &stack->timer_config;
}
int belle_sip_stack_get_transport_timeout(const belle_sip_stack_t *stack){
return stack->transport_timeout;
}
belle_sip_listening_point_t *belle_sip_stack_create_listening_point(belle_sip_stack_t *s, const char *ipaddress, int port, const char *transport){
belle_sip_listening_point_t *lp=NULL;
if (strcasecmp(transport,"UDP")==0) {
......
......@@ -30,7 +30,7 @@
/*************TCP********/
static int stream_channel_process_data(belle_sip_channel_t *obj,unsigned int revents);
static void stream_channel_uninit(belle_sip_stream_channel_t *obj){
......@@ -69,19 +69,28 @@ 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){
int stream_channel_connect(belle_sip_channel_t *obj, const struct addrinfo *ai){
int err;
int tmp;
belle_sip_fd_t sock = belle_sip_source_get_fd((belle_sip_source_t*)obj);
belle_sip_fd_t sock;
tmp=1;
sock=socket(ai->ai_family, SOCK_STREAM, ai->ai_protocol);
if (sock==-1){
belle_sip_error("Could not create socket: %s",belle_sip_get_socket_error_string());
return -1;
}
err=setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,(char*)&tmp,sizeof(tmp));
if (err!=0){
belle_sip_error("setsockopt TCP_NODELAY failed: [%s]",belle_sip_get_socket_error_string());
}
fcntl(sock,F_SETFL,fcntl(sock,F_GETFL) | O_NONBLOCK);
belle_sip_channel_set_fd(obj,sock,(belle_sip_source_func_t)stream_channel_process_data);
belle_sip_source_set_events((belle_sip_source_t*)obj,BELLE_SIP_EVENT_WRITE|BELLE_SIP_EVENT_ERROR);
belle_sip_main_loop_add_source(obj->stack->ml,(belle_sip_source_t*)obj);
err = connect(sock,addr,socklen);
err = connect(sock,ai->ai_addr,ai->ai_addrlen);
if (err != 0 && get_socket_error()!=EINPROGRESS) {
belle_sip_error("stream connect failed %s",belle_sip_get_socket_error_string());
close_socket(sock);
......@@ -110,6 +119,7 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_stream_channel_t)=
stream_channel_close,
}
};
int finalize_stream_connection (belle_sip_fd_t fd, struct sockaddr *addr, socklen_t* slen) {
int err, errnum;
socklen_t optlen=sizeof(errnum);
......@@ -163,8 +173,6 @@ belle_sip_channel_t * belle_sip_channel_new_tcp(belle_sip_stack_t *stack,const c
belle_sip_stream_channel_t *obj=belle_sip_object_new(belle_sip_stream_channel_t);
belle_sip_channel_init((belle_sip_channel_t*)obj
,stack
,socket(AF_INET, SOCK_STREAM, 0)
,(belle_sip_source_func_t)stream_channel_process_data
,bindip,localport,dest,port);
return (belle_sip_channel_t*)obj;
}
......
......@@ -28,7 +28,7 @@ BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_stream_channel_t,belle_sip_channel
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);
int stream_channel_connect(belle_sip_channel_t *obj, const struct addrinfo *ai);
/*return 0 if succeed*/
int finalize_stream_connection (belle_sip_fd_t fd, struct sockaddr *addr, socklen_t* slen);
int stream_channel_send(belle_sip_channel_t *obj, const void *buf, size_t buflen);
......
......@@ -30,6 +30,8 @@
#endif
/*************tls********/
static int tls_process_data(belle_sip_channel_t *obj,unsigned int revents);
struct belle_sip_tls_channel{
belle_sip_stream_channel_t base;
int socket_connected;
......@@ -89,8 +91,14 @@ static int tls_channel_recv(belle_sip_channel_t *obj, void *buf, size_t buflen){
return err;
}
int tls_channel_connect(belle_sip_channel_t *obj, const struct sockaddr *addr, socklen_t socklen){
return stream_channel_connect(obj,addr,socklen);
int tls_channel_connect(belle_sip_channel_t *obj, const struct addrinfo *ai){
int err= stream_channel_connect(obj,ai);
if (err==0){
belle_sip_fd_t sock=belle_sip_source_get_fd((belle_sip_source_t*)obj);
belle_sip_channel_set_fd(obj,sock,(belle_sip_source_func_t)tls_process_data);
return 0;
}
return -1;
}
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_tls_channel_t,belle_sip_stream_channel_t)
......@@ -118,7 +126,7 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_tls_channel_t)=
}
};
static int process_data(belle_sip_channel_t *obj,unsigned int revents){
static int tls_process_data(belle_sip_channel_t *obj,unsigned int revents){
belle_sip_tls_channel_t* channel=(belle_sip_tls_channel_t*)obj;
socklen_t addrlen=sizeof(channel->ss);
int result;
......@@ -222,8 +230,6 @@ belle_sip_channel_t * belle_sip_channel_new_tls(belle_sip_tls_listening_point_t
#endif
belle_sip_channel_init(channel
,((belle_sip_listening_point_t*)lp)->stack
,socket(AF_INET, SOCK_STREAM, 0)
,(belle_sip_source_func_t)process_data
,bindip,localport,dest,port);
return (belle_sip_channel_t*)obj;
error:
......
......@@ -64,11 +64,11 @@ static int udp_channel_recv(belle_sip_channel_t *obj, void *buf, size_t buflen){
return err;
}
int udp_channel_connect(belle_sip_channel_t *obj, const struct sockaddr *addr, socklen_t socklen){
int udp_channel_connect(belle_sip_channel_t *obj, const struct addrinfo *ai){
struct sockaddr_storage laddr;
socklen_t lslen=sizeof(laddr);
if (obj->local_ip==NULL){
belle_sip_get_src_addr_for(addr,socklen,(struct sockaddr*)&laddr,&lslen);
belle_sip_get_src_addr_for(ai->ai_addr,ai->ai_addrlen,(struct sockaddr*)&laddr,&lslen);
if (lslen==sizeof(struct sockaddr_in6)){
struct sockaddr_in6 *sin6=(struct sockaddr_in6*)&laddr;
sin6->sin6_port=htons(obj->local_port);
......@@ -102,7 +102,7 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_udp_channel_t)=
belle_sip_channel_t * belle_sip_channel_new_udp(belle_sip_stack_t *stack, int sock, const char *bindip, int localport, const char *dest, int port){
belle_sip_udp_channel_t *obj=belle_sip_object_new(belle_sip_udp_channel_t);
belle_sip_channel_init((belle_sip_channel_t*)obj,stack,sock,NULL,bindip,localport,dest,port);
belle_sip_channel_init((belle_sip_channel_t*)obj,stack,bindip,localport,dest,port);
obj->sock=sock;
return (belle_sip_channel_t*)obj;
}
......@@ -122,7 +122,7 @@ belle_sip_channel_t * belle_sip_channel_new_udp_with_addr(belle_sip_stack_t *sta
belle_sip_object_unref(obj);
return NULL;
}
belle_sip_channel_init((belle_sip_channel_t*)obj,stack,sock,NULL,bindip,localport,name,atoi(serv));
belle_sip_channel_init((belle_sip_channel_t*)obj,stack,bindip,localport,name,atoi(serv));
err=getaddrinfo(name,serv,ai,&obj->base.peer); /*might be optimized someway ?*/
if (err!=0){
belle_sip_error("getaddrinfo() failed for channel [%p] error [%s]",obj,gai_strerror(err));
......
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