chan_sip autocreatepeer=persist option for auto-created peers to survive reload
authorJonathan Rose <jrose@digium.com>
Fri, 23 Dec 2011 20:19:33 +0000 (20:19 +0000)
committerJonathan Rose <jrose@digium.com>
Fri, 23 Dec 2011 20:19:33 +0000 (20:19 +0000)
This patch moves destruction of sip peers to immediately after the general section of
sip.conf is read so that autocreatepeer setting can be read before deletion of peers.
If autocreatepeer=persist at reload, then peers created by the autocreatepeer setting
will be skipped when purging the current SIP peer list.

(closes ASTERISK-16508)
Reported by: Kirill Katsnelson
Patches:
017797-kkm-persist-autopeers-1.8.patch uploaded by Kirill Katsnelson (license 5845)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@349097 65c4cc65-6c06-0410-ace0-fbb531ad65f3

CHANGES
channels/chan_sip.c
channels/sip/include/sip.h
configs/sip.conf.sample

diff --git a/CHANGES b/CHANGES
index db9f1c2..30ba4d4 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -27,6 +27,8 @@ SIP Changes
    name field if CID number exists without a CID name. This change improves
    compatibility with certain device features such as Avaya IP500's directory
    lookup service.
+ * A new setting for autocreatepeer (autocreatepeer=persistent) allows peers
+   created using that setting to not be removed during SIP reload.
 
 Chan_local changes
 ------------------
index 21e2350..3f12e6e 100644 (file)
@@ -14998,7 +14998,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock
                }
                ao2_unlock(peer);
        }
-       if (!peer && sip_cfg.autocreatepeer) {
+       if (!peer && sip_cfg.autocreatepeer != AUTOPEERS_DISABLED) {
                /* Create peer if we have autocreate mode enabled */
                peer = temp_peer(name);
                if (peer) {
@@ -16715,6 +16715,18 @@ static enum st_refresher str2strefresher(const char *s)
        return map_s_x(strefreshers, s, -1);
 }
 
+/* Autocreatepeer modes */
+static struct _map_x_s autopeermodes[] = {
+        { AUTOPEERS_DISABLED, "Off"},
+        { AUTOPEERS_VOLATILE, "Volatile"},
+        { AUTOPEERS_PERSIST,  "Persisted"},
+        { -1, NULL},
+};
+
+static const char *autocreatepeer2str(enum autocreatepeer_mode r)
+{
+       return map_x_s(autopeermodes, r, "Unknown");
+}
 
 static int peer_status(struct sip_peer *peer, char *status, int statuslen)
 {
@@ -18336,7 +18348,7 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_
        ast_cli(a->fd, "  Videosupport:           %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT)));
        ast_cli(a->fd, "  Textsupport:            %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT)));
        ast_cli(a->fd, "  Ignore SDP sess. ver.:  %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION)));
-       ast_cli(a->fd, "  AutoCreate Peer:        %s\n", AST_CLI_YESNO(sip_cfg.autocreatepeer));
+       ast_cli(a->fd, "  AutoCreate Peer:        %s\n", autocreatepeer2str(sip_cfg.autocreatepeer));
        ast_cli(a->fd, "  Match Auth Username:    %s\n", AST_CLI_YESNO(global_match_auth_username));
        ast_cli(a->fd, "  Allow unknown access:   %s\n", AST_CLI_YESNO(sip_cfg.allowguest));
        ast_cli(a->fd, "  Allow subscriptions:    %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)));
@@ -28477,7 +28489,9 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
 static int peer_markall_func(void *device, void *arg, int flags)
 {
        struct sip_peer *peer = device;
-       peer->the_mark = 1;
+       if (!peer->selfdestruct || sip_cfg.autocreatepeer != AUTOPEERS_PERSIST) {
+               peer->the_mark = 1;
+       }
        return 0;
 }
 
@@ -28602,11 +28616,6 @@ static int reload_config(enum channelreloadreason reason)
                                }
                                ASTOBJ_UNLOCK(iterator);
                } while(0));
-
-               /* Then, actually destroy users and registry */
-               ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
-               ast_debug(4, "--------------- Done destroying registry list\n");
-               ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, NULL, "callback to mark all peers");
        }
 
        /* Reset certificate handling for TLS sessions */
@@ -29012,7 +29021,11 @@ static int reload_config(enum channelreloadreason reason)
 
                        proxy_update(&sip_cfg.outboundproxy);
                } else if (!strcasecmp(v->name, "autocreatepeer")) {
-                       sip_cfg.autocreatepeer = ast_true(v->value);
+                       if (!strcasecmp(v->value, "persist")) {
+                               sip_cfg.autocreatepeer = AUTOPEERS_PERSIST;
+                       } else {
+                               sip_cfg.autocreatepeer = ast_true(v->value) ? AUTOPEERS_VOLATILE : AUTOPEERS_DISABLED;
+                       }
                } else if (!strcasecmp(v->name, "match_auth_username")) {
                        global_match_auth_username = ast_true(v->value);
                } else if (!strcasecmp(v->name, "srvlookup")) {
@@ -29290,6 +29303,13 @@ static int reload_config(enum channelreloadreason reason)
                }
        }
 
