From 200f6ea9264ddfcabf7b8c91a96e6f3e894655dc Mon Sep 17 00:00:00 2001 From: Thomas Ries Date: Sun, 13 Jun 2004 12:46:33 +0000 Subject: [PATCH] - use SIGUSR2 for dmalloc debugging (SIGUSR1 is occupied with old libc5 & threads) - reworked calling parameters for passing SIP data --- ChangeLog | 4 ++ src/auth.c | 8 +-- src/proxy.c | 47 +++++++++---- src/register.c | 53 ++++++++------- src/security.c | 4 +- src/sip_utils.c | 39 ++++++----- src/siproxd.c | 85 ++++++++++++----------- src/siproxd.h | 176 ++++++++++++++++++++++++++---------------------- src/sock.c | 11 ++- 9 files changed, 244 insertions(+), 183 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3bac3b..57dfad3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 0.5.7 ===== + 13-Jun-2004: - fix: get_ip_by_host() and buffers for reentrant functions + 12-Jun-2004: - use SIGUSR2 for dmalloc debugging (SIGUSR1 is occupied + with old libc5 & threads) + - reworked calling parameters for passing SIP data 11-Jun-2004: - silenced some MSN Messenger provoked WARNings 29-May-2004: - "determine next hop" also takes Route header into account (outgoing packets only, incoming can not have a proxy diff --git a/src/auth.c b/src/auth.c index 4fbfce6..f8d04c7 100644 --- a/src/auth.c +++ b/src/auth.c @@ -55,7 +55,7 @@ static char *auth_getpwd(char *username); * STS_FAILURE : authentication failed * STS_NEEDAUTH: authentication needed */ -int authenticate_proxy(osip_message_t *request) { +int authenticate_proxy(sip_ticket_t *ticket) { osip_proxy_authorization_t *proxy_auth=NULL; /* required by config? */ @@ -64,7 +64,7 @@ int authenticate_proxy(osip_message_t *request) { } /* supplied by UA? */ - osip_message_get_proxy_authorization(request, 0, &proxy_auth); + osip_message_get_proxy_authorization(ticket->sipmsg, 0, &proxy_auth); if (proxy_auth == NULL) { DEBUGC(DBCLASS_AUTH,"proxy-auth required, not supplied by UA"); return STS_NEED_AUTH; @@ -88,7 +88,7 @@ int authenticate_proxy(osip_message_t *request) { * STS_SUCCESS * STS_FAILURE */ -int auth_include_authrq(osip_message_t *response) { +int auth_include_authrq(sip_ticket_t *ticket) { osip_proxy_authenticate_t *p_auth; char *realm=NULL; @@ -109,7 +109,7 @@ int auth_include_authrq(osip_message_t *response) { return STS_FAILURE; } - osip_list_add (response->proxy_authenticates, p_auth, -1); + osip_list_add (ticket->sipmsg->proxy_authenticates, p_auth, -1); DEBUGC(DBCLASS_AUTH,"added authentication header"); diff --git a/src/proxy.c b/src/proxy.c index 5ae5f16..63837a4 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -74,7 +74,7 @@ extern struct lcl_if_s local_addresses; * 10. Forward the new request * 11. Set timer C */ -int proxy_request (osip_message_t *request, struct sockaddr_in *from) { +int proxy_request (sip_ticket_t *ticket) { int i; int sts; int type; @@ -82,12 +82,21 @@ int proxy_request (osip_message_t *request, struct sockaddr_in *from) { osip_uri_t *url; int port; char *buffer; + osip_message_t *request; + struct sockaddr_in *from; #define REQTYP_INCOMING 1 #define REQTYP_OUTGOING 2 DEBUGC(DBCLASS_PROXY,"proxy_request"); + if (ticket==NULL) { + ERROR("proxy_request: called with NULL ticket"); + return STS_FAILURE; + } + + request=ticket->sipmsg; + from=&ticket->from; /* * RFC 3261, Section 16.4 @@ -336,7 +345,7 @@ int proxy_request (osip_message_t *request, struct sockaddr_in *from) { /* careful - an internal UA might send an request to another internal UA. This would be caught here, so don't do this. This situation should be caught in the default part of the CASE statement below */ - if (is_sipuri_local(request) == STS_TRUE) { + if (is_sipuri_local(ticket) == STS_TRUE) { WARN("unsupported request [%s] directed to proxy from %s@%s -> %s@%s", request->sip_method? request->sip_method:"*NULL*", request->from->url->username? request->from->url->username:"*NULL*", @@ -344,14 +353,14 @@ int proxy_request (osip_message_t *request, struct sockaddr_in *from) { url->username? url->username : "*NULL*", url->host? url->host : "*NULL*"); - sip_gen_response(request, 403 /*forbidden*/); + sip_gen_response(ticket, 403 /*forbidden*/); return STS_FAILURE; } #endif /* rewrite Contact header to represent the masqued address */ - sip_rewrite_contact(request, DIR_OUTGOING); + sip_rewrite_contact(ticket, DIR_OUTGOING); /* if an INVITE, rewrite body */ if (MSG_IS_INVITE(request)) { @@ -388,7 +397,7 @@ int proxy_request (osip_message_t *request, struct sockaddr_in *from) { * How about "408 Request Timeout" ? * */ - sip_gen_response(request, 408 /* Request Timeout */); + sip_gen_response(ticket, 408 /* Request Timeout */); return STS_FAILURE; } @@ -613,12 +622,12 @@ We should use the first Route header to send the packet to */ /* add my Via header line (outbound interface)*/ if (type == REQTYP_INCOMING) { - sts = sip_add_myvia(request, IF_INBOUND); + sts = sip_add_myvia(ticket, IF_INBOUND); if (sts == STS_FAILURE) { ERROR("adding my inbound via failed!"); } } else { - sts = sip_add_myvia(request, IF_OUTBOUND); + sts = sip_add_myvia(ticket, IF_OUTBOUND); if (sts == STS_FAILURE) { ERROR("adding my outbound via failed!"); return STS_FAILURE; @@ -640,7 +649,8 @@ We should use the first Route header to send the packet to return STS_FAILURE; } - sipsock_send(sendto_addr, port, buffer, strlen(buffer)); + sipsock_send(sendto_addr, port, ticket->protocol, + buffer, strlen(buffer)); osip_free (buffer); /* @@ -660,7 +670,7 @@ We should use the first Route header to send the packet to * STS_SUCCESS on success * STS_FAILURE on error */ -int proxy_response (osip_message_t *response, struct sockaddr_in *from) { +int proxy_response (sip_ticket_t *ticket) { int i; int sts; int type; @@ -668,18 +678,28 @@ int proxy_response (osip_message_t *response, struct sockaddr_in *from) { osip_via_t *via; int port; char *buffer; + osip_message_t *response; + struct sockaddr_in *from; #define RESTYP_INCOMING 1 #define RESTYP_OUTGOING 2 DEBUGC(DBCLASS_PROXY,"proxy_response"); + if (ticket==NULL) { + ERROR("proxy_response: called with NULL ticket"); + return STS_FAILURE; + } + + response=ticket->sipmsg; + from=&ticket->from; + /* * RFC 3261, Section 16.11 * Proxy Behavior - Remove my Via header field value */ /* remove my Via header line */ - sts = sip_del_myvia(response); + sts = sip_del_myvia(ticket); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_PROXY,"not addressed to my VIA, ignoring response"); return STS_FAILURE; @@ -794,7 +814,7 @@ int proxy_response (osip_message_t *response, struct sockaddr_in *from) { * Rewrite Contact header back to represent the true address. * Other responses do return the Contact header of the sender. */ - sip_rewrite_contact(response, DIR_INCOMING); + sip_rewrite_contact(ticket, DIR_INCOMING); } /* @@ -840,7 +860,7 @@ int proxy_response (osip_message_t *response, struct sockaddr_in *from) { response->from->url->host : "*NULL*"); /* rewrite Contact header to represent the masqued address */ - sip_rewrite_contact(response, DIR_OUTGOING); + sip_rewrite_contact(ticket, DIR_OUTGOING); /* If an 200 OK or 183 Trying answer to an INVITE request, * rewrite body */ @@ -905,7 +925,8 @@ int proxy_response (osip_message_t *response, struct sockaddr_in *from) { return STS_FAILURE; } - sipsock_send(sendto_addr, port, buffer, strlen(buffer)); + sipsock_send(sendto_addr, port, ticket->protocol, + buffer, strlen(buffer)); osip_free (buffer); return STS_SUCCESS; } diff --git a/src/register.c b/src/register.c index 168aa25..06a3928 100644 --- a/src/register.c +++ b/src/register.c @@ -163,7 +163,7 @@ void register_shut(void) { * STS_FAILURE : registration failed * STS_NEED_AUTH : authentication needed */ -int register_client(osip_message_t *my_msg, int force_lcl_masq) { +int register_client(sip_ticket_t *ticket, int force_lcl_masq) { int i, j, n, sts; int expires; time_t time_now; @@ -181,17 +181,19 @@ int register_client(osip_message_t *my_msg, int force_lcl_masq) { * RFC 3261, Section 16.3 step 6 * Proxy Behavior - Request Validation - Proxy-Authorization */ - sts = authenticate_proxy(my_msg); + sts = authenticate_proxy(ticket); if (sts == STS_FAILURE) { /* failed */ WARN("proxy authentication failed for %s@%s", - (my_msg->to->url->username)? my_msg->to->url->username : "*NULL*", - my_msg->to->url->host); + (ticket->sipmsg->to->url->username)? + ticket->sipmsg->to->url->username : "*NULL*", + ticket->sipmsg->to->url->host); return STS_FAILURE; } else if (sts == STS_NEED_AUTH) { /* needed */ DEBUGC(DBCLASS_REG,"proxy authentication needed for %s@%s", - my_msg->to->url->username,my_msg->to->url->host); + ticket->sipmsg->to->url->username, + ticket->sipmsg->to->url->host); return STS_NEED_AUTH; } } @@ -215,14 +217,14 @@ int register_client(osip_message_t *my_msg, int force_lcl_masq) { DEBUGC(DBCLASS_BABBLE,"sip_register:"); /* evaluate Expires Header field */ - osip_message_get_expires(my_msg, 0, &expires_hdr); + osip_message_get_expires(ticket->sipmsg, 0, &expires_hdr); /* * look for an Contact expires parameter - in case of REGISTER * these two are equal. The Contact expires has higher priority! */ osip_contact_param_get_byname( - (osip_contact_t*) my_msg->contacts->node->element, + (osip_contact_t*) ticket->sipmsg->contacts->node->element, EXPIRES, &expires_param); if (expires_param && expires_param->gvalue) { @@ -235,10 +237,10 @@ int register_client(osip_message_t *my_msg, int force_lcl_masq) { /* it seems, the expires field is not present everywhere... */ DEBUGC(DBCLASS_REG,"no 'expires' header found - set time to 600 sec"); expires=600; - osip_message_set_expires(my_msg, "600"); + osip_message_set_expires(ticket->sipmsg, "600"); } - url1_to=my_msg->to->url; + url1_to=ticket->sipmsg->to->url; @@ -257,7 +259,8 @@ int register_client(osip_message_t *my_msg, int force_lcl_masq) { * (gdb) p *((osip_contact_t*)(sip->contacts->node->element)) * $5 = {displayname = 0x8af8848 "*", url = 0x0, gen_params = 0x8af8838} */ - url1_contact=((osip_contact_t*)(my_msg->contacts->node->element))->url; + url1_contact=((osip_contact_t*) + (ticket->sipmsg->contacts->node->element))->url; if ((url1_contact == NULL) || (url1_contact->host == NULL)) { /* Don't have reqiured Contact fields */ ERROR("tried registration with empty Contact header"); @@ -310,10 +313,11 @@ int register_client(osip_message_t *my_msg, int force_lcl_masq) { /* write entry */ urlmap[i].active=1; /* Contact: field */ - osip_uri_clone( ((osip_contact_t*)(my_msg->contacts->node->element))->url, - &urlmap[i].true_url); + osip_uri_clone( ((osip_contact_t*) + (ticket->sipmsg->contacts->node->element))->url, + &urlmap[i].true_url); /* To: field */ - osip_uri_clone( my_msg->to->url, + osip_uri_clone( ticket->sipmsg->to->url, &urlmap[i].reg_url); DEBUGC(DBCLASS_REG,"create new entry for %s@%s <-> %s@%s at slot=%i", @@ -326,7 +330,7 @@ int register_client(osip_message_t *my_msg, int force_lcl_masq) { /* * try to figure out if we ought to do some masquerading */ - osip_uri_clone( my_msg->to->url, + osip_uri_clone( ticket->sipmsg->to->url, &urlmap[i].masq_url); n=configuration.mask_host.used; @@ -338,9 +342,9 @@ int register_client(osip_message_t *my_msg, int force_lcl_masq) { DEBUG("%i entries in MASK config table", n); for (j=0; j [%s]",configuration.mask_host.string[j], - my_msg->to->url->host); + ticket->sipmsg->to->url->host); if (strcmp(configuration.mask_host.string[j], - my_msg->to->url->host)==0) + ticket->sipmsg->to->url->host)==0) break; } if (jcontacts->node->element))->url, - &urlmap[i].true_url); + osip_uri_clone( ((osip_contact_t*) + (ticket->sipmsg->contacts->node->element))->url, + &urlmap[i].true_url); /* To: field */ osip_uri_free(urlmap[i].reg_url); - osip_uri_clone( my_msg->to->url, + osip_uri_clone( ticket->sipmsg->to->url, &urlmap[i].reg_url); } /* give some safety margin for the next update */ @@ -459,7 +464,7 @@ void register_agemap(void) { * STS_SUCCESS on success * STS_FAILURE on error */ -int register_response(osip_message_t *request, int flag) { +int register_response(sip_ticket_t *ticket, int flag) { osip_message_t *response; int code; int sts; @@ -486,13 +491,13 @@ int register_response(osip_message_t *request, int flag) { } /* create the response template */ - if ((response=msg_make_template_reply(request, code))==NULL) { + if ((response=msg_make_template_reply(ticket, code))==NULL) { ERROR("register_response: error in msg_make_template_reply"); return STS_FAILURE; } /* insert the expiration header */ - osip_message_get_expires(request, 0, &expires_hdr); + osip_message_get_expires(ticket->sipmsg, 0, &expires_hdr); if (expires_hdr) { osip_message_set_expires(response, expires_hdr->hvalue); } @@ -500,7 +505,7 @@ int register_response(osip_message_t *request, int flag) { /* if we send back an proxy authentication needed, include the Proxy-Authenticate field */ if (code == 407) { - auth_include_authrq(response); + auth_include_authrq(ticket); } /* get the IP address from existing VIA header */ @@ -534,7 +539,7 @@ int register_response(osip_message_t *request, int flag) { port=configuration.sip_listen_port; } - sipsock_send(addr, port, buffer, strlen(buffer)); + sipsock_send(addr, port, ticket->protocol, buffer, strlen(buffer)); /* free the resources */ osip_message_free(response); diff --git a/src/security.c b/src/security.c index 66e497b..53c4b64 100644 --- a/src/security.c +++ b/src/security.c @@ -110,8 +110,8 @@ int security_check_raw(char *sip_buffer, int size) { * STS_SUCCESS if ok * STS_FAILURE if the packed did not pass the checks */ -int security_check_sip(osip_message_t *sip){ - +int security_check_sip(sip_ticket_t *ticket){ + osip_message_t *sip=ticket->sipmsg; if (MSG_IS_REQUEST(sip)) { /* check for existing SIP URI in request */ if ((sip->req_uri == NULL) || (sip->req_uri->scheme == NULL)) { diff --git a/src/sip_utils.c b/src/sip_utils.c index 6a85213..5366ca4 100644 --- a/src/sip_utils.c +++ b/src/sip_utils.c @@ -59,7 +59,8 @@ extern struct urlmap_s urlmap[]; /* URL mapping table */ * * RETURNS a pointer to osip_message_t */ -osip_message_t *msg_make_template_reply (osip_message_t * request, int code) { +osip_message_t *msg_make_template_reply (sip_ticket_t *ticket, int code) { + osip_message_t *request=ticket->sipmsg; osip_message_t *response; int pos; @@ -114,7 +115,7 @@ osip_message_t *msg_make_template_reply (osip_message_t * request, int code) { * STS_TRUE if loop detected * STS_FALSE if no loop */ -int check_vialoop (osip_message_t *my_msg) { +int check_vialoop (sip_ticket_t *ticket) { /* !!! actually this is a problematic one. 1) for requests, I must search the whole VIA list @@ -134,6 +135,7 @@ int check_vialoop (osip_message_t *my_msg) { to-be-unique ID) */ + osip_message_t *my_msg=ticket->sipmsg; int sts; int pos; int found_own_via; @@ -383,7 +385,8 @@ mismatch: * STS_TRUE if the request is addressed local * STS_FALSE otherwise */ -int is_sipuri_local (osip_message_t *sip) { +int is_sipuri_local (sip_ticket_t *ticket) { + osip_message_t *sip=ticket->sipmsg; int sts, found; struct in_addr addr_uri, addr_myself; char *my_interfaces[]= @@ -520,7 +523,7 @@ int check_rewrite_rq_uri (osip_message_t *sip) { * STS_SUCCESS on success * STS_FAILURE on error */ -int sip_gen_response(osip_message_t *request, int code) { +int sip_gen_response(sip_ticket_t *ticket, int code) { osip_message_t *response; int sts; osip_via_t *via; @@ -529,8 +532,8 @@ int sip_gen_response(osip_message_t *request, int code) { struct in_addr addr; /* create the response template */ - if ((response=msg_make_template_reply(request, code))==NULL) { - ERROR("proxy_response: error in msg_make_template_reply"); + if ((response=msg_make_template_reply(ticket, code))==NULL) { + ERROR("sip_gen_response: error in msg_make_template_reply"); return STS_FAILURE; } @@ -538,7 +541,7 @@ int sip_gen_response(osip_message_t *request, int code) { osip_message_get_via (response, 0, &via); if (via == NULL) { - ERROR("proxy_response: Cannot send response - no via field"); + ERROR("sip_gen_response: Cannot send response - no via field"); return STS_FAILURE; } @@ -558,7 +561,7 @@ int sip_gen_response(osip_message_t *request, int code) { sts = osip_message_to_str(response, &buffer); if (sts != 0) { - ERROR("proxy_response: msg_2char failed"); + ERROR("sip_gen_response: msg_2char failed"); return STS_FAILURE; } @@ -570,7 +573,7 @@ int sip_gen_response(osip_message_t *request, int code) { } /* send to destination */ - sipsock_send(addr, port, buffer, strlen(buffer)); + sipsock_send(addr, port, ticket->protocol, buffer, strlen(buffer)); /* free the resources */ osip_message_free(response); @@ -588,7 +591,7 @@ int sip_gen_response(osip_message_t *request, int code) { * STS_SUCCESS on success * STS_FAILURE on error */ -int sip_add_myvia (osip_message_t *request, int interface) { +int sip_add_myvia (sip_ticket_t *ticket, int interface) { struct in_addr addr; char tmp[URL_STRING_SIZE]; osip_via_t *via; @@ -611,7 +614,7 @@ int sip_add_myvia (osip_message_t *request, int interface) { } } - sts = sip_calculate_branch_id(request, branch_id); + sts = sip_calculate_branch_id(ticket, branch_id); sprintf(tmp, "SIP/2.0/UDP %s:%i;branch=%s;", utils_inet_ntoa(addr), configuration.sip_listen_port, branch_id); @@ -623,7 +626,7 @@ int sip_add_myvia (osip_message_t *request, int interface) { sts = osip_via_parse(via, tmp); if (sts!=0) return STS_FAILURE; - osip_list_add(request->vias,via,0); + osip_list_add(ticket->sipmsg->vias,via,0); return STS_SUCCESS; } @@ -636,12 +639,12 @@ int sip_add_myvia (osip_message_t *request, int interface) { * STS_SUCCESS on success * STS_FAILURE on error */ -int sip_del_myvia (osip_message_t *response) { +int sip_del_myvia (sip_ticket_t *ticket) { osip_via_t *via; int sts; DEBUGC(DBCLASS_PROXY,"deleting topmost VIA"); - via = osip_list_get (response->vias, 0); + via = osip_list_get (ticket->sipmsg->vias, 0); if ( via == NULL ) { ERROR("Got empty VIA list - is your UA configured properly?"); @@ -653,7 +656,7 @@ int sip_del_myvia (osip_message_t *response) { return STS_FAILURE; } - sts = osip_list_remove(response->vias, 0); + sts = osip_list_remove(ticket->sipmsg->vias, 0); osip_via_free (via); return STS_SUCCESS; } @@ -668,7 +671,8 @@ int sip_del_myvia (osip_message_t *response) { * STS_SUCCESS on success * STS_FAILURE on error */ -int sip_rewrite_contact (osip_message_t *sip_msg, int direction) { +int sip_rewrite_contact (sip_ticket_t *ticket, int direction) { + osip_message_t *sip_msg=ticket->sipmsg; osip_contact_t *contact; int i; @@ -733,7 +737,7 @@ int sip_rewrite_contact (osip_message_t *sip_msg, int direction) { * STS_SUCCESS on success * STS_FAILURE on error */ -int sip_calculate_branch_id (osip_message_t *sip_msg, char *id) { +int sip_calculate_branch_id (sip_ticket_t *ticket, char *id) { /* RFC3261 section 16.11 recommends the following procedure: * The stateless proxy MAY use any technique it likes to guarantee * uniqueness of its branch IDs across transactions. However, the @@ -754,6 +758,7 @@ int sip_calculate_branch_id (osip_message_t *sip_msg, char *id) { * - 1st part (unique calculated ID * - 2nd part (value for loop detection) <<- not yet used by siproxd */ + osip_message_t *sip_msg=ticket->sipmsg; static char *magic_cookie="z9hG4bK"; osip_via_t *via; osip_uri_param_t *param=NULL; diff --git a/src/siproxd.c b/src/siproxd.c index caa8bf9..c5ca452 100644 --- a/src/siproxd.c +++ b/src/siproxd.c @@ -72,9 +72,8 @@ int main (int argc, char *argv[]) int sts; int i; int access; - struct sockaddr_in from; char buff [BUFFER_SIZE]; - osip_message_t *my_msg=NULL; + sip_ticket_t ticket; extern char *optarg; int ch1; @@ -99,8 +98,8 @@ int main (int argc, char *argv[]) if (sigaction(SIGINT, &act, NULL)) { ERROR("Failed to install SIGINT handler"); } - if (sigaction(SIGUSR1, &act, NULL)) { - ERROR("Failed to install SIGUSR1 handler"); + if (sigaction(SIGUSR2, &act, NULL)) { + ERROR("Failed to install SIGUSR2 handler"); } @@ -245,11 +244,11 @@ int main (int argc, char *argv[]) if (dmalloc_dump) { dmalloc_dump=0; #ifdef DMALLOC - INFO("SIGUSR1 - DMALLOC statistics is dumped"); + INFO("SIGUSR2 - DMALLOC statistics is dumped"); dmalloc_log_stats(); dmalloc_log_unfreed(); #else - INFO("SIGUSR1 - DMALLOC support is not compiled in"); + INFO("SIGUSR2 - DMALLOC support is not compiled in"); #endif } @@ -259,11 +258,11 @@ int main (int argc, char *argv[]) /* got input, process */ DEBUGC(DBCLASS_BABBLE,"back from sip_wait"); - i=sipsock_read(&buff, sizeof(buff)-1, &from); + i=sipsock_read(&buff, sizeof(buff)-1, &ticket.from, &ticket.protocol); buff[i]='\0'; /* evaluate the access lists (IP based filter)*/ - access=accesslist_check(from); + access=accesslist_check(ticket.from); if (access == 0) continue; /* there are no resources to free */ /* integrity checks */ @@ -271,8 +270,8 @@ int main (int argc, char *argv[]) if (sts != STS_SUCCESS) continue; /* there are no resources to free */ /* init sip_msg */ - sts=osip_message_init(&my_msg); - my_msg->message=NULL; + sts=osip_message_init(&ticket.sipmsg); + ticket.sipmsg->message=NULL; if (sts != 0) { ERROR("osip_message_init() failed... this is not good"); continue; /* skip, there are no resources to free */ @@ -283,7 +282,7 @@ int main (int argc, char *argv[]) * Proxy Behavior - Request Validation - Reasonable Syntax * (parse the received message) */ - sts=osip_message_parse(my_msg, buff); + sts=osip_message_parse(ticket.sipmsg, buff); if (sts != 0) { ERROR("osip_message_parse() failed... this is not good"); DUMP_BUFFER(-1, buff, i); @@ -291,7 +290,7 @@ int main (int argc, char *argv[]) } /* integrity checks - parsed buffer*/ - sts=security_check_sip(my_msg); + sts=security_check_sip(&ticket); if (sts != STS_SUCCESS) { ERROR("security_check_sip() failed... this is not good"); DUMP_BUFFER(-1, buff, i); @@ -314,7 +313,7 @@ int main (int argc, char *argv[]) osip_header_t *max_forwards; int forwards_count = DEFAULT_MAXFWD; - osip_message_get_max_forwards(my_msg, 0, &max_forwards); + osip_message_get_max_forwards(ticket.sipmsg, 0, &max_forwards); if (max_forwards && max_forwards->hvalue) { forwards_count = atoi(max_forwards->hvalue); } @@ -322,7 +321,7 @@ int main (int argc, char *argv[]) DEBUGC(DBCLASS_PROXY,"checking Max-Forwards (=%i)",forwards_count); if (forwards_count <= 0) { DEBUGC(DBCLASS_SIP, "Forward count reached 0 -> 483 response"); - sip_gen_response(my_msg, 483 /*Too many hops*/); + sip_gen_response(&ticket, 483 /*Too many hops*/); goto end_loop; /* skip and free resources */ } @@ -333,14 +332,15 @@ int main (int argc, char *argv[]) * Proxy Behavior - Request Validation - Loop Detection check * (check for loop and return 482 if a loop is detected) */ - if (check_vialoop(my_msg) == STS_TRUE) { + if (check_vialoop(&ticket) == STS_TRUE) { /* make sure we don't end up in endless loop when detecting * an loop in an "loop detected" message - brrr */ - if (MSG_IS_RESPONSE(my_msg) && MSG_TEST_CODE(my_msg, 482)) { + if (MSG_IS_RESPONSE(ticket.sipmsg) && + MSG_TEST_CODE(ticket.sipmsg, 482)) { DEBUGC(DBCLASS_SIP,"loop in loop-response detected, ignoring"); } else { DEBUGC(DBCLASS_SIP,"via loop detected, ignoring request"); - sip_gen_response(my_msg, 482 /*Loop detected*/); + sip_gen_response(&ticket, 482 /*Loop detected*/); } goto end_loop; /* skip and free resources */ } @@ -359,10 +359,12 @@ int main (int argc, char *argv[]) /* NOT IMPLEMENTED */ DEBUGC(DBCLASS_SIP,"received SIP type %s:%s", - (MSG_IS_REQUEST(my_msg))? "REQ" : "RES", - (MSG_IS_REQUEST(my_msg) ? - ((my_msg->sip_method)? my_msg->sip_method : "NULL") : - ((my_msg->reason_phrase) ? my_msg->reason_phrase : "NULL"))); + (MSG_IS_REQUEST(ticket.sipmsg))? "REQ" : "RES", + (MSG_IS_REQUEST(ticket.sipmsg) ? + ((ticket.sipmsg->sip_method)? + ticket.sipmsg->sip_method : "NULL") : + ((ticket.sipmsg->reason_phrase) ? + ticket.sipmsg->reason_phrase : "NULL"))); /* * if an REQ REGISTER, check if it is directed to myself, @@ -370,12 +372,13 @@ int main (int argc, char *argv[]) * - If I'm the registrar, register & generate answer * - If I'm just the outbound proxy, register, rewrite & forward */ - if (MSG_IS_REGISTER(my_msg) && MSG_IS_REQUEST(my_msg)) { + if (MSG_IS_REGISTER(ticket.sipmsg) && + MSG_IS_REQUEST(ticket.sipmsg)) { if (access & ACCESSCTL_REG) { osip_uri_t *url; struct in_addr addr1, addr2, addr3; - url = osip_message_get_uri(my_msg); + url = osip_message_get_uri(ticket.sipmsg); sts = get_ip_by_host(url->host, &addr1); get_ip_by_ifname(configuration.inbound_if,&addr2); @@ -385,17 +388,17 @@ int main (int argc, char *argv[]) ((memcmp(&addr1, &addr2, sizeof(addr1)) == 0) || (memcmp(&addr1, &addr3, sizeof(addr1)) == 0))) { /* I'm the registrar, send response myself */ - sts = register_client(my_msg, 0); - sts = register_response(my_msg, sts); + sts = register_client(&ticket, 0); + sts = register_response(&ticket, sts); } else { /* I'm just the outbound proxy */ DEBUGC(DBCLASS_SIP,"proxying REGISTER request to:%s",url->host); - sts = register_client(my_msg, 1); - sts = proxy_request(my_msg, &from); + sts = register_client(&ticket, 1); + sts = proxy_request(&ticket); } } else { WARN("non-authorized registration attempt from %s", - utils_inet_ntoa(from.sin_addr)); + utils_inet_ntoa(ticket.from.sin_addr)); } /* @@ -406,34 +409,34 @@ int main (int argc, char *argv[]) } else if (get_ip_by_ifname(configuration.outbound_if,NULL) != STS_SUCCESS) { DEBUGC(DBCLASS_SIP, "got a %s to proxy, but outbound interface " - "is down", (MSG_IS_REQUEST(my_msg))? "REQ" : "RES"); + "is down", (MSG_IS_REQUEST(ticket.sipmsg))? "REQ" : "RES"); - if (MSG_IS_REQUEST(my_msg)) - sip_gen_response(my_msg, 408 /*request timeout*/); + if (MSG_IS_REQUEST(ticket.sipmsg)) + sip_gen_response(&ticket, 408 /*request timeout*/); /* * MSG is a request, add current via entry, * do a lookup in the URLMAP table and * send to the final destination */ - } else if (MSG_IS_REQUEST(my_msg)) { + } else if (MSG_IS_REQUEST(ticket.sipmsg)) { if (access & ACCESSCTL_SIP) { - sts = proxy_request(my_msg, &from); + sts = proxy_request(&ticket); } else { INFO("non-authorized request received from %s", - utils_inet_ntoa(from.sin_addr)); + utils_inet_ntoa(ticket.from.sin_addr)); } /* * MSG is a response, remove current via and * send to the next VIA in chain */ - } else if (MSG_IS_RESPONSE(my_msg)) { + } else if (MSG_IS_RESPONSE(ticket.sipmsg)) { if (access & ACCESSCTL_SIP) { - sts = proxy_response(my_msg, &from); + sts = proxy_response(&ticket); } else { INFO("non-authorized response received from %s", - utils_inet_ntoa(from.sin_addr)); + utils_inet_ntoa(ticket.from.sin_addr)); } /* @@ -441,8 +444,8 @@ int main (int argc, char *argv[]) */ } else { ERROR("received unsupported SIP type %s %s", - (MSG_IS_REQUEST(my_msg))? "REQ" : "RES", - my_msg->sip_method); + (MSG_IS_REQUEST(ticket.sipmsg))? "REQ" : "RES", + ticket.sipmsg->sip_method); } @@ -450,7 +453,7 @@ int main (int argc, char *argv[]) * free the SIP message buffers */ end_loop: - osip_message_free(my_msg); + osip_message_free(ticket.sipmsg); } /* while TRUE */ exit_prg: @@ -482,6 +485,6 @@ int main (int argc, char *argv[]) static void sighandler(int sig) { if (sig==SIGTERM) exit_program=1; if (sig==SIGINT) exit_program=1; - if (sig==SIGUSR1) dmalloc_dump=1; + if (sig==SIGUSR2) dmalloc_dump=1; return; } diff --git a/src/siproxd.h b/src/siproxd.h index 3a0d398..57a3848 100644 --- a/src/siproxd.h +++ b/src/siproxd.h @@ -25,86 +25,6 @@ #endif -/* function returns STS_* status values vvv */ - -/* sock.c */ -int sipsock_listen (void); /*X*/ -int sipsock_wait(); -int sipsock_read(void *buf, size_t bufsize, - struct sockaddr_in *from); -int sipsock_send(struct in_addr addr, int port, /*X*/ - char *buffer, int size); -int sockbind(struct in_addr ipaddr, int localport, int errflg); - -/* register.c */ -void register_init(void); -void register_shut(void); -int register_client(osip_message_t *request, int force_lcl_masq); /*X*/ -void register_agemap(void); -int register_response(osip_message_t *request, int flag); /*X*/ - -/* proxy.c */ -int proxy_request (osip_message_t *request, struct sockaddr_in *from); /*X*/ -int proxy_response (osip_message_t *response, struct sockaddr_in *from);/*X*/ -int proxy_rewrite_invitation_body(osip_message_t *m, int direction); /*X*/ -int proxy_rewrite_request_uri(osip_message_t *mymsg, int idx); /*X*/ - -/* utils.c */ -int get_ip_by_host(char *hostname, struct in_addr *addr); /*X*/ -void secure_enviroment (void); -int get_ip_by_ifname(char *ifname, struct in_addr *retaddr); /*X*/ -char *utils_inet_ntoa(struct in_addr in); -int utils_inet_aton(const char *cp, struct in_addr *inp); - -/* sip_utils.c */ -osip_message_t * msg_make_template_reply (osip_message_t * request, int code); -int check_vialoop (osip_message_t *my_msg); /*X*/ -int is_via_local (osip_via_t *via); /*X*/ -int compare_url(osip_uri_t *url1, osip_uri_t *url2); /*X*/ -int compare_callid(osip_call_id_t *cid1, osip_call_id_t *cid2); /*X*/ -int is_sipuri_local (osip_message_t *sip); /*X*/ -int check_rewrite_rq_uri (osip_message_t *sip); /*X*/ -int sip_gen_response(osip_message_t *request, int code); /*X*/ -#define IF_OUTBOUND 0 -#define IF_INBOUND 1 -int sip_add_myvia (osip_message_t *request, int interface); /*X*/ -int sip_del_myvia (osip_message_t *response); /*X*/ -int sip_rewrite_contact (osip_message_t *sip_msg, int direction); /*X*/ -int sip_calculate_branch_id (osip_message_t *sip_msg, char *id); /*X*/ - -/* readconf.c */ -int read_config(char *name, int search); /*X*/ - -/* rtpproxy.c */ -int rtpproxy_init( void ); /*X*/ -int rtp_start_fwd (osip_call_id_t *callid, char *client_id, /*X*/ - int direction, int media_stream_no, - struct in_addr outbound_ipaddr, int *outboundport, - struct in_addr lcl_client_ipaddr, int lcl_clientport); -int rtp_stop_fwd (osip_call_id_t *callid, int direction); /*X*/ -void rtpproxy_kill( void ); /*X*/ - -/* accessctl.c */ -int accesslist_check(struct sockaddr_in from); - -/* security.c */ -int security_check_raw(char *sip_buffer, int size); /*X*/ -int security_check_sip(osip_message_t *sip); /*X*/ - -/* auth.c */ -int authenticate_proxy(osip_message_t *request); /*X*/ -int auth_include_authrq(osip_message_t *response); /*X*/ -void CvtHex(char *hash, char *hashstring); - -/* fwapi.h */ -int fwapi_start_rtp(int rtp_direction, - struct in_addr local_ipaddr, int local_port, - struct in_addr remote_ipaddr, int remote_port); -int fwapi_stop_rtp(int rtp_direction, - struct in_addr local_ipaddr, int local_port, - struct in_addr remote_ipaddr, int remote_port); - - /* * table to hold the client registrations */ @@ -163,6 +83,102 @@ struct siproxd_config { char *pid_file; }; +/* + * SIP ticket + */ +typedef struct { + osip_message_t *sipmsg; /* SIP */ + struct sockaddr_in from; /* received from */ +#define PROTO_UNKN -1 +#define PROTO_UDP 1 +#define PROTO_TCP 2 + int protocol; /* received by protocol */ +} sip_ticket_t; + + + +/* + * Function prototypes + */ + +/* function returns STS_* status values vvv */ + +/* sock.c */ +int sipsock_listen (void); /*X*/ +int sipsock_wait(); +int sipsock_read(void *buf, size_t bufsize, + struct sockaddr_in *from, int *protocol); +int sipsock_send(struct in_addr addr, int port, int protocol, /*X*/ + char *buffer, int size); +int sockbind(struct in_addr ipaddr, int localport, int errflg); + +/* register.c */ +void register_init(void); +void register_shut(void); +int register_client(sip_ticket_t *ticket, int force_lcl_masq); /*X*/ +void register_agemap(void); +int register_response(sip_ticket_t *ticket, int flag); /*X*/ + +/* proxy.c */ +int proxy_request (sip_ticket_t *ticket); /*X*/ +int proxy_response (sip_ticket_t *ticket); /*X*/ +int proxy_rewrite_invitation_body(osip_message_t *m, int direction); /*X*/ +int proxy_rewrite_request_uri(osip_message_t *mymsg, int idx); /*X*/ + +/* utils.c */ +int get_ip_by_host(char *hostname, struct in_addr *addr); /*X*/ +void secure_enviroment (void); +int get_ip_by_ifname(char *ifname, struct in_addr *retaddr); /*X*/ +char *utils_inet_ntoa(struct in_addr in); +int utils_inet_aton(const char *cp, struct in_addr *inp); + +/* sip_utils.c */ +osip_message_t * msg_make_template_reply (sip_ticket_t *ticket, int code); +int check_vialoop (sip_ticket_t *ticket); /*X*/ +int is_via_local (osip_via_t *via); /*X*/ +int compare_url(osip_uri_t *url1, osip_uri_t *url2); /*X*/ +int compare_callid(osip_call_id_t *cid1, osip_call_id_t *cid2); /*X*/ +int is_sipuri_local (sip_ticket_t *ticket); /*X*/ +int check_rewrite_rq_uri (osip_message_t *sip); /*X*/ +int sip_gen_response(sip_ticket_t *ticket, int code); /*X*/ +#define IF_OUTBOUND 0 +#define IF_INBOUND 1 +int sip_add_myvia (sip_ticket_t *ticket, int interface); /*X*/ +int sip_del_myvia (sip_ticket_t *ticket); /*X*/ +int sip_rewrite_contact (sip_ticket_t *ticket, int direction); /*X*/ +int sip_calculate_branch_id (sip_ticket_t *ticket, char *id); /*X*/ + +/* readconf.c */ +int read_config(char *name, int search); /*X*/ + +/* rtpproxy.c */ +int rtpproxy_init( void ); /*X*/ +int rtp_start_fwd (osip_call_id_t *callid, char *client_id, /*X*/ + int direction, int media_stream_no, + struct in_addr outbound_ipaddr, int *outboundport, + struct in_addr lcl_client_ipaddr, int lcl_clientport); +int rtp_stop_fwd (osip_call_id_t *callid, int direction); /*X*/ +void rtpproxy_kill( void ); /*X*/ + +/* accessctl.c */ +int accesslist_check(struct sockaddr_in from); + +/* security.c */ +int security_check_raw(char *sip_buffer, int size); /*X*/ +int security_check_sip(sip_ticket_t *ticket); /*X*/ + +/* auth.c */ +int authenticate_proxy(sip_ticket_t *ticket); /*X*/ +int auth_include_authrq(sip_ticket_t *ticket); /*X*/ +void CvtHex(char *hash, char *hashstring); + +/* fwapi.c */ +int fwapi_start_rtp(int rtp_direction, + struct in_addr local_ipaddr, int local_port, + struct in_addr remote_ipaddr, int remote_port); +int fwapi_stop_rtp(int rtp_direction, + struct in_addr local_ipaddr, int local_port, + struct in_addr remote_ipaddr, int remote_port); /* * some constant definitions diff --git a/src/sock.c b/src/sock.c index 32ca255..f48bdfe 100644 --- a/src/sock.c +++ b/src/sock.c @@ -107,16 +107,18 @@ int sipsock_wait(void) { * from is modified to return the sockaddr_in of the sender */ int sipsock_read(void *buf, size_t bufsize, - struct sockaddr_in *from) { + struct sockaddr_in *from, int *protocol) { int count; socklen_t fromlen; fromlen=sizeof(struct sockaddr_in); + *protocol = PROTO_UDP; /* up to now, unly UDP */ count=recvfrom(sip_udp_socket, buf, bufsize, 0, (struct sockaddr *)from, &fromlen); if (count<0) { WARN("recvfrom() returned error [%s]",strerror(errno)); + *protocol = PROTO_UNKN; } DEBUGC(DBCLASS_NET,"received UDP packet from %s, count=%i", @@ -134,7 +136,7 @@ int sipsock_read(void *buf, size_t bufsize, * STS_SUCCESS on success * STS_FAILURE on error */ -int sipsock_send(struct in_addr addr, int port, +int sipsock_send(struct in_addr addr, int port, int protocol, char *buffer, int size) { struct sockaddr_in dst_addr; int sts; @@ -150,6 +152,11 @@ int sipsock_send(struct in_addr addr, int port, return STS_FAILURE; } + if (protocol != PROTO_UDP) { + ERROR("sipsock_send: only UDP supported by now"); + return STS_FAILURE; + } + dst_addr.sin_family = AF_INET; memcpy(&dst_addr.sin_addr.s_addr, &addr, sizeof(struct in_addr)); dst_addr.sin_port= htons(port);