Module: sip-router
Branch: pd/outbound
Commit: aabb7adb933185f4bc12dcd82cdee357246c8c2f
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=aabb7ad…
Author: Peter Dunkley <peter.dunkley(a)crocodile-rcs.com>
Committer: Peter Dunkley <peter.dunkley(a)crocodile-rcs.com>
Date: Wed Feb 27 15:29:35 2013 +0000
modules/registrar: add Require: outbound to 200 OK when required by client and supported
by server
- Reported by @oej
---
modules/registrar/reply.c | 28 ++++++++++++++++++++++++----
modules/registrar/rerrno.h | 3 ++-
modules/registrar/save.c | 15 +++++++++++++--
3 files changed, 39 insertions(+), 7 deletions(-)
diff --git a/modules/registrar/reply.c b/modules/registrar/reply.c
index 97c8274..4b05aa7 100644
--- a/modules/registrar/reply.c
+++ b/modules/registrar/reply.c
@@ -39,6 +39,7 @@
#include "../../ut.h"
#include "../../xavp.h"
#include "../../parser/msg_parser.h"
+#include "../../lib/kcore/parse_require.h"
#include "../../lib/kcore/parse_supported.h"
#include "../../data_lump_rpl.h"
#include "../usrloc/usrloc.h"
@@ -408,6 +409,8 @@ int build_contact(sip_msg_t *msg, ucontact_t* c, str *host)
#define EI_R_PARSE_PATH "Path parse error" /*
R_PARSE_PATH */
#define EI_R_PATH_UNSUP "No support for found Path indicated" /*
R_PATH_UNSUP */
#define EI_R_OB_UNSUP "No support for Outbound indicated" /*
R_OB_UNSUP */
+#define EI_R_OB_REQD "No support for Outbound on server" /*
R_OB_REQD */
+
str error_info[] = {
{EI_R_FINE, sizeof(EI_R_FINE) - 1},
@@ -441,7 +444,7 @@ str error_info[] = {
{EI_R_PARSE_PATH, sizeof(EI_R_PARSE_PATH) - 1},
{EI_R_PATH_UNSUP, sizeof(EI_R_PATH_UNSUP) - 1},
{EI_R_OB_UNSUP, sizeof(EI_R_OB_UNSUP) - 1},
-
+ {EI_R_OB_REQD, sizeof(EI_R_OB_REQD) - 1},
};
int codes[] = {
@@ -475,8 +478,8 @@ int codes[] = {
400, /* R_CALLID_LEN */
400, /* R_PARSE_PATH */
420, /* R_PATH_UNSUP */
- 421 /* R_OB_UNSUP */
-
+ 421, /* R_OB_UNSUP */
+ 420 /* R_OB_REQD */
};
@@ -654,14 +657,27 @@ int reg_send_reply(struct sip_msg* _m)
if (add_require(_m, &outbound_str) < 0)
return -1;
+ if (add_supported(_m, &outbound_str) < 0)
+ return -1;
+
if (reg_flow_timer > 0) {
if (add_flow_timer(_m) < 0)
return -1;
}
- /* Fall-thru */
+ break;
case REG_OUTBOUND_SUPPORTED:
if (add_supported(_m, &outbound_str) < 0)
return -1;
+
+ if (get_require(_m) & F_OPTION_TAG_OUTBOUND) {
+ if (add_require(_m, &outbound_str) < 0)
+ return -1;
+
+ if (reg_flow_timer > 0) {
+ if (add_flow_timer(_m) < 0)
+ return -1;
+ }
+ }
break;
}
break;
@@ -671,6 +687,10 @@ int reg_send_reply(struct sip_msg* _m)
if (add_supported(_m, &outbound_str) < 0)
return -1;
break;
+ case R_OB_REQD:
+ if (add_unsupported(_m, &outbound_str) < 0)
+ return -1;
+ break;
default:
break;
}
diff --git a/modules/registrar/rerrno.h b/modules/registrar/rerrno.h
index 63add5a..9bc9338 100644
--- a/modules/registrar/rerrno.h
+++ b/modules/registrar/rerrno.h
@@ -64,7 +64,8 @@ typedef enum rerr {
R_CALLID_LEN, /*!< Callid too long */
R_PARSE_PATH, /*!< Error while parsing Path */
R_PATH_UNSUP, /*!< Path not supported by UAC */
- R_OB_UNSUP /*!< Outbound not supported by UAC */
+ R_OB_UNSUP, /*!< Outbound not supported by UAC */
+ R_OB_REQD /*!< Outbound required by UAC but not supported on server */
} rerr_t;
diff --git a/modules/registrar/save.c b/modules/registrar/save.c
index 9cc2dd4..b7a4035 100644
--- a/modules/registrar/save.c
+++ b/modules/registrar/save.c
@@ -61,6 +61,7 @@
#include "../../mod_fix.h"
#include "../../lib/srutils/sruid.h"
#include "../../lib/kcore/cmpapi.h"
+#include "../../lib/kcore/parse_require.h"
#include "../../lib/kcore/parse_supported.h"
#include "../../lib/kcore/statistics.h"
#ifdef USE_TCP
@@ -843,13 +844,23 @@ int save(struct sip_msg* _m, udomain_t* _d, int _cflags, str *_uri)
}
if (parse_supported(_m) == 0) {
- if (!(((struct option_tag_body *)_m->supported->parsed)->option_tags_all
- & F_OPTION_TAG_OUTBOUND) && reg_outbound_mode == REG_OUTBOUND_REQUIRE) {
+ if (!(get_supported(_m) & F_OPTION_TAG_OUTBOUND)
+ && reg_outbound_mode == REG_OUTBOUND_REQUIRE) {
LM_WARN("Outbound required by server and not supported by UAC\n");
rerrno = R_OB_UNSUP;
goto error;
}
}
+
+ if (parse_require(_m) == 0) {
+ if (!(get_require(_m) & F_OPTION_TAG_OUTBOUND)
+ && reg_outbound_mode == REG_OUTBOUND_NONE) {
+ LM_WARN("Outbound required by client and not supported by server\n");
+ rerrno = R_OB_REQD;
+ goto error;
+ }
+ }
+
get_act_time();
c = get_first_contact(_m);