+       if (reason != CHANNEL_MODULE_LOAD) {
+               /* Then, actually destroy users and registry */
+               ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
+               ast_debug(4, "--------------- Done destroying registry list\n");
+               ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, NULL, "callback to mark all peers");
+       }
+
        if (subscribe_network_change) {
                network_change_event_subscribe();
        } else {
index 0c3661d..84f3af9 100644 (file)
 #define DEFAULT_NOTIFYRINGING  TRUE     /*!< Notify devicestate system on ringing state */
 #define DEFAULT_NOTIFYCID      DISABLED        /*!< Include CID with ringing notifications */
 #define DEFAULT_PEDANTIC       TRUE     /*!< Follow SIP standards for dialog matching */
-#define DEFAULT_AUTOCREATEPEER FALSE    /*!< Don't create peers automagically */
+#define DEFAULT_AUTOCREATEPEER AUTOPEERS_DISABLED    /*!< Don't create peers automagically */
 #define        DEFAULT_MATCHEXTERNADDRLOCALLY FALSE /*!< Match extern IP locally default setting */
 #define DEFAULT_QUALIFY        FALSE    /*!< Don't monitor devices */
 #define DEFAULT_CALLEVENTS     FALSE    /*!< Extra manager SIP call events */
@@ -556,6 +556,14 @@ enum sip_transport {
        SIP_TRANSPORT_TLS = 1 << 2,    /*!< TCP/TLS - reliable and secure transport for signalling */
 };
 
+/*! \brief Automatic peer registration behavior
+*/
+enum autocreatepeer_mode {
+       AUTOPEERS_DISABLED = 0,         /*!< Automatic peer creation disabled */
+       AUTOPEERS_VOLATILE,                     /*!< Automatic peers dropped on sip reload (pre-1.8 behavior) */
+       AUTOPEERS_PERSIST                       /*!< Automatic peers survive sip configuration reload */
+};
+
 /*! \brief States whether a SIP message can create a dialog in Asterisk. */
 enum can_create_dialog {
        CAN_NOT_CREATE_DIALOG,
@@ -709,7 +717,7 @@ struct sip_settings {
        int rtautoclear;            /*!< Realtime ?? */
        int directrtpsetup;         /*!< Enable support for Direct RTP setup (no re-invites) */
        int pedanticsipchecking;    /*!< Extra checking ?  Default off */
-       int autocreatepeer;         /*!< Auto creation of peers at registration? Default off. */
+       enum autocreatepeer_mode autocreatepeer;  /*!< Auto creation of peers at registration? Default off. */
        int srvlookup;              /*!< SRV Lookup on or off. Default is on */
        int allowguest;             /*!< allow unauthenticated peers to connect? */
        int alwaysauthreject;       /*!< Send 401 Unauthorized for all failing requests */
index c6b7e1e..115b337 100644 (file)
@@ -478,6 +478,16 @@ srvlookup=yes                   ; Enable DNS SRV lookups on outbound calls
 
 ;use_q850_reason = no ; Default "no"
                       ; Set to yes add Reason header and use Reason header if it is available.
+
+;autocreatepeers=no             ; Allow any not exsplicitly defined here UAC to register
+                                ; WITHOUT AUTHENTICATION. Enabling this options poses a high
+                                ; potential security risk and should be avoided unless the 
+                                ; server is behind a trusted firewall. 
+                                ; When enabled by setting to "yes", the autocreated peers are
+                                ; pruned immediately when the "sip reload" command is issued
+                                ; through CLI. When enabled by setting to "persist", the auto-
+                                ; created peers survive the "sip reload" command.
+
 ;
 ;------------------------ TLS settings ------------------------------------------------------------
 ;tlscertfile=</path/to/certificate.pem> ; Certificate file (*.pem format only) to use for TLS connections