1 /*
2 	belle-sip - SIP (RFC3261) library.
3     Copyright (C) 2010  Belledonne Communications SARL
4 
5     This program is free software: you can redistribute it and/or modify
6     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     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include "belle_sip_internal.h"
20 #include "listeningpoint_internal.h"
21 
22 
belle_sip_hop_new(const char * transport,const char * cname,const char * host,int port)23 belle_sip_hop_t* belle_sip_hop_new(const char* transport, const char *cname, const char* host,int port) {
24 	belle_sip_hop_t* hop = belle_sip_object_new(belle_sip_hop_t);
25 	if (transport) hop->transport=belle_sip_strdup(transport);
26 	if (host) {
27 		if (host[0] == '[' && host[1] != '\0'){ /*IPv6 case */
28 			hop->host = belle_sip_strdup(host+1);
29 			hop->host[strlen(hop->host)-1] = '\0';
30 		}else{
31 			hop->host=belle_sip_strdup(host);
32 		}
33 	}
34 	if (cname) hop->cname=belle_sip_strdup(cname);
35 	hop->port=port;
36 	return hop;
37 }
38 
belle_sip_hop_new_from_uri(const belle_sip_uri_t * uri)39 belle_sip_hop_t* belle_sip_hop_new_from_uri(const belle_sip_uri_t *uri){
40 	const char *host;
41 	const char *cname=NULL;
42 	const char * transport=belle_sip_uri_get_transport_param(uri);
43 	if (!transport) {
44 		transport=belle_sip_uri_is_secure(uri)?"tls":"udp";
45 	}
46 	host=belle_sip_uri_get_maddr_param(uri);
47 	if (!host) host=belle_sip_uri_get_host(uri);
48 	else cname=belle_sip_uri_get_host(uri);
49 
50 	return belle_sip_hop_new(	transport,
51 								cname,
52 								host,
53 								belle_sip_uri_get_listening_port(uri));
54 }
55 
belle_sip_hop_new_from_generic_uri(const belle_generic_uri_t * uri)56 belle_sip_hop_t* belle_sip_hop_new_from_generic_uri(const belle_generic_uri_t *uri){
57 	const char *host;
58 	const char * transport="TCP";
59 	const char *scheme=belle_generic_uri_get_scheme(uri);
60 	int port=belle_generic_uri_get_port(uri);
61 	int well_known_port=0;
62 
63 	host=belle_generic_uri_get_host(uri);
64 	if (strcasecmp(scheme,"http")==0) {
65 		transport="TCP";
66 		well_known_port=80;
67 	}else if (strcasecmp(scheme,"https")==0) {
68 		transport="TLS";
69 		well_known_port=443;
70 	}
71 
72 	return belle_sip_hop_new(transport,
73 				host,
74 				host,
75 				port > 0 ? port : well_known_port);
76 }
77 
belle_sip_hop_destroy(belle_sip_hop_t * hop)78 static void belle_sip_hop_destroy(belle_sip_hop_t *hop){
79 	if (hop->host) {
80 		belle_sip_free(hop->host);
81 		hop->host=NULL;
82 	}
83 	if (hop->cname){
84 		belle_sip_free(hop->cname);
85 		hop->cname=NULL;
86 	}
87 	if (hop->transport){
88 		belle_sip_free(hop->transport);
89 		hop->transport=NULL;
90 	}
91 }
92 
belle_sip_hop_clone(belle_sip_hop_t * hop,const belle_sip_hop_t * orig)93 static void belle_sip_hop_clone(belle_sip_hop_t *hop, const belle_sip_hop_t *orig){
94 	if (orig->host)
95 		hop->host=belle_sip_strdup(orig->host);
96 	if (orig->cname)
97 		hop->cname=belle_sip_strdup(orig->cname);
98 	if (orig->transport)
99 		hop->transport=belle_sip_strdup(orig->transport);
100 
101 }
102 
103 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_hop_t);
104 BELLE_SIP_INSTANCIATE_VPTR(belle_sip_hop_t,belle_sip_object_t,belle_sip_hop_destroy,belle_sip_hop_clone,NULL,TRUE);
105 
belle_sip_stack_destroy(belle_sip_stack_t * stack)106 static void belle_sip_stack_destroy(belle_sip_stack_t *stack){
107 	belle_sip_message("stack [%p] destroyed.",stack);
108 	if (stack->dns_user_hosts_file) belle_sip_free(stack->dns_user_hosts_file);
109 	if (stack->dns_resolv_conf) belle_sip_free(stack->dns_resolv_conf);
110 	belle_sip_object_unref(stack->ml);
111 	if (stack->http_proxy_host) belle_sip_free(stack->http_proxy_host);
112 	if (stack->http_proxy_passwd) belle_sip_free(stack->http_proxy_passwd);
113 	if (stack->http_proxy_username) belle_sip_free(stack->http_proxy_username);
114 	belle_sip_list_free_with_data(stack->dns_servers, belle_sip_free);
115 
116 }
117 
118 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_stack_t);
119 BELLE_SIP_INSTANCIATE_VPTR(belle_sip_stack_t,belle_sip_object_t,belle_sip_stack_destroy,NULL,NULL,FALSE);
120 
belle_sip_stack_new(const char * properties)121 belle_sip_stack_t * belle_sip_stack_new(const char *properties){
122 	belle_sip_stack_t *stack=belle_sip_object_new(belle_sip_stack_t);
123 	stack->ml=belle_sip_main_loop_new ();
124 	stack->timer_config.T1=500;
125 	stack->timer_config.T2=4000;
126 	stack->timer_config.T4=5000;
127 	stack->transport_timeout=63000;
128 	stack->dns_timeout=15000;
129 	stack->dns_srv_enabled=TRUE;
130 	stack->dns_search_enabled=TRUE;
131 	stack->inactive_transport_timeout=3600; /*one hour*/
132 	return stack;
133 }
134 
belle_sip_stack_get_timer_config(const belle_sip_stack_t * stack)135 const belle_sip_timer_config_t *belle_sip_stack_get_timer_config(const belle_sip_stack_t *stack){
136 	return &stack->timer_config;
137 }
138 
belle_sip_stack_set_timer_config(belle_sip_stack_t * stack,const belle_sip_timer_config_t * timer_config)139 void belle_sip_stack_set_timer_config(belle_sip_stack_t *stack,const belle_sip_timer_config_t *timer_config){
140 	belle_sip_message("Setting timer config to T1 [%i], T2 [%i], T3 [%i], T4 [%i] on stack [%p]", timer_config->T1
141 																								, timer_config->T2
142 																								, timer_config->T3
143 																								, timer_config->T4
144 																								, stack);
145 	stack->timer_config=*timer_config;
146 }
147 
belle_sip_stack_set_transport_timeout(belle_sip_stack_t * stack,int timeout_ms)148 void belle_sip_stack_set_transport_timeout(belle_sip_stack_t *stack, int timeout_ms){
149 	stack->transport_timeout=timeout_ms;
150 }
151 
belle_sip_stack_get_transport_timeout(const belle_sip_stack_t * stack)152 int belle_sip_stack_get_transport_timeout(const belle_sip_stack_t *stack){
153 	return stack->transport_timeout;
154 }
155 
belle_sip_stack_get_dns_timeout(const belle_sip_stack_t * stack)156 int belle_sip_stack_get_dns_timeout(const belle_sip_stack_t *stack) {
157 	return stack->dns_timeout;
158 }
159 
belle_sip_stack_set_dns_timeout(belle_sip_stack_t * stack,int timeout)160 void belle_sip_stack_set_dns_timeout(belle_sip_stack_t *stack, int timeout) {
161 	stack->dns_timeout = timeout;
162 }
163 
belle_sip_stack_dns_srv_enabled(const belle_sip_stack_t * stack)164 unsigned char belle_sip_stack_dns_srv_enabled(const belle_sip_stack_t *stack) {
165 	return stack->dns_srv_enabled;
166 }
167 
belle_sip_stack_enable_dns_srv(belle_sip_stack_t * stack,unsigned char enable)168 void belle_sip_stack_enable_dns_srv(belle_sip_stack_t *stack, unsigned char enable) {
169 	stack->dns_srv_enabled = enable;
170 }
171 
belle_sip_stack_dns_search_enabled(const belle_sip_stack_t * stack)172 unsigned char belle_sip_stack_dns_search_enabled(const belle_sip_stack_t *stack) {
173 	return stack->dns_search_enabled;
174 }
175 
belle_sip_stack_enable_dns_search(belle_sip_stack_t * stack,unsigned char enable)176 void belle_sip_stack_enable_dns_search(belle_sip_stack_t *stack, unsigned char enable) {
177 	stack->dns_search_enabled = enable;
178 }
179 
belle_sip_stack_create_listening_point(belle_sip_stack_t * s,const char * ipaddress,int port,const char * transport)180 belle_sip_listening_point_t *belle_sip_stack_create_listening_point(belle_sip_stack_t *s, const char *ipaddress, int port, const char *transport){
181 	belle_sip_listening_point_t *lp=NULL;
182 	if (strcasecmp(transport,"UDP")==0) {
183 		lp=belle_sip_udp_listening_point_new(s,ipaddress,port);
184 	} else if (strcasecmp(transport,"TCP") == 0) {
185 		lp=belle_sip_stream_listening_point_new(s,ipaddress,port);
186 	}else if (strcasecmp(transport,"TLS") == 0) {
187 		lp=belle_sip_tls_listening_point_new(s,ipaddress,port);
188 	} else {
189 		belle_sip_fatal("Unsupported transport %s",transport);
190 	}
191 	return lp;
192 }
193 
belle_sip_stack_delete_listening_point(belle_sip_stack_t * s,belle_sip_listening_point_t * lp)194 void belle_sip_stack_delete_listening_point(belle_sip_stack_t *s, belle_sip_listening_point_t *lp){
195 	belle_sip_object_unref(lp);
196 }
197 
belle_sip_stack_create_provider(belle_sip_stack_t * s,belle_sip_listening_point_t * lp)198 belle_sip_provider_t *belle_sip_stack_create_provider(belle_sip_stack_t *s, belle_sip_listening_point_t *lp){
199 	belle_sip_provider_t *p=belle_sip_provider_new(s,lp);
200 	return p;
201 }
202 
belle_sip_stack_create_http_provider(belle_sip_stack_t * s,const char * bind_ip)203 belle_http_provider_t *belle_sip_stack_create_http_provider(belle_sip_stack_t *s, const char *bind_ip){
204 	belle_http_provider_t *p=belle_http_provider_new(s, bind_ip);
205 	return p;
206 }
207 
belle_sip_stack_delete_provider(belle_sip_stack_t * s,belle_sip_provider_t * p)208 void belle_sip_stack_delete_provider(belle_sip_stack_t *s, belle_sip_provider_t *p){
209 	belle_sip_object_unref(p);
210 }
211 
belle_sip_stack_get_main_loop(belle_sip_stack_t * stack)212 belle_sip_main_loop_t * belle_sip_stack_get_main_loop(belle_sip_stack_t *stack){
213 	return stack->ml;
214 }
215 
belle_sip_stack_main(belle_sip_stack_t * stack)216 void belle_sip_stack_main(belle_sip_stack_t *stack){
217 	belle_sip_main_loop_run(stack->ml);
218 }
219 
belle_sip_stack_sleep(belle_sip_stack_t * stack,unsigned int milliseconds)220 void belle_sip_stack_sleep(belle_sip_stack_t *stack, unsigned int milliseconds){
221 	belle_sip_main_loop_sleep (stack->ml,milliseconds);
222 }
223 
belle_sip_stack_get_next_hop(belle_sip_stack_t * stack,belle_sip_request_t * req)224 belle_sip_hop_t * belle_sip_stack_get_next_hop(belle_sip_stack_t *stack, belle_sip_request_t *req) {
225 	belle_sip_header_route_t *route=BELLE_SIP_HEADER_ROUTE(belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"route"));
226 	belle_sip_uri_t *uri;
227 
228 	if (route!=NULL){
229 		uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(route));
230 	}else{
231 		uri=belle_sip_request_get_uri(req);
232 	}
233 	return belle_sip_hop_new_from_uri(uri);
234 }
235 
236 
237 
belle_sip_stack_set_tx_delay(belle_sip_stack_t * stack,int delay_ms)238 void belle_sip_stack_set_tx_delay(belle_sip_stack_t *stack, int delay_ms){
239 	stack->tx_delay=delay_ms;
240 }
belle_sip_stack_set_send_error(belle_sip_stack_t * stack,int send_error)241 void belle_sip_stack_set_send_error(belle_sip_stack_t *stack, int send_error){
242 	stack->send_error=send_error;
243 }
244 
belle_sip_stack_set_resolver_tx_delay(belle_sip_stack_t * stack,int delay_ms)245 void belle_sip_stack_set_resolver_tx_delay(belle_sip_stack_t *stack, int delay_ms) {
246 	stack->resolver_tx_delay = delay_ms;
247 }
248 
belle_sip_stack_set_resolver_send_error(belle_sip_stack_t * stack,int send_error)249 void belle_sip_stack_set_resolver_send_error(belle_sip_stack_t *stack, int send_error) {
250 	stack->resolver_send_error = send_error;
251 }
252 
belle_sip_stack_get_dns_user_hosts_file(const belle_sip_stack_t * stack)253 const char * belle_sip_stack_get_dns_user_hosts_file(const belle_sip_stack_t *stack) {
254 	return stack->dns_user_hosts_file;
255 }
256 
belle_sip_stack_set_dns_user_hosts_file(belle_sip_stack_t * stack,const char * hosts_file)257 void belle_sip_stack_set_dns_user_hosts_file(belle_sip_stack_t *stack, const char *hosts_file) {
258 	if (stack->dns_user_hosts_file) belle_sip_free(stack->dns_user_hosts_file);
259 	stack->dns_user_hosts_file = hosts_file?belle_sip_strdup(hosts_file):NULL;
260 }
261 
belle_sip_stack_get_dns_resolv_conf_file(const belle_sip_stack_t * stack)262 const char * belle_sip_stack_get_dns_resolv_conf_file(const belle_sip_stack_t *stack){
263 	return stack->dns_resolv_conf;
264 }
265 
belle_sip_stack_set_dns_resolv_conf_file(belle_sip_stack_t * stack,const char * resolv_conf_file)266 void belle_sip_stack_set_dns_resolv_conf_file(belle_sip_stack_t *stack, const char *resolv_conf_file){
267 	if (stack->dns_resolv_conf) belle_sip_free(stack->dns_resolv_conf);
268 	stack->dns_resolv_conf = resolv_conf_file?belle_sip_strdup(resolv_conf_file):NULL;
269 }
270 
belle_sip_stack_set_dns_servers(belle_sip_stack_t * stack,const belle_sip_list_t * servers)271 void belle_sip_stack_set_dns_servers(belle_sip_stack_t *stack, const belle_sip_list_t *servers){
272 	belle_sip_list_t *newservers = NULL;
273 	if (servers) newservers = belle_sip_list_copy_with_data(servers, (void *(*)(void*))belle_sip_strdup);
274 	if (stack->dns_servers){
275 		belle_sip_list_free_with_data(stack->dns_servers, belle_sip_free);
276 	}
277 	stack->dns_servers = newservers;
278 }
279 
belle_sip_version_to_string()280 const char* belle_sip_version_to_string() {
281 #ifdef BELLESIP_VERSION
282 	return BELLESIP_VERSION;
283 #else
284 	return PACKAGE_VERSION;
285 #endif
286 }
287 
belle_sip_stack_get_inactive_transport_timeout(const belle_sip_stack_t * stack)288 int belle_sip_stack_get_inactive_transport_timeout(const belle_sip_stack_t *stack){
289 	return stack->inactive_transport_timeout;
290 }
291 
belle_sip_stack_set_inactive_transport_timeout(belle_sip_stack_t * stack,int seconds)292 void belle_sip_stack_set_inactive_transport_timeout(belle_sip_stack_t *stack, int seconds){
293 	stack->inactive_transport_timeout=seconds;
294 }
295 
belle_sip_stack_set_default_dscp(belle_sip_stack_t * stack,int dscp)296 void belle_sip_stack_set_default_dscp(belle_sip_stack_t *stack, int dscp){
297 	stack->dscp=dscp;
298 }
299 
belle_sip_stack_get_default_dscp(belle_sip_stack_t * stack)300 int belle_sip_stack_get_default_dscp(belle_sip_stack_t *stack){
301 	return stack->dscp;
302 }
303 
belle_sip_stack_tls_available(belle_sip_stack_t * stack)304 int belle_sip_stack_tls_available(belle_sip_stack_t *stack){
305 	return belle_sip_tls_listening_point_available();
306 }
307 
belle_sip_stack_content_encoding_available(belle_sip_stack_t * stack,const char * content_encoding)308 int belle_sip_stack_content_encoding_available(belle_sip_stack_t *stack, const char *content_encoding) {
309 #ifdef HAVE_ZLIB
310 	if (strcmp(content_encoding, "deflate") == 0) return TRUE;
311 #endif
312 	return FALSE;
313 }
314 
315 GET_SET_STRING(belle_sip_stack,http_proxy_host)
316 GET_SET_INT(belle_sip_stack,http_proxy_port, int)
317 
318