Exemple #1
0
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END


static belle_sip_socket_t create_udp_socket(const char *addr, int *port, int *family){
	struct addrinfo hints={0};
	struct addrinfo *res=NULL;
	int err;
	belle_sip_socket_t sock;
	char portnum[10];
	int optval=1;
	
	if (*port==-1) *port=0; /*random port for bind()*/

	snprintf(portnum,sizeof(portnum),"%i",*port);
	hints.ai_family=AF_UNSPEC;
	hints.ai_socktype=SOCK_DGRAM;
	hints.ai_protocol=IPPROTO_UDP;
	hints.ai_flags=AI_NUMERICSERV;
	err=getaddrinfo(addr,portnum,&hints,&res);
	if (err!=0){
		belle_sip_error("getaddrinfo() failed for %s port %i: %s",addr,*port,gai_strerror(err));
		return -1;
	}
	*family=res->ai_family;
	sock=socket(res->ai_family,res->ai_socktype,res->ai_protocol);
	if (sock==-1){
		belle_sip_error("Cannot create UDP socket: %s",belle_sip_get_socket_error_string());
		freeaddrinfo(res);
		return -1;
	}
	err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
			(char*)&optval, sizeof (optval));
	if (err == -1){
		belle_sip_warning ("Fail to set SIP/UDP address reusable: %s.", belle_sip_get_socket_error_string());
	}
	
	err=bind(sock,res->ai_addr,res->ai_addrlen);
	if (err==-1){
		belle_sip_error("udp bind() failed for %s port %i: %s",addr,*port,belle_sip_get_socket_error_string());
		close_socket(sock);
		freeaddrinfo(res);
		return -1;
	}
	freeaddrinfo(res);
	if (*port==0){
		struct sockaddr_storage saddr;
		socklen_t saddr_len=sizeof(saddr);
		err=getsockname(sock,(struct sockaddr*)&saddr,&saddr_len);
		if (err==0){
			err=getnameinfo((struct sockaddr*)&saddr,saddr_len,NULL,0,portnum,sizeof(portnum),NI_NUMERICSERV|NI_NUMERICHOST);
			if (err==0){
				*port=atoi(portnum);
				belle_sip_message("Random UDP port is %i",*port);
			}else belle_sip_error("udp bind failed, getnameinfo(): %s",gai_strerror(err));
		}else belle_sip_error("udp bind failed, getsockname(): %s",belle_sip_get_socket_error_string());
	}
	return sock;
}
Exemple #2
0
int belle_sip_socket_set_dscp(belle_sip_socket_t sock, int ai_family, int dscp){
	int tos;
	int proto;
	int value_type;
	int retval;
	
	tos = (dscp << 2) & 0xFC;
	switch (ai_family) {
		case AF_INET:
			proto=IPPROTO_IP;
			value_type=IP_TOS;
		break;
		case AF_INET6:
			proto=IPPROTO_IPV6;
#ifdef IPV6_TCLASS /*seems not defined by my libc*/
			value_type=IPV6_TCLASS;
#else
			value_type=IP_TOS;
#endif
		break;
		default:
			belle_sip_error("Cannot set DSCP because socket family is unspecified.");
			return -1;
	}
	retval = setsockopt(sock, proto, value_type, (const char*)&tos, sizeof(tos));
	if (retval==-1)
		belle_sip_error("Fail to set DSCP value on socket: %s",belle_sip_get_socket_error_string());
	return retval;
}
Exemple #3
0
static unsigned int belle_sip_source_get_revents(belle_sip_source_t *s,belle_sip_pollfd_t *pfd){
	WSANETWORKEVENTS revents={0};
	int err;
	unsigned int ret=0;
	
	if (WaitForSingleObjectEx(s->fd,0,FALSE)==WAIT_OBJECT_0){
		if (s->sock!=(belle_sip_socket_t)-1){
			/*special treatments for windows sockets*/
			err=WSAEnumNetworkEvents(s->sock,s->fd,&revents);
			if (err!=0){
				belle_sip_error("WSAEnumNetworkEvents() failed: %s socket=%x",belle_sip_get_socket_error_string(),(unsigned int)s->sock);
				return 0;
			}
			if (revents.lNetworkEvents & FD_READ){
				ret|=BELLE_SIP_EVENT_READ;
			}
			if (revents.lNetworkEvents & FD_WRITE){
				ret|=BELLE_SIP_EVENT_WRITE;
			}
			s->armed_events=0;
		}else{
			ret=BELLE_SIP_EVENT_READ;
			ResetEvent(s->fd);
		}
	}
	return ret;
}
static belle_sip_socket_t create_udp_socket(const char *addr, int port, int *family){
/*	struct addrinfo hints={0}; */
	struct addrinfo *res=NULL;
	int err;
	belle_sip_socket_t sock;
	char portnum[10];
/*	int optval=1; */

	snprintf(portnum,sizeof(portnum),"%i",port);
/*	hints.ai_family=AF_UNSPEC;
	hints.ai_socktype=SOCK_DGRAM;
	hints.ai_protocol=IPPROTO_UDP;
	hints.ai_flags=AI_NUMERICSERV; */
	err=Xgetaddrinfo(addr,NULL,NULL,&res);
	if (err!=0){
		printf("getaddrinfo() failed for %s port %i: %s",addr,port,gai_strerror(err));
		return -1;
	}
	*family=res->ai_family;
/*	sock=Xsocket(res->ai_family,res->ai_socktype,res->ai_protocol); */
	sock=Xsocket(AF_XIA, SOCK_DGRAM, 0);
	if (sock==-1){
		printf("Cannot create UDP socket: %s",belle_sip_get_socket_error_string());
		Xfreeaddrinfo(res);
		return -1;
	}
/*	err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
			(char*)&optval, sizeof (optval)); 
	if (err == -1){
		belle_sip_warning ("Fail to set SIP/UDP address reusable: %s.", belle_sip_get_socket_error_string());
	} */
	
	err=Xbind(sock,res->ai_addr,res->ai_addrlen);
	if (err==-1){
		printf("udp bind() failed for %s port %i: %s",addr,port,belle_sip_get_socket_error_string());
		close_socket(sock);
		Xfreeaddrinfo(res);
		return -1;
	}
	Xfreeaddrinfo(res);
	return sock;
}
Exemple #5
0
static int udp_channel_send(belle_sip_channel_t *obj, const void *buf, size_t buflen){
	belle_sip_udp_channel_t *chan=(belle_sip_udp_channel_t *)obj;
	int err;
	belle_sip_socket_t sock=belle_sip_source_get_socket((belle_sip_source_t*)chan);
	
	err=sendto(sock,buf,buflen,0,obj->current_peer->ai_addr,obj->current_peer->ai_addrlen);
	if (err==-1){
		belle_sip_error("channel [%p]: could not send UDP packet because [%s]",obj,belle_sip_get_socket_error_string());
		return -errno;
	}
	return err;
}
/*peek data from the master socket to see where it comes from, and dispatch to matching channel.
 * If the channel does not exist, create it */
static int on_udp_data(belle_sip_udp_listening_point_t *lp, unsigned int events){
	int err;
	unsigned char buf[4096];
	sockaddr_x addr;
	socklen_t addrlen=sizeof(sockaddr_x);

	if (events & BELLE_SIP_EVENT_READ){
		belle_sip_debug("udp_listening_point: data to read.");
		err=Xrecvfrom(lp->sock,(char*)buf,sizeof(buf),MSG_PEEK,(struct sockaddr*)&addr,&addrlen);
		if (err==-1){
			char *tmp=belle_sip_object_to_string((belle_sip_object_t*) ((belle_sip_listening_point_t*)lp)->listening_uri);
			belle_sip_error("udp_listening_point: recvfrom() failed on [%s], : [%s] reopening server socket"
					,tmp
					,belle_sip_get_socket_error_string());
			belle_sip_free(tmp);
			belle_sip_udp_listening_point_uninit(lp);
			/*clean all udp channels that are actually sharing the server socket with the listening points*/
			belle_sip_listening_point_clean_channels((belle_sip_listening_point_t*)lp);
			belle_sip_udp_listening_point_init_socket(lp);
		}else{
			belle_sip_channel_t *chan;
			struct addrinfo ai={0};
			belle_sip_address_remove_v4_mapping((struct sockaddr*)&addr,(struct sockaddr*)&addr,&addrlen);
			ai.ai_family=((struct sockaddr*)&addr)->sa_family;
			ai.ai_addr=(struct sockaddr*)&addr;
			ai.ai_addrlen=addrlen;
			chan=_belle_sip_listening_point_get_channel((belle_sip_listening_point_t*)lp,NULL,&ai);
			if (chan==NULL){
				/*TODO: should rather create the channel with real local ip and port and not just 0.0.0.0"*/
				chan=belle_sip_channel_new_udp_with_addr(lp->base.stack
														,lp->sock
														,belle_sip_uri_get_host(lp->base.listening_uri)
														,belle_sip_uri_get_port(lp->base.listening_uri)
														,&ai);
				if (chan!=NULL){
					belle_sip_message("udp_listening_point: new channel created to %s:%i",chan->peer_name,chan->peer_port);
					chan->lp=(belle_sip_listening_point_t*)lp; /*FIXME, exactly the same code as for channel creation from provider. might be good to factorize*/
					belle_sip_listening_point_add_channel((belle_sip_listening_point_t*)lp,chan);
				}
			}
			if (chan){
				/*notify the channel*/
				belle_sip_debug("Notifying udp channel, local [%s:%i]  remote [%s:%i]"
						,chan->local_ip
						,chan->local_port
						,chan->peer_name
						,chan->peer_port);
				belle_sip_channel_process_data(chan,events);
			}
		}
	}
	return BELLE_SIP_CONTINUE;
}
Exemple #7
0
static int udp_channel_recv(belle_sip_channel_t *obj, void *buf, size_t buflen){
	belle_sip_udp_channel_t *chan=(belle_sip_udp_channel_t *)obj;
	int err;
	struct sockaddr_storage addr;
	socklen_t addrlen=sizeof(addr);
	belle_sip_socket_t sock=belle_sip_source_get_socket((belle_sip_source_t*)chan);
	
	err=recvfrom(sock,buf,buflen,0,(struct sockaddr*)&addr,&addrlen);

	if (err==-1 && get_socket_error()!=BELLESIP_EWOULDBLOCK){
		belle_sip_error("Could not receive UDP packet: %s",belle_sip_get_socket_error_string());
		return -errno;
	}
	return err;
}
static void belle_sip_source_to_poll(belle_sip_source_t *s, belle_sip_pollfd_t *pfd,int i){
	s->index=i;
	pfd[i]=s->fd;
	
	/*special treatments for windows sockets*/
	if (s->sock!=(belle_sip_socket_t)-1){
		int err;
		long events=0;
		
		if (s->events & BELLE_SIP_EVENT_READ)
			events|=FD_READ;
		if (s->events & BELLE_SIP_EVENT_WRITE)
			events|=FD_WRITE;
		
		err=WSAEventSelect(s->sock,s->fd,events);
		if (err!=0) belle_sip_error("WSAEventSelect() failed: %s",belle_sip_get_socket_error_string());
	}
}
static int on_new_connection(void *userdata, unsigned int revents){
	belle_sip_socket_t child;
	struct sockaddr_storage addr;
	socklen_t slen=sizeof(addr);
	belle_sip_tls_listening_point_t *lp=(belle_sip_tls_listening_point_t*)userdata;
	belle_sip_stream_listening_point_t *super=(belle_sip_stream_listening_point_t*)lp;
	
	child=accept(super->server_sock,(struct sockaddr*)&addr,&slen);
	if (child==(belle_sip_socket_t)-1){
		belle_sip_error("Listening point [%p] accept() failed on TLS server socket: %s",lp,belle_sip_get_socket_error_string());
		belle_sip_stream_listening_point_destroy_server_socket(super);
		belle_sip_stream_listening_point_setup_server_socket(super,on_new_connection);
		return BELLE_SIP_STOP;
	}
	belle_sip_message("New connection arriving on TLS, not handled !");
	close_socket(child);
	return BELLE_SIP_CONTINUE;
}
static int on_new_connection(void *userdata, unsigned int events){
	belle_sip_socket_t child;
	struct sockaddr_storage addr;
	socklen_t slen=sizeof(addr);
	belle_sip_stream_listening_point_t *lp=(belle_sip_stream_listening_point_t*)userdata;
	belle_sip_channel_t *chan;
	
	child=accept(lp->server_sock,(struct sockaddr*)&addr,&slen);
	if (child==(belle_sip_socket_t)-1){
		belle_sip_error("Listening point [%p] accept() failed on TCP server socket: %s",lp,belle_sip_get_socket_error_string());
		belle_sip_stream_listening_point_destroy_server_socket(lp);
		belle_sip_stream_listening_point_setup_server_socket(lp,on_new_connection);
		return BELLE_SIP_STOP;
	}
	belle_sip_message("New connection arriving !");
	chan=belle_sip_stream_channel_new_child(lp->base.stack,child,(struct sockaddr*)&addr,slen);
	if (chan) belle_sip_listening_point_add_channel((belle_sip_listening_point_t*)lp,chan);
	return BELLE_SIP_CONTINUE;
}
Exemple #11
0
int belle_sip_socket_enable_dual_stack(belle_sip_socket_t sock){
	int value=0;
	int err=setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&value, sizeof(value));
	if (err==-1){
		belle_sip_warning("belle_sip_socket_enable_dual_stack: setsockopt(IPV6_ONLY) failed: %s",belle_sip_get_socket_error_string());
	}
	return err;
}