📄 proxy.c
字号:
default: DEBUGC(DBCLASS_PROXY, "request [%s] from/to unregistered UA " "(RQ: %s@%s -> %s@%s)", request->sip_method? request->sip_method:"*NULL*", request->from->url->username? request->from->url->username:"*NULL*", request->from->url->host? request->from->url->host : "*NULL*", url->username? url->username : "*NULL*", url->host? url->host : "*NULL*");/* * we may end up here for two reasons: * 1) An incomming request (from outbound) that is directed to * an unknown (not registered) local UA * 2) an outgoing request from a local UA that is not registered. * * Case 1) we should probably answer with "404 Not Found", * case 2) more likely a "403 Forbidden" * * How about "408 Request Timeout" ? * */ sip_gen_response(request, 408 /* Request Timeout */); return STS_FAILURE; } /* * RFC 3261, Section 16.6 step 3 * Proxy Behavior - Request Forwarding - Max-Forwards * (if Max-Forwards header exists, decrement by one, if it does not * exist, add a new one with value SHOULD be 70) */ { osip_header_t *max_forwards; int forwards_count = DEFAULT_MAXFWD; char mfwd[8]; osip_message_get_max_forwards(request, 0, &max_forwards); if (max_forwards == NULL) { sprintf(mfwd, "%i", forwards_count); osip_message_set_max_forwards(request, mfwd); } else { if (max_forwards->hvalue) { forwards_count = atoi(max_forwards->hvalue); forwards_count -=1; osip_free (max_forwards->hvalue); } sprintf(mfwd, "%i", forwards_count); max_forwards->hvalue = osip_strdup(mfwd); } DEBUGC(DBCLASS_PROXY,"setting Max-Forwards=%s",mfwd); } /* * RFC 3261, Section 16.6 step 4 * Proxy Behavior - Request Forwarding - Add a Record-route header */#if 0/* NOT IMPLEMENTED - this requires proper implementation of the Route headers first. */ { struct in_addr addr; osip_record_route_t *r_route; osip_uri_t *uri_of_proxy; /* * get the IP address of the interface where I'm going to * send out this request */ switch (type) { case REQTYP_INCOMING: sts = get_ip_by_ifname(configuration.inbound_if, &addr); if (sts == STS_FAILURE) { ERROR("can't find inbound interface %s - configuration error?", configuration.outbound_if); return STS_FAILURE; } break; case REQTYP_OUTGOING: sts = get_ip_by_ifname(configuration.outbound_if, &addr); if (sts == STS_FAILURE) { ERROR("can't find outbound interface %s - configuration error?", configuration.outbound_if); return STS_FAILURE; } break; default: ERROR("Oops, never should end up here (type=%i)", type); return STS_FAILURE; } sts = osip_record_route_init(&r_route); if (sts == 0) { sts = osip_uri_init(&uri_of_proxy); if (sts == 0) { char tmp[8]; /* host name / IP */ osip_uri_set_host(uri_of_proxy, osip_strdup(utils_inet_ntoa(addr))); /* port number */ sprintf(tmp, "%i", configuration.sip_listen_port); osip_uri_set_port(uri_of_proxy, osip_strdup(tmp)); /* 'lr' parameter */ osip_uri_uparam_add(uri_of_proxy, "lr", NULL); osip_record_route_set_url(r_route, uri_of_proxy); /* insert before all other record-route */ osip_list_add (request->record_routes, r_route, 0); } else { osip_record_route_free (r_route); osip_free (r_route); } /* if url_init */ } /* if record route init */ }#endif /* * RFC 3261, Section 16.6 step 5 * Proxy Behavior - Request Forwarding - Add Additional Header Fields */ /* NOT IMPLEMENTED (optional) */ /* * RFC 3261, Section 16.6 step 6 * Proxy Behavior - Request Forwarding - Postprocess routing information */ /* * RFC 3261, Section 16.6 step 7 * Proxy Behavior - Determine Next-Hop Address */ if ((type == REQTYP_OUTGOING) && (configuration.outbound_proxy_host)) { /* I have an outbound proxy configured */ sts = get_ip_by_host(configuration.outbound_proxy_host, &sendto_addr); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_PROXY, "proxy_request: cannot resolve outbound " " proxy host [%s]", configuration.outbound_proxy_host); return STS_FAILURE; } if (configuration.outbound_proxy_port) { port=configuration.outbound_proxy_port; } else { port = SIP_PORT; } } else { /* get the destination from the SIP URI */ sts = get_ip_by_host(url->host, &sendto_addr); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_PROXY, "proxy_request: cannot resolve URI [%s]", url->host); return STS_FAILURE; } if (url->port) { port=atoi(url->port); } else { port=SIP_PORT; } } /* * RFC 3261, Section 16.6 step 8 * Proxy Behavior - Add a Via header field value */ /* add my Via header line (outbound interface)*/ if (type == REQTYP_INCOMING) { sts = sip_add_myvia(request, IF_INBOUND); if (sts == STS_FAILURE) { ERROR("adding my inbound via failed!"); } } else { sts = sip_add_myvia(request, IF_OUTBOUND); if (sts == STS_FAILURE) { ERROR("adding my outbound via failed!"); return STS_FAILURE; } } /* * RFC 3261, Section 16.6 step 9 * Proxy Behavior - Add a Content-Length header field if necessary */ /* not necessary, already in message and we do not support TCP */ /* * RFC 3261, Section 16.6 step 10 * Proxy Behavior - Forward the new request */ sts = osip_message_to_str(request, &buffer); if (sts != 0) { ERROR("proxy_request: osip_message_to_str failed"); return STS_FAILURE; } sipsock_send_udp(&sip_socket, sendto_addr, port, buffer, strlen(buffer), 1); osip_free (buffer); /* * RFC 3261, Section 16.6 step 11 * Proxy Behavior - Set timer C */ /* NOT IMPLEMENTED - does this really apply for stateless proxies? */ return STS_SUCCESS;}/* * PROXY_RESPONSE * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error */int proxy_response (osip_message_t *response, struct sockaddr_in *from) { int i; int sts; int type; struct in_addr sendto_addr; osip_via_t *via; int port; char *buffer;#define RESTYP_INCOMING 1#define RESTYP_OUTGOING 2 DEBUGC(DBCLASS_PROXY,"proxy_response"); /* * RFC 3261, Section 16.11 * Proxy Behavior - Remove my Via header field value */ /* remove my Via header line */ sts = sip_del_myvia(response); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_PROXY,"not addressed to my VIA, ignoring response"); return STS_FAILURE; } /* * figure out if this is an request coming from the outside * world to one of our registered clients */ /* Ahhrghh...... a response seems to have NO contact information... * so let's take FROM instead... * the TO and FROM headers are EQUAL to the request - that means * they are swapped in their meaning for a response... */#if _OLD_DIRECTION_EVALUATION type = 0; for (i=0; i<URLMAP_SIZE; i++) { if (urlmap[i].active == 0) continue; /* incoming response ('from' == 'masq') || ('from' == 'reg') */ if ((compare_url(response->from->url, urlmap[i].reg_url)==STS_SUCCESS) || (compare_url(response->from->url, urlmap[i].masq_url)==STS_SUCCESS)) { type=RESTYP_INCOMING; DEBUGC(DBCLASS_PROXY,"incoming response for %s@%s from outbound", response->from->url->username? response->from->url->username:"*NULL*", response->from->url->host? response->from->url->host : "*NULL*"); break; } /* outgoing response ('to' == 'reg') || ('to' == 'masq' ) */ if ((compare_url(response->to->url, urlmap[i].masq_url)==STS_SUCCESS) || (compare_url(response->to->url, urlmap[i].reg_url)==STS_SUCCESS)){ type=RESTYP_OUTGOING; DEBUGC(DBCLASS_PROXY,"outgoing response for %s@%s from inbound", response->from->url->username ? response->from->url->username : "*NULL*", response->from->url->host ? response->from->url->host : "*NULL*"); break; } }#else type = 0; /* * did I receive the telegram from a REGISTERED host? * -> it must be an OUTGOING response */ for (i=0; i<URLMAP_SIZE; i++) { struct in_addr tmp_addr; if (urlmap[i].active == 0) continue; if (get_ip_by_host(urlmap[i].true_url->host, &tmp_addr) == STS_FAILURE) { DEBUGC(DBCLASS_PROXY, "proxy_request: cannot resolve host [%s]", urlmap[i].true_url); } else { DEBUGC(DBCLASS_PROXY, "proxy_request: reghost:%s ip:%s", urlmap[i].true_url->host, utils_inet_ntoa(from->sin_addr)); if (memcmp(&tmp_addr, &from->sin_addr, sizeof(tmp_addr)) == 0) { type=RESTYP_OUTGOING; break; } } } /* * is the telegram directed to an internal registered host? * -> it must be an INCOMING response */ if (type == 0) for (i=0; i<URLMAP_SIZE; i++) { if (urlmap[i].active == 0) continue; /* incoming response ('from' == 'masq') || ('from' == 'reg') */ if ((compare_url(response->from->url, urlmap[i].reg_url)==STS_SUCCESS) || (compare_url(response->from->url, urlmap[i].masq_url)==STS_SUCCESS)) { type=RESTYP_INCOMING; break; } }#endif/* * ok, we got a response that we are allowed to process. */ switch (type) { /* * from an external host to the internal masqueraded host */ case RESTYP_INCOMING: DEBUGC(DBCLASS_PROXY,"incoming response for %s@%s from outbound", response->from->url->username? response->from->url->username:"*NULL*", response->from->url->host? response->from->url->host : "*NULL*"); if ((MSG_IS_RESPONSE_FOR(response,"INVITE")) && ((MSG_TEST_CODE(response, 200)) || (MSG_TEST_CODE(response, 183)))) { /* This is an incoming response, therefore we need an incoming stream */ if (configuration.rtp_proxy_enable == 1) { sts = proxy_rewrite_invitation_body(response, DIR_INCOMING); } } if (MSG_IS_RESPONSE_FOR(response,"REGISTER")) { /* * REGISTER returns *my* Contact header information. * Rewrite Contact header back to represent the true address.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -