- new doc/RFC3261_compliance.txt and comments in the
code that refer to the RFC.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
0.5.2
|
||||
=====
|
||||
29-Jan-2004: - new doc/RFC3261_compliance.txt and comments in the
|
||||
code that refer to the RFC.
|
||||
28-Jan-2004: - don't die on INVITE requests that include no Contact
|
||||
header - which is legal. (patch by Robert Högberg)
|
||||
- RTP proxy: don't try to forward empty RTP packets
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
RFC3261 describes in detail for UAs and proxies how to behave.
|
||||
This document tries to make the link between the RFC and the
|
||||
code locations in siproxd where these actions are performed.
|
||||
|
||||
|
||||
|
||||
Request Processing: implemented
|
||||
===================
|
||||
Section 16.3: Request Validation
|
||||
1. Reasonable Syntax yes
|
||||
2. URI scheme no
|
||||
3. Max-Forwards no
|
||||
4. (Optional) Loop Detection partially
|
||||
5. Proxy-Require no
|
||||
6. Proxy-Authorization yes
|
||||
|
||||
Section 16.4 Route Information Preprocessing yes
|
||||
|
||||
Section 16.5 Determining Request Targets no
|
||||
|
||||
Section 16.6 Request Forwarding
|
||||
1. Make a copy of the received request yes
|
||||
2. Update the Request-URI yes
|
||||
3. Update the Max-Forwards header field no
|
||||
4. Optionally add a Record-route header field value no
|
||||
5. Optionally add additional header fields no
|
||||
6. Postprocess routing information no
|
||||
7. Determine the next-hop address, port, and transport yes
|
||||
8. Add a Via header field value yes
|
||||
9. Add a Content-Length header field if necessary yes
|
||||
10. Forward the new request yes
|
||||
11. Set timer C no
|
||||
|
||||
Response Processing: implemented
|
||||
====================
|
||||
Section 16.3: Request Validation
|
||||
1. Reasonable Syntax yes
|
||||
2. URI scheme no
|
||||
3. Max-Forwards no
|
||||
4. (Optional) Loop Detection partially
|
||||
5. Proxy-Require no
|
||||
6. Proxy-Authorization yes
|
||||
|
||||
Section 16.7 Response Processing n/a
|
||||
|
||||
Section 16.11 Stateless Proxy partially
|
||||
Response processing as described in Section 16.7 does
|
||||
not apply to a proxy behaving statelessly. When a
|
||||
response arrives at a stateless proxy, the proxy MUST
|
||||
inspect the sent-by value in the first (topmost) Via
|
||||
header field value. If that address matches the proxy,
|
||||
(it equals a value this proxy has inserted into previous
|
||||
requests) the proxy MUST remove that header field value
|
||||
from the response and forward the result to the location
|
||||
indicated in the next Via header field value. The proxy
|
||||
MUST NOT add to, modify, or remove the message body.
|
||||
Unless specified otherwise, the proxy MUST NOT remove any
|
||||
other header field values. If the address does not match
|
||||
the proxy, the message MUST be silently discarded.
|
||||
+113
-37
@@ -54,6 +54,28 @@ extern int sip_socket; /* sending SIP datagrams */
|
||||
* RETURNS
|
||||
* STS_SUCCESS on success
|
||||
* STS_FAILURE on error
|
||||
*
|
||||
* RFC3261
|
||||
* Section 16.3: Proxy Behavior - Request Validation
|
||||
* 1. Reasonable Syntax
|
||||
* 2. URI scheme
|
||||
* 3. Max-Forwards
|
||||
* 4. (Optional) Loop Detection
|
||||
* 5. Proxy-Require
|
||||
* 6. Proxy-Authorization
|
||||
*
|
||||
* Section 16.6: Proxy Behavior - Request Forwarding
|
||||
* 1. Make a copy of the received request
|
||||
* 2. Update the Request-URI
|
||||
* 3. Update the Max-Forwards header field
|
||||
* 4. Optionally add a Record-route header field value
|
||||
* 5. Optionally add additional header fields
|
||||
* 6. Postprocess routing information
|
||||
* 7. Determine the next-hop address, port, and transport
|
||||
* 8. Add a Via header field value
|
||||
* 9. Add a Content-Length header field if necessary
|
||||
* 10. Forward the new request
|
||||
* 11. Set timer C
|
||||
*/
|
||||
int proxy_request (osip_message_t *request) {
|
||||
int i;
|
||||
@@ -69,18 +91,47 @@ int proxy_request (osip_message_t *request) {
|
||||
|
||||
DEBUGC(DBCLASS_PROXY,"proxy_request");
|
||||
|
||||
/* check for VIA loop, if yes, discard the request */
|
||||
sts=check_vialoop(request);
|
||||
if (sts == STS_TRUE) {
|
||||
DEBUGC(DBCLASS_PROXY,"via loop detected, ignoring request");
|
||||
/* according to the SIP RFC we are supposed to return an 482 error */
|
||||
return STS_FAILURE;
|
||||
}
|
||||
/*
|
||||
* RFC 3261, Section 16.6 step 1
|
||||
* Proxy Behavior - Request Forwarding - Make a copy
|
||||
*/
|
||||
/* nothing to do here, copy is ready in 'request'*/
|
||||
|
||||
/*
|
||||
* RFC 3261, Section 16.6 step 3
|
||||
* Proxy Behavior - Request Forwarding - Max-Forwards
|
||||
* (if Max-Forward header exists, decrement by one, if it does not
|
||||
* exist, add a new one with value SHOULD be 70)
|
||||
*/
|
||||
/* NOT IMPLEMENTED */
|
||||
|
||||
/*
|
||||
* RFC 3261, Section 16.6 step 4
|
||||
* Proxy Behavior - Request Forwarding - Add a Record-route header
|
||||
*/
|
||||
/* NOT IMPLEMENTED (optional) */
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
/* NOT IMPLEMENTED */
|
||||
|
||||
|
||||
/*
|
||||
* RFC 3261, Section 16.4
|
||||
* Proxy Behavior - Route Information Preprocessing
|
||||
* (process Record-Route header)
|
||||
*/
|
||||
/*
|
||||
* Check if I am listed at the topmost Route header (if any Route
|
||||
* header is existing at all). If so, remove it from the list.
|
||||
* -> RFC3261 Section 16.4
|
||||
*/
|
||||
if (request->routes && !osip_list_eol(request->routes, 0)) {
|
||||
struct in_addr addr1, addr2, addr3;
|
||||
@@ -216,19 +267,20 @@ int proxy_request (osip_message_t *request) {
|
||||
* from an external host to the internal masqueraded host
|
||||
*/
|
||||
case REQTYP_INCOMING:
|
||||
sts = get_ip_by_host(urlmap[i].true_url->host, &sendto_addr);
|
||||
if (sts == STS_FAILURE) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_request: cannot resolve URI [%s]",
|
||||
urlmap[i].true_url->host);
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
/* rewrite request URI to point to the real host */
|
||||
/*
|
||||
* RFC 3261, Section 16.6 step 2
|
||||
* Proxy Behavior - Request Forwarding - Request-URI
|
||||
* (rewrite request URI to point to the real host)
|
||||
*/
|
||||
/* 'i' still holds the valid index into the URLMAP table */
|
||||
if (check_rewrite_rq_uri(request)==STS_TRUE) {
|
||||
proxy_rewrite_request_uri(request, i);
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 3261, Section 16.6 step 8
|
||||
* Proxy Behavior - Add a Via header field value
|
||||
*/
|
||||
/* add my Via header line (inbound interface)*/
|
||||
sts = sip_add_myvia(request, IF_INBOUND);
|
||||
if (sts == STS_FAILURE) {
|
||||
@@ -259,12 +311,12 @@ int proxy_request (osip_message_t *request) {
|
||||
* from the internal masqueraded host to an external host
|
||||
*/
|
||||
case REQTYP_OUTGOING:
|
||||
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;
|
||||
}
|
||||
/*
|
||||
* RFC 3261, Section 16.6 step 2
|
||||
* Proxy Behavior - Request Forwarding - Request-URI
|
||||
*/
|
||||
/* nothing to do for an outgoing request */
|
||||
|
||||
|
||||
/* if it is addressed to myself, then it must be some request
|
||||
* method that I as a proxy do not support. Reject */
|
||||
@@ -289,6 +341,10 @@ int proxy_request (osip_message_t *request) {
|
||||
/* rewrite Contact header to represent the masqued address */
|
||||
sip_rewrite_contact(request, DIR_OUTGOING);
|
||||
|
||||
/*
|
||||
* RFC 3261, Section 16.8
|
||||
* Proxy Behavior - Add a Via header field value
|
||||
*/
|
||||
/* add my Via header line (outbound interface)*/
|
||||
sts = sip_add_myvia(request, IF_OUTBOUND);
|
||||
if (sts == STS_FAILURE) {
|
||||
@@ -329,10 +385,12 @@ int proxy_request (osip_message_t *request) {
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* check if we need to send to an outbound proxy
|
||||
*/
|
||||
/*
|
||||
* 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 "
|
||||
@@ -346,7 +404,14 @@ int proxy_request (osip_message_t *request) {
|
||||
port = 5060;
|
||||
}
|
||||
} else {
|
||||
/* the host part already has been resolved above*/
|
||||
/* 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 {
|
||||
@@ -354,6 +419,16 @@ int proxy_request (osip_message_t *request) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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");
|
||||
@@ -362,6 +437,13 @@ int proxy_request (osip_message_t *request) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -387,16 +469,11 @@ int proxy_response (osip_message_t *response) {
|
||||
|
||||
DEBUGC(DBCLASS_PROXY,"proxy_response");
|
||||
|
||||
|
||||
/* check for VIA loop, if yes, discard the request */
|
||||
sts=check_vialoop(response);
|
||||
if (sts == STS_TRUE) {
|
||||
DEBUGC(DBCLASS_PROXY,"via loop detected, ignoring response");
|
||||
/* according to the SIP RFC we are supposed to return an 482 error */
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
/* ALWAYS: remove my Via header line */
|
||||
/*
|
||||
* 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");
|
||||
@@ -408,7 +485,6 @@ int proxy_response (osip_message_t *response) {
|
||||
* 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
|
||||
|
||||
+5
-2
@@ -174,10 +174,13 @@ int register_client(osip_message_t *my_msg, int force_lcl_masq) {
|
||||
osip_header_t *expires_hdr;
|
||||
osip_uri_param_t *expires_param=NULL;
|
||||
|
||||
/* check for proxy authentication */
|
||||
/*
|
||||
* RFC 3261, Section 16.3 step 6
|
||||
* Proxy Behavior - Request Validation - Proxy-Authorization
|
||||
*/
|
||||
sts = authenticate_proxy(my_msg);
|
||||
if (sts == STS_FAILURE) {
|
||||
/* failed */
|
||||
/* failed */
|
||||
WARN("proxy authentication failed for %s@%s",
|
||||
(my_msg->to->url->username)? my_msg->to->url->username : "*NULL*",
|
||||
my_msg->to->url->host);
|
||||
|
||||
+49
-8
@@ -256,15 +256,19 @@ int main (int argc, char *argv[])
|
||||
sts=security_check_raw(buff, i);
|
||||
if (sts != STS_SUCCESS) continue; /* there are no resources to free */
|
||||
|
||||
/* parse the received message */
|
||||
/* init sip_msg */
|
||||
sts=osip_message_init(&my_msg);
|
||||
my_msg->message=NULL;
|
||||
|
||||
if (sts != 0) {
|
||||
ERROR("osip_message_init() failed... this is not good");
|
||||
continue; /* skip, there are no resources to free */
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 3261, Section 16.3 step 1
|
||||
* Proxy Behavior - Request Validation - Reasonable Syntax
|
||||
* (parse the received message)
|
||||
*/
|
||||
sts=osip_message_parse(my_msg, buff);
|
||||
if (sts != 0) {
|
||||
ERROR("osip_message_parse() failed... this is not good");
|
||||
@@ -280,19 +284,56 @@ int main (int argc, char *argv[])
|
||||
goto end_loop; /* skip and free resources */
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 3261, Section 16.3 step 2
|
||||
* Proxy Behavior - Request Validation - URI scheme
|
||||
* (check request URI and refuse with 416 if not understood)
|
||||
*/
|
||||
/* NOT IMPLEMENTED */
|
||||
|
||||
/*
|
||||
* RFC 3261, Section 16.3 step 3
|
||||
* Proxy Behavior - Request Validation - Max-Forwards check
|
||||
* (check Max-Forward header and refuse with 483 if too many hops)
|
||||
*/
|
||||
/* NOT IMPLEMENTED */
|
||||
|
||||
/*
|
||||
* RFC 3261, Section 16.3 step 4
|
||||
* 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) {
|
||||
DEBUGC(DBCLASS_PROXY,"via loop detected, ignoring request");
|
||||
/* we should return 482, NOT IMPLEMENTED */
|
||||
goto end_loop; /* skip and free resources */
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 3261, Section 16.3 step 5
|
||||
* Proxy Behavior - Request Validation - Proxy-Require check
|
||||
* (check Proxy-Require header and return 420 if unsupported option)
|
||||
*/
|
||||
/* NOT IMPLEMENTED */
|
||||
|
||||
/*
|
||||
* RFC 3261, Section 16.5
|
||||
* Proxy Behavior - Determining Request Targets
|
||||
*/
|
||||
/* 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")));
|
||||
|
||||
|
||||
/*
|
||||
* if an REQ REGISTER, check if it is directed to myself,
|
||||
* or am I just the outbound proxy but no registrar.
|
||||
* - If I'm the registrar, register & generate answer
|
||||
* - If I'm just the outbound proxy, register, rewrite & forward
|
||||
*/
|
||||
* if an REQ REGISTER, check if it is directed to myself,
|
||||
* or am I just the outbound proxy but no registrar.
|
||||
* - 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 (access & ACCESSCTL_REG) {
|
||||
osip_uri_t *url;
|
||||
|
||||
Reference in New Issue
Block a user