Skip to content

Commit

Permalink
registrars: Correctly reply on all save() edge-cases
Browse files Browse the repository at this point in the history
This patch fixes several corner-cases when calling
[mid_registrar]_save(), where:

    * the registrar would not send a reply
    * the registrar would send a bad reply (e.g. 200 OK on an error!)

(cherry picked from commit 46553a9)
  • Loading branch information
liviuchircu committed Jan 14, 2021
1 parent 210295f commit b36ed2f
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 11 deletions.
4 changes: 4 additions & 0 deletions lib/reg/rerrno.c
Expand Up @@ -29,6 +29,8 @@ rerr_t rerrno;

str error_info[] = {
{EI_R_FINE, sizeof(EI_R_FINE) - 1},
{EI_R_INTERNAL, sizeof(EI_R_INTERNAL) - 1},
{EI_R_NOT_IMPL, sizeof(EI_R_NOT_IMPL) - 1},
{EI_R_UL_DEL_R, sizeof(EI_R_UL_DEL_R) - 1},
{EI_R_UL_GET_R, sizeof(EI_R_UL_GET_R) - 1},
{EI_R_UL_NEW_R, sizeof(EI_R_UL_NEW_R) - 1},
Expand Down Expand Up @@ -62,6 +64,8 @@ str error_info[] = {

int rerr_codes[] = {
200, /* R_FINE */
500, /* R_FINE */
501, /* R_FINE */
500, /* R_UL_DEL_R */
500, /* R_UL_GET */
500, /* R_UL_NEW_R */
Expand Down
16 changes: 10 additions & 6 deletions lib/reg/rerrno.h
Expand Up @@ -25,6 +25,8 @@
#define __LIB_REG_RERRNO_H__

#define EI_R_FINE "No problem" /* R_FINE */
#define EI_R_INTERNAL "Server Internal Error" /* R_INTERNAL */
#define EI_R_NOT_IMPL "Method Not Implemented" /* R_NOT_IMPL */
#define EI_R_UL_DEL_R "usrloc_record_delete failed" /* R_UL_DEL_R */
#define EI_R_UL_GET_R "usrloc_record_get failed" /* R_UL_GET */
#define EI_R_UL_NEW_R "usrloc_record_new failed" /* R_UL_NEW_R */
Expand All @@ -42,21 +44,23 @@
#define EI_R_TO_MISS "To header not found" /* R_TO_MISS */
#define EI_R_CID_MISS "Call-ID header not found" /* R_CID_MISS */
#define EI_R_CS_MISS "CSeq header not found" /* R_CS_MISS */
#define EI_R_PARSE_EXP "Expires parse error" /* R_PARSE_EXP */
#define EI_R_PARSE_EXP "Expires parse error" /* R_PARSE_EXP */
#define EI_R_PARSE_CONT "Contact parse error" /* R_PARSE_CONT */
#define EI_R_STAR_EXP "* used in contact and expires is not zero" /* R_STAR__EXP */
#define EI_R_STAR_CONT "* used in contact and more than 1 contact" /* R_STAR_CONT */
#define EI_R_OOO "Out of order request" /* R_OOO */
#define EI_R_RETRANS "Retransmission" /* R_RETRANS */
#define EI_R_STAR_EXP "* used in contact and expires is not zero" /* R_STAR__EXP */
#define EI_R_STAR_CONT "* used in contact and more than 1 contact" /* R_STAR_CONT */
#define EI_R_OOO "Out of order request" /* R_OOO */
#define EI_R_RETRANS "Retransmission" /* R_RETRANS */
#define EI_R_UNESCAPE "Error while unescaping username" /* R_UNESCAPE */
#define EI_R_TOO_MANY "Too many registered contacts" /* R_TOO_MANY */
#define EI_R_CONTACT_LEN "Contact/received too long" /* R_CONTACT_LEN */
#define EI_R_CONTACT_LEN "Contact/received too long" /* R_CONTACT_LEN */
#define EI_R_CALLID_LEN "Callid too long" /* R_CALLID_LEN */
#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 */

typedef enum rerr {
R_FINE = 0, /*!< Everything went OK */
R_INTERNAL, /*!< Internal Error */
R_NOT_IMPL, /*!< Not Implemented */
R_UL_DEL_R, /*!< Usrloc record delete failed */
R_UL_GET_R, /*!< Usrloc record get failed */
R_UL_NEW_R, /*!< Usrloc new record failed */
Expand Down
12 changes: 7 additions & 5 deletions modules/mid_registrar/save.c
Expand Up @@ -2323,8 +2323,9 @@ int mid_reg_save(struct sip_msg *msg, char *dom, char *flags_gp,
int rc = -1, st, unlock_udomain = 0;

if (msg->REQ_METHOD != METHOD_REGISTER) {
LM_ERR("ignoring non-REGISTER SIP request (%d)\n", msg->REQ_METHOD);
return -1;
LM_ERR("rejecting non-REGISTER SIP request (%d)\n", msg->REQ_METHOD);
rerrno = R_NOT_IMPL;
goto out_error;
}

rerrno = R_FINE;
Expand All @@ -2343,7 +2344,7 @@ int mid_reg_save(struct sip_msg *msg, char *dom, char *flags_gp,

if (parse_reg_headers(msg) != 0) {
LM_ERR("failed to parse req headers\n");
return -1;
goto out_error;
}

if (!to_uri_gp) {
Expand All @@ -2362,7 +2363,7 @@ int mid_reg_save(struct sip_msg *msg, char *dom, char *flags_gp,

if (extract_aor(&to_uri, &sctx.aor, 0, 0) < 0) {
LM_ERR("failed to extract Address Of Record\n");
return -1;
goto out_error;
}

if (check_contacts(msg, &st) > 0) {
Expand All @@ -2383,7 +2384,8 @@ int mid_reg_save(struct sip_msg *msg, char *dom, char *flags_gp,
if (!del_lump(msg, path->name.s - msg->buf,
path->len, HDR_PATH_T)) {
LM_ERR("failed to remove Path HF\n");
return -1;
rerrno = R_INTERNAL;
goto out_error;
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions modules/registrar/save.c
Expand Up @@ -237,10 +237,12 @@ static inline int insert_contacts(struct sip_msg* _m, contact_t* _c,
if (r==NULL || r->contacts==NULL) {
LM_CRIT("BUG - overflow detected with r=%p and "
"contacts=%p\n",r,r->contacts);
rerrno = R_INTERNAL;
goto error;
}
if (ul.delete_ucontact( r, r->contacts, 0)!=0) {
LM_ERR("failed to remove contact\n");
rerrno = R_INTERNAL;
goto error;
}
} else {
Expand Down Expand Up @@ -649,6 +651,7 @@ int save_aux(struct sip_msg* _m, str* forced_binding, char* _d, char* _f, char*
if (parse_contacts(forced_binding, &forced_c) < 0) {
LM_ERR("Unable to parse forced binding [%.*s]\n",
forced_binding->len, forced_binding->s);
rerrno = R_INTERNAL;
goto error;
}
/* prevent processing all the headers from the message */
Expand Down

0 comments on commit b36ed2f

Please sign in to comment.