- new doc/RFC3261_compliance.txt and comments in the

code that refer to the RFC.
This commit is contained in:
Thomas Ries
2004-01-29 20:11:12 +00:00
parent 8af5baeddc
commit ba2b99a635
5 changed files with 228 additions and 47 deletions
+2
View File
@@ -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
+59
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;