* Set the invitestate to INV_CALLING when we send a connected line reinvite.
This prevents us from potentially rapid-firing reinvites to a single peer.
* Use the astdb to store a peer's allowed methods. This prevents us from sending
an UPDATE during the interval between startup and the peer's first registration
if the peer does not support the UPDATE method.
* Handle Polycom's method of indicating allowed methods in REGISTER. Instead of
using an Allow header, they place the allowed methods in a methods= parameter
in the Contact header.
if (ast_strlen_zero(allow)) {
- /* RFC 3261 states:
- *
- * "The absence of an Allow header field MUST NOT be
- * interpreted to mean that the UA sending the message supports no
- * methods. Rather, it implies that the UA is not providing any
- * information on what methods it supports."
- *
- * For simplicity, we'll assume that the peer allows all known
- * SIP methods if they have no Allow header. We can then clear out the necessary
- * bits if the peer lets us know that we have sent an unsupported method.
+ /* I have witnessed that REGISTER requests from Polycom phones do not
+ * place the phone's allowed methods in an Allow header. Instead, they place the
+ * allowed methods in a methods= parameter in the Contact header.
*/
- return UINT_MAX;
+ char *contact = ast_strdupa(get_header(req, "Contact"));
+ char *methods = strstr(contact, ";methods=");
+
+ if (ast_strlen_zero(methods)) {
+ /* RFC 3261 states:
+ *
+ * "The absence of an Allow header field MUST NOT be
+ * interpreted to mean that the UA sending the message supports no
+ * methods. Rather, it implies that the UA is not providing any
+ * information on what methods it supports."
+ *
+ * For simplicity, we'll assume that the peer allows all known
+ * SIP methods if they have no Allow header. We can then clear out the necessary
+ * bits if the peer lets us know that we have sent an unsupported method.
+ */
+ return UINT_MAX;
+ }
+ allow = ast_strip_quoted(methods + 9, "\"", "\"");
}
for (method = strsep(&allow, ","); !ast_strlen_zero(method); method = strsep(&allow, ",")) {
int id = find_sip_method(ast_skip_blanks(method));
@@ -11020,6 +11030,7 @@
initialize_initreq(p, &req);
p->lastinvite = p->ocseq;
ast_set_flag(&p->flags[0], SIP_OUTGOING);
+ p->invitestate = INV_CALLING;
send_request(p, &req, XMIT_CRITICAL, p->ocseq);
} else if (is_method_allowed(&p->allowed_methods, SIP_UPDATE)) {
reqprep(&req, p, SIP_UPDATE, 0, 1);
@@ -11614,6 +11625,7 @@
ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", peer->deprecated_username ? "username" : "defaultuser", "", "regserver", "", "useragent", "", "lastms", "", SENTINEL);
} else {
ast_db_del("SIP/Registry", peer->name);
+ ast_db_del("SIP/PeerMethods", peer->name);
}
}
}
@@ -11691,11 +11703,13 @@
int expire;
int port;
char *scan, *addr, *port_str, *expiry_str, *username, *contact;
+ char allowed_methods_str[256] = "";
if (peer->rt_fromcontact)
return;
if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
return;
+ ast_db_get("SIP/PeerMethods", peer->name, allowed_methods_str, sizeof(allowed_methods_str));
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum