int save(struct sip_msg* _m, udomain_t* _d, int _cflags, str *_uri) { contact_t* c; int st, mode; str aor; int ret; sip_uri_t *u; rr_t *route; struct sip_uri puri; param_hooks_t hooks; param_t *params; contact_t *contact; int use_ob = 1, use_regid = 1; u = parse_to_uri(_m); if(u==NULL) goto error; rerrno = R_FINE; ret = 1; if (parse_message(_m) < 0) { goto error; } if (check_contacts(_m, &st) > 0) { goto error; } if (parse_supported(_m) == 0) { 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 UAC and not supported by server\n"); rerrno = R_OB_REQD; goto error; } } if (reg_outbound_mode != REG_OUTBOUND_NONE && _m->contact && _m->contact->parsed && !(parse_headers(_m, HDR_VIA2_F, 0) == -1 || _m->via2 == 0 || _m->via2->error != PARSE_OK)) { /* Outbound supported on server, and more than one Via: - not the first hop */ if (!(parse_headers(_m, HDR_PATH_F, 0) == -1 || _m->path == 0)) { route = (rr_t *)0; if (parse_rr_body(_m->path->body.s, _m->path->body.len, &route) < 0) { LM_ERR("Failed to parse Path: header body\n"); goto error; } if (parse_uri(route->nameaddr.uri.s, route->nameaddr.uri.len, &puri) < 0) { LM_ERR("Failed to parse Path: URI\n"); goto error; } if (parse_params(&puri.params, CLASS_URI, &hooks, ¶ms) != 0) { LM_ERR("Failed to parse Path: URI parameters\n"); goto error; } if (!hooks.uri.ob) { /* No ;ob parameter to top Path: URI - no outbound */ use_ob = 0; } } else { /* No Path: header - no outbound */ use_ob = 0; } contact = ((contact_body_t *) _m->contact->parsed)->contacts; if (!contact) { LM_ERR("empty Contact:\n"); goto error; } if ((use_ob == 0) && (reg_regid_mode == REG_REGID_OUTBOUND)) { if ((get_supported(_m) & F_OPTION_TAG_OUTBOUND) && contact->reg_id) { LM_WARN("Outbound used by UAC but not supported by edge proxy\n"); rerrno = R_OB_UNSUP_EDGE; goto error; } else { /* ignore ;reg-id parameter */ use_regid = 0; } } } get_act_time(); c = get_first_contact(_m); if (extract_aor((_uri)?_uri:&get_to(_m)->uri, &aor, NULL) < 0) { LM_ERR("failed to extract Address Of Record\n"); goto error; } mem_only = is_cflag_set(REG_SAVE_MEM_FL)?FL_MEM:FL_NONE; if (c == 0) { if (st) { if (star(_m, (udomain_t*)_d, &aor, &u->host) < 0) goto error; else ret=3; } else { if (no_contacts(_m, (udomain_t*)_d, &aor, &u->host) < 0) goto error; else ret=4; } } else { mode = is_cflag_set(REG_SAVE_REPL_FL)?1:0; if ((ret=add_contacts(_m, (udomain_t*)_d, &aor, mode, use_regid)) < 0) goto error; ret = (ret==0)?1:ret; } update_stat(accepted_registrations, 1); /* Only send reply upon request, not upon reply */ if ((is_route_type(REQUEST_ROUTE) || is_route_type(FAILURE_ROUTE)) && !is_cflag_set(REG_SAVE_NORPL_FL) && (reg_send_reply(_m) < 0)) return -1; return ret; error: update_stat(rejected_registrations, 1); if (is_route_type(REQUEST_ROUTE) && !is_cflag_set(REG_SAVE_NORPL_FL) ) reg_send_reply(_m); return 0; }
int save(struct sip_msg* _m, udomain_t* _d, int _cflags, str *_uri) { contact_t* c; int st, mode; str aor; int ret; sip_uri_t *u; u = parse_to_uri(_m); if(u==NULL) goto error; rerrno = R_FINE; ret = 1; if (parse_message(_m) < 0) { goto error; } if (check_contacts(_m, &st) > 0) { goto error; } if (parse_supported(_m) == 0) { if (!(((struct supported_body *)_m->supported->parsed)->supported_all & F_SUPPORTED_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; } } get_act_time(); c = get_first_contact(_m); if (extract_aor((_uri)?_uri:&get_to(_m)->uri, &aor, NULL) < 0) { LM_ERR("failed to extract Address Of Record\n"); goto error; } mem_only = is_cflag_set(REG_SAVE_MEM_FL)?FL_MEM:FL_NONE; if (c == 0) { if (st) { if (star(_m, (udomain_t*)_d, &aor, &u->host) < 0) goto error; else ret=3; } else { if (no_contacts(_m, (udomain_t*)_d, &aor, &u->host) < 0) goto error; else ret=4; } } else { mode = is_cflag_set(REG_SAVE_REPL_FL)?1:0; if ((ret=add_contacts(_m, (udomain_t*)_d, &aor, mode)) < 0) goto error; ret = (ret==0)?1:ret; } update_stat(accepted_registrations, 1); /* Only send reply upon request, not upon reply */ if ((is_route_type(REQUEST_ROUTE)) && !is_cflag_set(REG_SAVE_NORPL_FL) && (reg_send_reply(_m) < 0)) return -1; return ret; error: update_stat(rejected_registrations, 1); if (is_route_type(REQUEST_ROUTE) && !is_cflag_set(REG_SAVE_NORPL_FL) ) reg_send_reply(_m); return 0; }