/* * SIP_GEN_RESPONSE * * send an proxy generated response back to the client. * Only errors are reported from the proxy itself. * code = SIP result code to deliver * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error */ int sip_gen_response(sip_ticket_t *ticket, int code) { osip_message_t *response; int sts; osip_via_t *via; int port; char *buffer; size_t buflen; struct in_addr addr; /* create the response template */ if ((response=msg_make_template_reply(ticket, code))==NULL) { ERROR("sip_gen_response: error in msg_make_template_reply"); return STS_FAILURE; } /* we must check if first via has x.x.x.x address. If not, we must resolve it */ osip_message_get_via (response, 0, &via); if (via == NULL) { ERROR("sip_gen_response: Cannot send response - no via field"); return STS_FAILURE; } /* name resolution */ if (utils_inet_aton(via->host, &addr) == 0) { /* need name resolution */ DEBUGC(DBCLASS_DNS,"resolving name:%s",via->host); sts = get_ip_by_host(via->host, &addr); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_PROXY, "sip_gen_response: cannot resolve via [%s]", via->host); return STS_FAILURE; } } sts = sip_message_to_str(response, &buffer, &buflen); if (sts != 0) { ERROR("sip_gen_response: msg_2char failed"); return STS_FAILURE; } if (via->port) { port=atoi(via->port); } else { port=SIP_PORT; } /* send to destination */ sipsock_send(addr, port, ticket->protocol, buffer, buflen); /* free the resources */ osip_message_free(response); osip_free(buffer); return STS_SUCCESS; }
/* * check if a given request is addressed to local. I.e. it is addressed * to the proxy itself (IP of my inbound or outbound interface, same port) * * RETURNS * STS_TRUE if the request is addressed local * STS_FALSE otherwise */ int is_sipuri_local (sip_ticket_t *ticket) { osip_message_t *sip=ticket->sipmsg; int found; struct in_addr addr_uri, addr_myself; int port; int i; if (sip==NULL) { ERROR("called is_sipuri_local with NULL sip"); return STS_FALSE; } if (!sip || !sip->req_uri) { ERROR("is_sipuri_local: no request URI present"); return STS_FALSE; } DEBUGC(DBCLASS_DNS,"check for local SIP URI %s:%s", sip->req_uri->host? sip->req_uri->host : "*NULL*", sip->req_uri->port? sip->req_uri->port : "*NULL*"); if (utils_inet_aton(sip->req_uri->host, &addr_uri) == 0) { /* need name resolution */ get_ip_by_host(sip->req_uri->host, &addr_uri); } found=0; for (i=0; i<2; i++) { /* * search my in/outbound interfaces */ DEBUGC(DBCLASS_BABBLE,"resolving IP of interface %s", (i==IF_INBOUND)? "inbound":"outbound"); if (get_interface_ip(i, &addr_myself) != STS_SUCCESS) { continue; } /* check the extracted HOST against my own host addresses */ if (sip->req_uri->port) { port=atoi(sip->req_uri->port); } else { port=SIP_PORT; } if ( (memcmp(&addr_myself, &addr_uri, sizeof(addr_myself))==0) && (port == configuration.sip_listen_port) ) { DEBUG("address match [%s]", utils_inet_ntoa(addr_uri)); found=1; break; } } DEBUGC(DBCLASS_DNS, "SIP URI is %slocal", found? "":"not "); return (found)? STS_TRUE : STS_FALSE; }
/* * check if a given osip_via_t is local. I.e. its address is owned * by my inbound or outbound interface * * RETURNS * STS_TRUE if the given VIA is one of my interfaces * STS_FALSE otherwise */ int is_via_local (osip_via_t *via) { int sts, found; struct in_addr addr_via, addr_myself; int port; int i; if (via==NULL) { ERROR("called is_via_local with NULL via"); return STS_FALSE; } DEBUGC(DBCLASS_BABBLE,"via name %s",via->host); if (utils_inet_aton(via->host,&addr_via) == 0) { /* need name resolution */ sts=get_ip_by_host(via->host, &addr_via); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_DNS, "is_via_local: cannot resolve VIA [%s]", via->host); return STS_FAILURE; } } found=0; for (i=0; i<2; i++) { /* * search my in/outbound interfaces */ DEBUGC(DBCLASS_BABBLE,"resolving IP of interface %s", (i==IF_INBOUND)? "inbound":"outbound"); if (get_interface_ip(i, &addr_myself) != STS_SUCCESS) { continue; } /* check the extracted VIA against my own host addresses */ if (via->port) port=atoi(via->port); else port=SIP_PORT; if ( (memcmp(&addr_myself, &addr_via, sizeof(addr_myself))==0) && (port == configuration.sip_listen_port) ) { DEBUG("got address match [%s]", utils_inet_ntoa(addr_via)); found=1; break; } } return (found)? STS_TRUE : STS_FALSE; }
static int stun_send_request(char *tid){ struct in_addr addr; int sts; char stun_rq[28]; /*&&& testing */ size_t size=28; /* name resolution */ if (utils_inet_aton(plugin_cfg.server, &addr) == 0) { /* need name resolution */ DEBUGC(DBCLASS_DNS,"resolving name:%s", plugin_cfg.server); sts = get_ip_by_host(plugin_cfg.server, &addr); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_DNS, "stun_send_request: cannot resolve STUN server [%s]", plugin_cfg.server); return STS_FAILURE; } } /* compose STUN BIND request - poor mans way */ stun_rq[0]=0x00; // type stun_rq[1]=0x01; stun_rq[2]=0x00; // length stun_rq[3]=0x08; memcpy (&stun_rq[4], tid, STUN_TID_SIZE); stun_rq[20]=0x00; // ATTR change request stun_rq[21]=0x03; stun_rq[22]=0x00; // ATTR len 4 stun_rq[23]=0x04; stun_rq[24]=0x00; // Change IP not set, Change port not set stun_rq[25]=0x00; stun_rq[26]=0x00; stun_rq[27]=0x00; /* and send via the SIP UDP port */ sts = sipsock_send(addr, plugin_cfg.port, PROTO_UDP, stun_rq, size); return STS_SUCCESS; }
/* * send answer to a registration request. * flag = STS_SUCCESS -> positive answer (200) * flag = STS_FAILURE -> negative answer (503) * flag = STS_NEED_AUTH -> proxy authentication needed (407) * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error */ int register_response(sip_ticket_t *ticket, int flag) { osip_message_t *response; int code; int sts; osip_via_t *via; int port; char *buffer; size_t buflen; struct in_addr addr; osip_header_t *expires_hdr; /* ok -> 200, fail -> 503 */ switch (flag) { case STS_SUCCESS: code = 200; /* OK */ break; case STS_FAILURE: code = 503; /* failed */ break; case STS_NEED_AUTH: code = 407; /* proxy authentication needed */ break; default: code = 503; /* failed */ break; } /* create the response template */ 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(ticket->sipmsg, 0, &expires_hdr); if (expires_hdr) { osip_message_set_expires(response, expires_hdr->hvalue); } /* if we send back an proxy authentication needed, include the Proxy-Authenticate field */ if (code == 407) { auth_include_authrq(response); } /* get the IP address from existing VIA header */ osip_message_get_via (response, 0, &via); if (via == NULL) { ERROR("register_response: Cannot send response - no via field"); return STS_FAILURE; } /* name resolution needed? */ if (utils_inet_aton(via->host,&addr) == 0) { /* yes, get IP address */ sts = get_ip_by_host(via->host, &addr); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_REG, "register_response: cannot resolve VIA [%s]", via->host); return STS_FAILURE; } } sts = sip_message_to_str(response, &buffer, &buflen); if (sts != 0) { ERROR("register_response: msg_2char failed"); return STS_FAILURE; } /* send answer back */ if (via->port) { port=atoi(via->port); if ((port<=0) || (port>65535)) port=SIP_PORT; } else { port=configuration.sip_listen_port; } sipsock_send(addr, port, ticket->protocol, buffer, buflen); /* free the resources */ osip_message_free(response); free(buffer); return STS_SUCCESS; }
/* * check if a given request is addressed to local. I.e. it is addressed * to the proxy itself (IP of my inbound or outbound interface, same port) * * RETURNS * STS_TRUE if the request is addressed local * STS_FALSE otherwise */ int is_sipuri_local (sip_ticket_t *ticket) { osip_message_t *sip=ticket->sipmsg; int found; struct in_addr addr_uri, addr_myself; char *my_interfaces[]= { configuration.inbound_if, configuration.outbound_if, (char*)-1 }; int port; int i; char *ptr; if (sip==NULL) { ERROR("called is_sipuri_local with NULL sip"); return STS_FALSE; } if (!sip || !sip->req_uri) { ERROR("is_sipuri_local: no request URI present"); return STS_FALSE; } DEBUGC(DBCLASS_DNS,"check for local SIP URI %s:%s", sip->req_uri->host? sip->req_uri->host : "*NULL*", sip->req_uri->port? sip->req_uri->port : "*NULL*"); if (utils_inet_aton(sip->req_uri->host, &addr_uri) == 0) { /* need name resolution */ get_ip_by_host(sip->req_uri->host, &addr_uri); } found=0; for (i=0; ; i++) { /* * try to search by interface name first */ ptr=my_interfaces[i]; if (ptr==(char*)-1) break; /* end of list mark */ if (ptr) { DEBUGC(DBCLASS_BABBLE,"resolving IP of interface %s",ptr); if (get_ip_by_ifname(ptr, &addr_myself) != STS_SUCCESS) { ERROR("can't find interface %s - configuration error?", ptr); continue; } } /* check the extracted HOST against my own host addresses */ if (sip->req_uri->port) { port=atoi(sip->req_uri->port); } else { port=SIP_PORT; } if ( (memcmp(&addr_myself, &addr_uri, sizeof(addr_myself))==0) && (port == configuration.sip_listen_port) ) { DEBUG("address match [%s]", utils_inet_ntoa(addr_uri)); found=1; break; } } DEBUGC(DBCLASS_DNS, "SIP URI is %slocal", found? "":"not "); return (found)? STS_TRUE : STS_FALSE; }
/* * check if a given osip_via_t is local. I.e. its address is owned * by my inbound or outbound interface * * RETURNS * STS_TRUE if the given VIA is one of my interfaces * STS_FALSE otherwise */ int is_via_local (osip_via_t *via, struct in_addr *local_ip) { int sts, found; struct in_addr addr_via, addr_myself; char *my_interfaces[]= { configuration.inbound_if, configuration.outbound_if, (char*)-1 }; int port; int i; char *ptr; if (via==NULL) { ERROR("called is_via_local with NULL via"); return STS_FALSE; } DEBUGC(DBCLASS_BABBLE,"via name %s",via->host); if (utils_inet_aton(via->host,&addr_via) == 0) { /* need name resolution */ sts=get_ip_by_host(via->host, &addr_via); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_DNS, "is_via_local: cannot resolve VIA [%s]", via->host); return STS_FAILURE; } } /* check the extracted VIA against my own host addresses */ if (via->port) port=atoi(via->port); else port=SIP_PORT; /* Check local_ip if defined */ if (local_ip) { if ( (memcmp(&addr_via, local_ip, sizeof(addr_via))==0) && (port == configuration.sip_listen_port) ) { DEBUGC(DBCLASS_BABBLE,"via is local due to local_ip"); return STS_TRUE; } } found=0; for (i=0; ; i++) { /* * try to search by interface name first */ ptr=my_interfaces[i]; if (ptr==(char*)-1) break; /* end of list mark */ if (ptr) { DEBUGC(DBCLASS_BABBLE,"resolving IP of interface %s",ptr); if (get_ip_by_ifname(ptr, &addr_myself) != STS_SUCCESS) { ERROR("can't find interface %s - configuration error?", ptr); continue; } } if ( (memcmp(&addr_myself, &addr_via, sizeof(addr_myself))==0) && (port == configuration.sip_listen_port) ) { DEBUG("got address match [%s]", utils_inet_ntoa(addr_via)); found=1; break; } } return (found)? STS_TRUE : STS_FALSE; }