Index: chan_sip.c =================================================================== --- chan_sip.c (revision 94774) +++ chan_sip.c (working copy) @@ -1091,6 +1091,37 @@ enum referstatus status; /*!< REFER status */ }; + +/*! \brief Structure that encapsulates all attributes related to running + * SIP Session-Timers feature on a per dialog basis. + */ +struct sip_st_dlg { + int st_active; /*!< Session-Timers on/off */ + int st_interval; /*!< Session-Timers negotiated session refresh interval */ + int st_schedid; /*!< Session-Timers ast_sched scheduler id */ + enum st_refresher st_ref; /*!< Session-Timers session refresher */ + int st_expirys; /*!< Session-Timers number of expirys */ + int st_active_peer_ua; /*!< Session-Timers on/off in peer UA */ + int st_cached_min_se; /*!< Session-Timers cached Min-SE */ + int st_cached_max_se; /*!< Session-Timers cached Session-Expires */ + enum st_mode st_cached_mode; /*!< Session-Timers cached M.O. */ + enum st_refresher st_cached_ref; /*!< Session-Timers cached refresher */ +}; + + +/*! \brief Structure that encapsulates all attributes related to configuration + * of SIP Session-Timers feature on a per user/peer basis. + */ +struct sip_st_cfg { + enum st_mode st_mode_oper; /*!< Mode of operation for Session-Timers */ + enum st_refresher st_ref; /*!< Session-Timer refresher */ + int st_min_se; /*!< Lowest threshold for session refresh interval */ + int st_max_se; /*!< Highest threshold for session refresh interval */ +}; + + + + /*! \brief sip_pvt: structures used for each SIP dialog, ie. a call, a registration, a subscribe. * Created and initialized by sip_alloc(), the descriptor goes into the list of * descriptors (dialoglist). @@ -1235,17 +1266,7 @@ before strolling to the Grokyzpå (A bit unsure of this, please correct if you know more) */ - - int st_active; /*!< Session-Timers on/off */ - int st_interval; /*!< Session-Timers negotiated session refresh interval */ - int st_schedid; /*!< Session-Timers ast_sched scheduler id */ - enum st_refresher st_ref; /*!< Session-Timers session refresher */ - int st_expirys; /*!< Session-Timers number of expirys */ - int st_active_peer_ua; /*!< Session-Timers on/off in peer UA */ - int st_cached_min_se; /*!< Session-Timers cached Min-SE */ - int st_cached_max_se; /*!< Session-Timers cached Session-Expires */ - enum st_mode st_cached_mode; /*!< Session-Timers cached M.O. */ - enum st_refresher st_cached_ref; /*!< Session-Timers cached refresher */ + struct sip_st_dlg *stimer; /*!< SIP Session-Timers */ }; @@ -1353,11 +1374,7 @@ struct ast_variable *chanvars; /*!< Variables to set for channel created by user */ int maxcallbitrate; /*!< Maximum Bitrate for a video call */ int autoframing; - - enum st_mode st_mode_oper; /*!< Mode of operation for Session-Timers */ - enum st_refresher st_ref; /*!< Session-Timer refresher */ - int st_min_se; /*!< Lowest threshold for session refresh interval */ - int st_max_se; /*!< Highest threshold for session refresh interval */ + struct sip_st_cfg stimer; /*!< SIP Session-Timers */ }; /*! @@ -1443,12 +1460,9 @@ struct ast_variable *chanvars; /*!< Variables to set for channel created by user */ struct sip_pvt *mwipvt; /*!< Subscription for MWI */ int autoframing; - enum st_mode st_mode_oper; /*!< Mode of operation for Session-Timers */ - enum st_refresher st_ref; /*!< Session-Timer refresher */ - int st_min_se; /*!< Lowest threshold for session refresh interval */ - int st_max_se; /*!< Highest threshold for session refresh interval */ - int timer_t1; /*!< The maximum T1 value for the peer */ - int timer_b; /*!< The maximum timer B (transaction timeouts) */ + struct sip_st_cfg stimer; /*!< SIP Session-Timers */ + int timer_t1; /*!< The maximum T1 value for the peer */ + int timer_b; /*!< The maximum timer B (transaction timeouts) */ }; @@ -1944,6 +1958,7 @@ static int st_get_se(struct sip_pvt *, int max); static enum st_refresher st_get_refresher(struct sip_pvt *); static enum st_mode st_get_mode(struct sip_pvt *); +static struct sip_st_dlg* sip_st_alloc(struct sip_pvt *const p); /*! \brief Definition of this channel for PBX channel registration */ @@ -2637,7 +2652,7 @@ append_history(p, "SchedDestroy", "%d ms", ms); p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p)); - if (p->st_active == TRUE && p->st_schedid > 0) + if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > 0) stop_session_timer(p); } @@ -3404,6 +3419,7 @@ static void sip_destroy_user(struct sip_user *user) { ast_debug(3, "Destroying user object from memory: %s\n", user->name); + ast_free_ha(user->ha); if (user->chanvars) { ast_variables_destroy(user->chanvars); @@ -3884,6 +3900,13 @@ p->registry = registry_unref(p->registry); } + /* Destroy Session-Timers if allocated */ + if (p->stimer) { + if (p->stimer->st_active == TRUE && p->stimer->st_schedid > -1) + ast_sched_del(sched, p->stimer->st_schedid); + ast_free(p->stimer); + } + /* Unlink us from the owner if we have one */ if (p->owner) { if (lockowner) @@ -5207,6 +5230,35 @@ snprintf(tagbuf, len, "as%08lx", ast_random()); } +/*! \brief Allocate Session-Timers struct w/in dialog */ +static struct sip_st_dlg* sip_st_alloc(struct sip_pvt *const p) +{ + struct sip_st_dlg *stp; + + if (p->stimer) { + ast_log(LOG_ERROR, "Session-Timer struct already allocated\n"); + return p->stimer; + } + + if (!(stp = ast_calloc(1, sizeof(struct sip_st_dlg)))) + return NULL; + + p->stimer = stp; + + stp->st_active = FALSE; /* Session-Timers on/off */ + stp->st_interval = 0; /* Session-Timers negotiated session refresh interval */ + stp->st_schedid = -1; /* Session-Timers ast_sched scheduler id */ + stp->st_ref = 0; /* Session-Timers session refresher */ + stp->st_expirys = 0; /* Session-Timers number of expirys */ + stp->st_active_peer_ua = FALSE; /* Session-Timers on/off in peer UA */ + stp->st_cached_min_se = 0; /* Session-Timers cached Min-SE */ + stp->st_cached_max_se = 0; /* Session-Timers cached Session-Expires */ + stp->st_cached_ref = 0; /* Session-Timers cached refresher */ + stp->st_cached_mode = 0; /* Session-Timers cached mode */ + return p->stimer; +} + + /*! \brief Allocate sip_pvt structure, set defaults and link in the container. * Returns a reference to the object so whoever uses it later must * remember to release the reference. @@ -5234,16 +5286,7 @@ p->stateid = -1; p->sessionversion_remote = -1; p->session_modify = TRUE; - p->st_active = FALSE; /* Session-Timers on/off */ - p->st_interval = 0; /* Session-Timers negotiated session refresh interval */ - p->st_schedid = -1; /* Session-Timers ast_sched scheduler id */ - p->st_ref = 0; /* Session-Timers session refresher */ - p->st_expirys = 0; /* Session-Timers number of expirys */ - p->st_active_peer_ua = FALSE; /* Session-Timers on/off in peer UA */ - p->st_cached_min_se = 0; /* Session-Timers cached Min-SE */ - p->st_cached_max_se = 0; /* Session-Timers cached Session-Expires */ - p->st_cached_ref = 0; /* Session-Timers cached refresher */ - p->st_cached_mode = 0; /* Session-Timers cached mode */ + p->stimer = NULL; p->prefs = default_prefs; /* Set default codecs for this call */ if (intended_method != SIP_OPTIONS) { /* Peerpoke has it's own system */ @@ -6768,10 +6811,10 @@ add_header(resp, "Supported", SUPPORTED_EXTENSIONS); /* Add Session-Timers related headers if the feature is active for this session */ - if (p->st_active == TRUE && p->st_active_peer_ua == TRUE) { + if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE) { char se_hdr[256]; - snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->st_interval, - strefresher2str(p->st_ref)); + snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, + strefresher2str(p->stimer->st_ref)); add_header(resp, "Require", "timer"); add_header(resp, "Session-Expires", se_hdr); } @@ -6908,10 +6951,10 @@ } /* Add Session-Timers related headers if the feature is active for this session */ - if (p->st_active == TRUE && p->st_active_peer_ua == TRUE) { + if (p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE) { char se_hdr[256]; - snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->st_interval, - strefresher2str(p->st_ref)); + snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, + strefresher2str(p->stimer->st_ref)); add_header(req, "Require", "timer"); add_header(req, "Session-Expires", se_hdr); snprintf(se_hdr, sizeof(se_hdr), "%d", st_get_se(p, FALSE)); @@ -8170,15 +8213,13 @@ if (st_get_mode(p) == SESSION_TIMER_MODE_ORIGINATE) { char i2astr[10]; - if (!p->st_interval) - p->st_interval = st_get_se(p, TRUE); + if (!p->stimer->st_interval) + p->stimer->st_interval = st_get_se(p, TRUE); - p->st_active = TRUE; + p->stimer->st_active = TRUE; - snprintf(i2astr, sizeof(i2astr), "%d", p->st_interval); + snprintf(i2astr, sizeof(i2astr), "%d", p->stimer->st_interval); add_header(&req, "Session-Expires", i2astr); - - snprintf(i2astr, sizeof(i2astr), "%d", st_get_se(p, FALSE)); add_header(&req, "Min-SE", i2astr); } @@ -11943,10 +11984,10 @@ ast_cli(fd, " %s = %s\n", v->name, v->value); } - ast_cli(fd, " Sess-Timers : %s\n", stmode2str(peer->st_mode_oper)); - ast_cli(fd, " Sess-Refresh : %s\n", strefresher2str(peer->st_ref)); - ast_cli(fd, " Sess-Expires : %d secs\n", peer->st_max_se); - ast_cli(fd, " Min-Sess : %d secs\n", peer->st_min_se); + ast_cli(fd, " Sess-Timers : %s\n", stmode2str(peer->stimer.st_mode_oper)); + ast_cli(fd, " Sess-Refresh : %s\n", strefresher2str(peer->stimer.st_ref)); + ast_cli(fd, " Sess-Expires : %d secs\n", peer->stimer.st_max_se); + ast_cli(fd, " Min-Sess : %d secs\n", peer->stimer.st_min_se); ast_cli(fd,"\n"); unref_peer(peer); } else if (peer && type == 1) { /* manager listing */ @@ -11989,10 +12030,10 @@ astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); astman_append(s, "SIP-TextSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)?"Y":"N")); - astman_append(s, "SIP-Sess-Timers: %s\r\n", stmode2str(peer->st_mode_oper)); - astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresher2str(peer->st_ref)); - astman_append(s, "SIP-Sess-Expires: %d\r\n", peer->st_max_se); - astman_append(s, "SIP-Sess-Min: %d\r\n", peer->st_min_se); + astman_append(s, "SIP-Sess-Timers: %s\r\n", stmode2str(peer->stimer.st_mode_oper)); + astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresher2str(peer->stimer.st_ref)); + astman_append(s, "SIP-Sess-Expires: %d\r\n", peer->stimer.st_max_se); + astman_append(s, "SIP-Sess-Min: %d\r\n", peer->stimer.st_min_se); /* - is enumerated */ astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); @@ -12086,10 +12127,10 @@ print_group(a->fd, user->pickupgroup, 0); ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "")); ast_cli(a->fd, " ACL : %s\n", cli_yesno(user->ha != NULL)); - ast_cli(a->fd, " Sess-Timers : %s\n", stmode2str(user->st_mode_oper)); - ast_cli(a->fd, " Sess-Refresh : %s\n", strefresher2str(user->st_ref)); - ast_cli(a->fd, " Sess-Expires : %d secs\n", user->st_max_se); - ast_cli(a->fd, " Sess-Min-SE : %d secs\n", user->st_min_se); + ast_cli(a->fd, " Sess-Timers : %s\n", stmode2str(user->stimer.st_mode_oper)); + ast_cli(a->fd, " Sess-Refresh : %s\n", strefresher2str(user->stimer.st_ref)); + ast_cli(a->fd, " Sess-Expires : %d secs\n", user->stimer.st_max_se); + ast_cli(a->fd, " Sess-Min-SE : %d secs\n", user->stimer.st_min_se); ast_cli(a->fd, " Codec Order : ("); print_codec_to_cli(a->fd, &user->prefs); @@ -12722,18 +12763,22 @@ } else ast_cli(a->fd, "(none)\n"); - ast_cli(a->fd, " Session-Timer: %s\n", cur->st_active ? "Active" : "Inactive"); - if (cur->st_active == TRUE) { - ast_cli(a->fd, " S-Timer Interval: %d\n", cur->st_interval); - ast_cli(a->fd, " S-Timer Refresher: %s\n", strefresher2str(cur->st_ref)); - ast_cli(a->fd, " S-Timer Expirys: %d\n", cur->st_expirys); - ast_cli(a->fd, " S-Timer Sched Id: %d\n", cur->st_schedid); - ast_cli(a->fd, " S-Timer Peer Sts: %s\n", cur->st_active_peer_ua ? "Active" : "Inactive"); - ast_cli(a->fd, " S-Timer Cached Min-SE: %d\n", cur->st_cached_min_se); - ast_cli(a->fd, " S-Timer Cached SE: %d\n", cur->st_cached_max_se); - ast_cli(a->fd, " S-Timer Cached Ref: %s\n", strefresher2str(cur->st_cached_ref)); - ast_cli(a->fd, " S-Timer Cached Mode: %s\n", stmode2str(cur->st_cached_mode)); - } + if (!cur->stimer) + ast_cli(a->fd, " Session-Timer: Uninitiallized\n"); + else { + ast_cli(a->fd, " Session-Timer: %s\n", cur->stimer->st_active ? "Active" : "Inactive"); + if (cur->stimer->st_active == TRUE) { + ast_cli(a->fd, " S-Timer Interval: %d\n", cur->stimer->st_interval); + ast_cli(a->fd, " S-Timer Refresher: %s\n", strefresher2str(cur->stimer->st_ref)); + ast_cli(a->fd, " S-Timer Expirys: %d\n", cur->stimer->st_expirys); + ast_cli(a->fd, " S-Timer Sched Id: %d\n", cur->stimer->st_schedid); + ast_cli(a->fd, " S-Timer Peer Sts: %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive"); + ast_cli(a->fd, " S-Timer Cached Min-SE: %d\n", cur->stimer->st_cached_min_se); + ast_cli(a->fd, " S-Timer Cached SE: %d\n", cur->stimer->st_cached_max_se); + ast_cli(a->fd, " S-Timer Cached Ref: %s\n", strefresher2str(cur->stimer->st_cached_ref)); + ast_cli(a->fd, " S-Timer Cached Mode: %s\n", stmode2str(cur->stimer->st_cached_mode)); + } + } ast_cli(a->fd, "\n\n"); @@ -13966,19 +14011,19 @@ } if (tmp_st_ref == SESSION_TIMER_REFRESHER_UAC || tmp_st_ref == SESSION_TIMER_REFRESHER_UAS) { - p->st_ref = tmp_st_ref; + p->stimer->st_ref = tmp_st_ref; } if (tmp_st_interval) { - p->st_interval = tmp_st_interval; + p->stimer->st_interval = tmp_st_interval; } - p->st_active = TRUE; - p->st_active_peer_ua = TRUE; + p->stimer->st_active = TRUE; + p->stimer->st_active_peer_ua = TRUE; start_session_timer(p); } else { /* UAS doesn't support Session-Timers */ if (st_get_mode(p) == SESSION_TIMER_MODE_ORIGINATE) { - p->st_ref = SESSION_TIMER_REFRESHER_UAC; - p->st_active_peer_ua = FALSE; + p->stimer->st_ref = SESSION_TIMER_REFRESHER_UAC; + p->stimer->st_active_peer_ua = FALSE; start_session_timer(p); } } @@ -15738,6 +15783,10 @@ the session refresh interval and who will be the refresher */ ast_debug(2, "Incoming INVITE with 'timer' option enabled\n"); + /* Allocate Session-Timers struct w/in the dialog */ + if (!p->stimer) + sip_st_alloc(p); + /* Parse the Session-Expires header */ p_uac_se_hdr = get_header(req, "Session-Expires"); if (!ast_strlen_zero(p_uac_se_hdr)) { @@ -15779,7 +15828,7 @@ return -1; } - p->st_active_peer_ua = TRUE; + p->stimer->st_active_peer_ua = TRUE; st_active = TRUE; if (st_ref == SESSION_TIMER_REFRESHER_AUTO) { st_ref = st_get_refresher(p); @@ -15817,7 +15866,7 @@ /* The UAC did not request session-timers. Asterisk (UAS), will now decide (based on session-timer-mode in sip.conf) whether to run session-timers for this session or not. */ - p->st_active_peer_ua = FALSE; + p->stimer->st_active_peer_ua = FALSE; switch (st_get_mode(p)) { case SESSION_TIMER_MODE_ORIGINATE: st_active = TRUE; @@ -15833,13 +15882,13 @@ if (reinvite == 0) { /* Session-Timers: Start session refresh timer based on negotiation/config */ if (st_active == TRUE) { - p->st_active = TRUE; - p->st_interval = st_interval; - p->st_ref = st_ref; + p->stimer->st_active = TRUE; + p->stimer->st_interval = st_interval; + p->stimer->st_ref = st_ref; start_session_timer(p); } } else { - if (p->st_active == TRUE) { + if (p->stimer->st_active == TRUE) { /* Session-Timers: A re-invite request sent within a dialog will serve as a refresh request, no matter whether the re-invite was sent for refreshing the session or modifying it.*/ @@ -15847,13 +15896,13 @@ /* The UAC may be adjusting the session-timers mid-session */ if (st_interval > 0) { - p->st_interval = st_interval; - p->st_ref = st_ref; + p->stimer->st_interval = st_interval; + p->stimer->st_ref = st_ref; } restart_session_timer(p); - if (p->st_expirys > 0) { - p->st_expirys--; + if (p->stimer->st_expirys > 0) { + p->stimer->st_expirys--; } } } @@ -17647,12 +17696,17 @@ /*! \brief Session-Timers: Restart session timer */ static void restart_session_timer(struct sip_pvt *p) { - if (p->st_active == TRUE) { - if (ast_sched_del(sched, p->st_schedid) != 0) { - ast_log(LOG_WARNING, "ast_sched_del failed: %d - %s\n", p->st_schedid, p->callid); + if (!p->stimer) { + ast_log(LOG_WARNING, "Null stimer in restart_session_timer - %s\n", p->callid); + return; + } + + if (p->stimer->st_active == TRUE) { + if (ast_sched_del(sched, p->stimer->st_schedid) != 0) { + ast_log(LOG_WARNING, "ast_sched_del failed: %d - %s\n", p->stimer->st_schedid, p->callid); } - ast_debug(2, "Session timer stopped: %d - %s\n", p->st_schedid, p->callid); + ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); start_session_timer(p); } } @@ -17661,22 +17715,32 @@ /*! \brief Session-Timers: Stop session timer */ static void stop_session_timer(struct sip_pvt *p) { - if (p->st_active == TRUE) { - p->st_active = FALSE; - ast_sched_del(sched, p->st_schedid); - ast_debug(2, "Session timer stopped: %d - %s\n", p->st_schedid, p->callid); + if (!p->stimer) { + ast_log(LOG_WARNING, "Null stimer in stop_session_timer - %s\n", p->callid); + return; } + + if (p->stimer->st_active == TRUE) { + p->stimer->st_active = FALSE; + ast_sched_del(sched, p->stimer->st_schedid); + ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); + } } /*! \brief Session-Timers: Start session timer */ static void start_session_timer(struct sip_pvt *p) { - p->st_schedid = ast_sched_add(sched, p->st_interval * 1000 / 2, proc_session_timer, p); - if (p->st_schedid < 0) { + if (!p->stimer) { + ast_log(LOG_WARNING, "Null stimer in start_session_timer - %s\n", p->callid); + return; + } + + p->stimer->st_schedid = ast_sched_add(sched, p->stimer->st_interval * 1000 / 2, proc_session_timer, p); + if (p->stimer->st_schedid < 0) { ast_log(LOG_ERROR, "ast_sched_add failed.\n"); } - ast_debug(2, "Session timer started: %d - %s\n", p->st_schedid, p->callid); + ast_debug(2, "Session timer started: %d - %s\n", p->stimer->st_schedid, p->callid); } @@ -17686,20 +17750,25 @@ struct sip_pvt *p = (struct sip_pvt *) vp; int sendreinv = FALSE; - ast_debug(2, "Session timer expired: %d - %s\n", p->st_schedid, p->callid); + if (!p->stimer) { + ast_log(LOG_WARNING, "Null stimer in proc_session_timer - %s\n", p->callid); + return; + } + ast_debug(2, "Session timer expired: %d - %s\n", p->stimer->st_schedid, p->callid); + if (!p->owner) { - if (p->st_active == TRUE) { + if (p->stimer->st_active == TRUE) { stop_session_timer(p); } return 0; } - if ((p->st_active != TRUE) || (p->owner->_state != AST_STATE_UP)) { + if ((p->stimer->st_active != TRUE) || (p->owner->_state != AST_STATE_UP)) { return 0; } - switch (p->st_ref) { + switch (p->stimer->st_ref) { case SESSION_TIMER_REFRESHER_UAC: if (p->outgoing_call == TRUE) { sendreinv = TRUE; @@ -17713,15 +17782,15 @@ break; default: - ast_log(LOG_ERROR, "Unknown session refresher %d\n", p->st_ref); + ast_log(LOG_ERROR, "Unknown session refresher %d\n", p->stimer->st_ref); return -1; } if (sendreinv == TRUE) { transmit_reinvite_with_sdp(p, FALSE, TRUE); } else { - p->st_expirys++; - if (p->st_expirys >= 2) { + p->stimer->st_expirys++; + if (p->stimer->st_expirys >= 2) { ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid); stop_session_timer(p); @@ -17833,7 +17902,7 @@ ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval); return; } - p->st_interval = minse; + p->stimer->st_interval = minse; transmit_invite(p, SIP_INVITE, 1, 2); } @@ -17844,47 +17913,47 @@ int st_get_se(struct sip_pvt *p, int max) { if (max == TRUE) { - if (p->st_cached_max_se) { - return p->st_cached_max_se; + if (p->stimer->st_cached_max_se) { + return p->stimer->st_cached_max_se; } else { if (p->username) { struct sip_user *up = find_user(p->username, 1); if (up) { - p->st_cached_max_se = up->st_max_se; - return (p->st_cached_max_se); + p->stimer->st_cached_max_se = up->stimer.st_max_se; + return (p->stimer->st_cached_max_se); } } if (p->peername) { struct sip_peer *pp = find_peer(p->peername, NULL, 1); if (pp) { - p->st_cached_max_se = pp->st_max_se; - return (p->st_cached_max_se); + p->stimer->st_cached_max_se = pp->stimer.st_max_se; + return (p->stimer->st_cached_max_se); } } } - p->st_cached_max_se = global_max_se; - return (p->st_cached_max_se); + p->stimer->st_cached_max_se = global_max_se; + return (p->stimer->st_cached_max_se); } else { - if (p->st_cached_min_se) { - return p->st_cached_min_se; + if (p->stimer->st_cached_min_se) { + return p->stimer->st_cached_min_se; } else { if (p->username) { struct sip_user *up = find_user(p->username, 1); if (up) { - p->st_cached_min_se = up->st_min_se; - return (p->st_cached_min_se); + p->stimer->st_cached_min_se = up->stimer.st_min_se; + return (p->stimer->st_cached_min_se); } } if (p->peername) { struct sip_peer *pp = find_peer(p->peername, NULL, 1); if (pp) { - p->st_cached_min_se = pp->st_min_se; - return (p->st_cached_min_se); + p->stimer->st_cached_min_se = pp->stimer.st_min_se; + return (p->stimer->st_cached_min_se); } } } - p->st_cached_min_se = global_min_se; - return (p->st_cached_min_se); + p->stimer->st_cached_min_se = global_min_se; + return (p->stimer->st_cached_min_se); } } @@ -17894,26 +17963,26 @@ */ enum st_refresher st_get_refresher(struct sip_pvt *p) { - if (p->st_cached_ref != SESSION_TIMER_REFRESHER_AUTO) - return p->st_cached_ref; + if (p->stimer->st_cached_ref != SESSION_TIMER_REFRESHER_AUTO) + return p->stimer->st_cached_ref; if (p->username) { struct sip_user *up = find_user(p->username, 1); if (up) { - p->st_cached_ref = up->st_ref; - return up->st_ref; + p->stimer->st_cached_ref = up->stimer.st_ref; + return up->stimer.st_ref; } } if (p->peername) { struct sip_peer *pp = find_peer(p->peername, NULL, 1); if (pp) { - p->st_cached_ref = pp->st_ref; - return pp->st_ref; + p->stimer->st_cached_ref = pp->stimer.st_ref; + return pp->stimer.st_ref; } } - p->st_cached_ref = global_st_refresher; + p->stimer->st_cached_ref = global_st_refresher; return global_st_refresher; } @@ -17923,25 +17992,28 @@ */ enum st_mode st_get_mode(struct sip_pvt *p) { - if (p->st_cached_mode != SESSION_TIMER_MODE_INVALID) - return p->st_cached_mode; + if (!p->stimer) + sip_st_alloc(p); + if (p->stimer->st_cached_mode != SESSION_TIMER_MODE_INVALID) + return p->stimer->st_cached_mode; + if (p->username) { struct sip_user *up = find_user(p->username, 1); if (up) { - p->st_cached_mode = up->st_mode_oper; - return up->st_mode_oper; + p->stimer->st_cached_mode = up->stimer.st_mode_oper; + return up->stimer.st_mode_oper; } } if (p->peername) { struct sip_peer *pp = find_peer(p->peername, NULL, 1); if (pp) { - p->st_cached_mode = pp->st_mode_oper; - return pp->st_mode_oper; + p->stimer->st_cached_mode = pp->stimer.st_mode_oper; + return pp->stimer.st_mode_oper; } } - p->st_cached_mode = global_st_mode; + p->stimer->st_cached_mode = global_st_mode; return global_st_mode; } @@ -18593,10 +18665,10 @@ if (global_callcounter) user->call_limit=999; user->prefs = default_prefs; - user->st_mode_oper = global_st_mode; /* Session-Timers */ - user->st_ref = global_st_refresher; - user->st_min_se = global_min_se; - user->st_max_se = global_max_se; + user->stimer.st_mode_oper = global_st_mode; /* Session-Timers */ + user->stimer.st_ref = global_st_refresher; + user->stimer.st_min_se = global_min_se; + user->stimer.st_max_se = global_max_se; /* set default context */ strcpy(user->context, default_context); @@ -18679,31 +18751,31 @@ int i = (int) str2stmode(v->value); if (i < 0) { ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); - user->st_mode_oper = global_st_mode; + user->stimer.st_mode_oper = global_st_mode; } else { - user->st_mode_oper = i; + user->stimer.st_mode_oper = i; } } else if (!strcasecmp(v->name, "session-expires")) { - if (sscanf(v->value, "%d", &user->st_max_se) != 1) { + if (sscanf(v->value, "%d", &user->stimer.st_max_se) != 1) { ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); - user->st_max_se = global_max_se; + user->stimer.st_max_se = global_max_se; } } else if (!strcasecmp(v->name, "session-minse")) { - if (sscanf(v->value, "%d", &user->st_min_se) != 1) { + if (sscanf(v->value, "%d", &user->stimer.st_min_se) != 1) { ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); - user->st_min_se = global_min_se; + user->stimer.st_min_se = global_min_se; } - if (user->st_min_se < 90) { + if (user->stimer.st_min_se < 90) { ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < 90 secs\n", v->value, v->lineno, config); - user->st_min_se = global_min_se; + user->stimer.st_min_se = global_min_se; } } else if (!strcasecmp(v->name, "session-refresher")) { int i = (int) str2strefresher(v->value); if (i < 0) { ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); - user->st_ref = global_st_refresher; + user->stimer.st_ref = global_st_refresher; } else { - user->st_ref = i; + user->stimer.st_ref = i; } } @@ -18760,10 +18832,10 @@ peer->pickupgroup = 0; peer->maxms = default_qualify; peer->prefs = default_prefs; - peer->st_mode_oper = global_st_mode; /* Session-Timers */ - peer->st_ref = global_st_refresher; - peer->st_min_se = global_min_se; - peer->st_max_se = global_max_se; + peer->stimer.st_mode_oper = global_st_mode; /* Session-Timers */ + peer->stimer.st_ref = global_st_refresher; + peer->stimer.st_min_se = global_min_se; + peer->stimer.st_max_se = global_max_se; peer->timer_t1 = global_t1; peer->timer_b = global_timer_b; @@ -19071,31 +19143,31 @@ int i = (int) str2stmode(v->value); if (i < 0) { ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); - peer->st_mode_oper = global_st_mode; + peer->stimer.st_mode_oper = global_st_mode; } else { - peer->st_mode_oper = i; + peer->stimer.st_mode_oper = i; } } else if (!strcasecmp(v->name, "session-expires")) { - if (sscanf(v->value, "%d", &peer->st_max_se) != 1) { + if (sscanf(v->value, "%d", &peer->stimer.st_max_se) != 1) { ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); - peer->st_max_se = global_max_se; + peer->stimer.st_max_se = global_max_se; } } else if (!strcasecmp(v->name, "session-minse")) { - if (sscanf(v->value, "%d", &peer->st_min_se) != 1) { + if (sscanf(v->value, "%d", &peer->stimer.st_min_se) != 1) { ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); - peer->st_min_se = global_min_se; + peer->stimer.st_min_se = global_min_se; } - if (peer->st_min_se < 90) { + if (peer->stimer.st_min_se < 90) { ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < 90 secs\n", v->value, v->lineno, config); - peer->st_min_se = global_min_se; + peer->stimer.st_min_se = global_min_se; } } else if (!strcasecmp(v->name, "session-refresher")) { int i = (int) str2strefresher(v->value); if (i < 0) { ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); - peer->st_ref = global_st_refresher; + peer->stimer.st_ref = global_st_refresher; } else { - peer->st_ref = i; + peer->stimer.st_ref = i; } } }