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