/* * 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; }
/* * 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; }