diff options
-rw-r--r-- | main/cli.c | 6 | ||||
-rw-r--r-- | res/res_format_attr_h264.c | 16 | ||||
-rw-r--r-- | res/res_pjsip_outbound_registration.c | 36 | ||||
-rw-r--r-- | res/res_pjsip_t38.c | 14 |
4 files changed, 56 insertions, 16 deletions
diff --git a/main/cli.c b/main/cli.c index 0d66f3e48..7f86eab3a 100644 --- a/main/cli.c +++ b/main/cli.c @@ -1076,10 +1076,12 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar char locbuf[40] = "(None)"; char appdata[40] = "(None)"; - if (!cs->context && !cs->exten) + if (!ast_strlen_zero(cs->context) && !ast_strlen_zero(cs->exten)) { snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", cs->exten, cs->context, cs->priority); - if (cs->appl) + } + if (!ast_strlen_zero(cs->appl)) { snprintf(appdata, sizeof(appdata), "%s(%s)", cs->appl, S_OR(cs->data, "")); + } ast_cli(a->fd, FORMAT_STRING, cs->name, locbuf, ast_state2str(cs->state), appdata); } } diff --git a/res/res_format_attr_h264.c b/res/res_format_attr_h264.c index d263a556f..34793ef6b 100644 --- a/res/res_format_attr_h264.c +++ b/res/res_format_attr_h264.c @@ -236,7 +236,7 @@ static struct ast_format *h264_parse_sdp_fmtp(const struct ast_format *format, c if (field != H264_ATTR_KEY_UNSET) { \ if (added) { \ ast_str_append(str, 0, ";"); \ - } else { \ + } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) { \ added = 1; \ } \ ast_str_append(str, 0, "%s=%u", name, field); \ @@ -247,7 +247,7 @@ static struct ast_format *h264_parse_sdp_fmtp(const struct ast_format *format, c if (field) { \ if (added) { \ ast_str_append(str, 0, ";"); \ - } else { \ + } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) { \ added = 1; \ } \ ast_str_append(str, 0, "%s=%u", name, field); \ @@ -263,8 +263,6 @@ static void h264_generate_sdp_fmtp(const struct ast_format *format, unsigned int return; } - ast_str_append(str, 0, "a=fmtp:%u ", payload); - APPEND_IF_NONZERO(attr->MAX_MBPS, str, "max-mbps"); APPEND_IF_NONZERO(attr->MAX_FS, str, "max-fs"); APPEND_IF_NONZERO(attr->MAX_CPB, str, "max-cpb"); @@ -287,7 +285,7 @@ static void h264_generate_sdp_fmtp(const struct ast_format *format, unsigned int if (attr->PROFILE_IDC && attr->PROFILE_IOP && attr->LEVEL) { if (added) { ast_str_append(str, 0, ";"); - } else { + } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) { added = 1; } ast_str_append(str, 0, "profile-level-id=%02X%02X%02X", attr->PROFILE_IDC, attr->PROFILE_IOP, attr->LEVEL); @@ -296,15 +294,13 @@ static void h264_generate_sdp_fmtp(const struct ast_format *format, unsigned int if (!ast_strlen_zero(attr->SPS) && !ast_strlen_zero(attr->PPS)) { if (added) { ast_str_append(str, 0, ";"); - } else { + } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) { added = 1; } - ast_str_append(str, 0, ";sprop-parameter-sets=%s,%s", attr->SPS, attr->PPS); + ast_str_append(str, 0, "sprop-parameter-sets=%s,%s", attr->SPS, attr->PPS); } - if (!added) { - ast_str_reset(*str); - } else { + if (added) { ast_str_append(str, 0, "\r\n"); } diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c index 22657ecd6..6f3155d8b 100644 --- a/res/res_pjsip_outbound_registration.c +++ b/res/res_pjsip_outbound_registration.c @@ -336,6 +336,8 @@ struct sip_outbound_registration_client_state { unsigned int auth_rejection_permanent; /*! \brief Determines whether SIP Path support should be advertised */ unsigned int support_path; + /*! CSeq number of last sent auth request. */ + unsigned int auth_cseq; /*! \brief Serializer for stuff and things */ struct ast_taskprocessor *serializer; /*! \brief Configured authentication credentials */ @@ -772,15 +774,27 @@ static int handle_registration_response(void *data) ast_debug(1, "Processing REGISTER response %d from server '%s' for client '%s'\n", response->code, server_uri, client_uri); - if (!response->client_state->auth_attempted && - (response->code == 401 || response->code == 407)) { + if ((response->code == 401 || response->code == 407) + && (!response->client_state->auth_attempted + || response->rdata->msg_info.cseq->cseq != response->client_state->auth_cseq)) { + int res; + pjsip_cseq_hdr *cseq_hdr; pjsip_tx_data *tdata; + if (!ast_sip_create_request_with_auth_from_old(&response->client_state->outbound_auths, response->rdata, response->old_request, &tdata)) { response->client_state->auth_attempted = 1; ast_debug(1, "Sending authenticated REGISTER to server '%s' from client '%s'\n", server_uri, client_uri); - if (registration_client_send(response->client_state, tdata) == PJ_SUCCESS) { + pjsip_tx_data_add_ref(tdata); + res = registration_client_send(response->client_state, tdata); + + /* Save the cseq that actually got sent. */ + cseq_hdr = (pjsip_cseq_hdr *) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, + NULL); + response->client_state->auth_cseq = cseq_hdr->cseq; + pjsip_tx_data_dec_ref(tdata); + if (res == PJ_SUCCESS) { ao2_ref(response, -1); return 0; } @@ -796,11 +810,18 @@ static int handle_registration_response(void *data) if (PJSIP_IS_STATUS_IN_CLASS(response->code, 200)) { /* Check if this is in regards to registering or unregistering */ if (response->expiration) { + int next_registration_round; + /* If the registration went fine simply reschedule registration for the future */ ast_debug(1, "Outbound registration to '%s' with client '%s' successful\n", server_uri, client_uri); update_client_state_status(response->client_state, SIP_REGISTRATION_REGISTERED); response->client_state->retries = 0; - schedule_registration(response->client_state, response->expiration - REREGISTER_BUFFER_TIME); + next_registration_round = response->expiration - REREGISTER_BUFFER_TIME; + if (next_registration_round < 0) { + /* Re-register immediately. */ + next_registration_round = 0; + } + schedule_registration(response->client_state, next_registration_round); } else { ast_debug(1, "Outbound unregistration to '%s' with client '%s' successful\n", server_uri, client_uri); update_client_state_status(response->client_state, SIP_REGISTRATION_UNREGISTERED); @@ -1867,6 +1888,13 @@ static void registration_loaded_observer(const char *name, const struct ast_sorc return; } + /* + * Refresh the current configured registrations. We don't need to hold + * onto the objects, as the apply handler will cause their states to + * be created appropriately. + */ + ao2_cleanup(get_registrations()); + /* Now to purge dead registrations. */ ao2_callback(states, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, check_state, NULL); ao2_ref(states, -1); diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c index c867f7f21..0db2e5c37 100644 --- a/res/res_pjsip_t38.c +++ b/res/res_pjsip_t38.c @@ -264,6 +264,7 @@ static int t38_initialize_session(struct ast_sip_session *session, struct ast_si ast_udptl_set_error_correction_scheme(session_media->udptl, session->endpoint->media.t38.error_correction); ast_udptl_setnat(session_media->udptl, session->endpoint->media.t38.nat); ast_udptl_set_far_max_datagram(session_media->udptl, session->endpoint->media.t38.maxdatagram); + ast_debug(3, "UDPTL initialized on session for %s\n", ast_channel_name(session->channel)); return 0; } @@ -630,10 +631,12 @@ static enum ast_sip_session_sdp_stream_defer defer_incoming_sdp_stream( struct t38_state *state; if (!session->endpoint->media.t38.enabled) { + ast_debug(3, "Not deferring incoming SDP stream: T.38 not enabled on %s\n", ast_channel_name(session->channel)); return AST_SIP_SESSION_SDP_DEFER_NOT_HANDLED; } if (t38_initialize_session(session, session_media)) { + ast_debug(3, "Not deferring incoming SDP stream: Failed to initialize UDPTL on %s\n", ast_channel_name(session->channel)); return AST_SIP_SESSION_SDP_DEFER_ERROR; } @@ -646,6 +649,7 @@ static enum ast_sip_session_sdp_stream_defer defer_incoming_sdp_stream( /* If they are initiating the re-invite we need to defer responding until later */ if (session->t38state == T38_DISABLED) { t38_change_state(session, session_media, state, T38_PEER_REINVITE); + ast_debug(3, "Deferring incoming SDP stream on %s for peer re-invite\n", ast_channel_name(session->channel)); return AST_SIP_SESSION_SDP_DEFER_NEEDED; } @@ -661,6 +665,7 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free); if (!session->endpoint->media.t38.enabled) { + ast_debug(3, "Declining; T.38 not enabled on session\n"); return -1; } @@ -669,6 +674,7 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct } if ((session->t38state == T38_REJECTED) || (session->t38state == T38_DISABLED)) { + ast_debug(3, "Declining; T.38 state is rejected or declined\n"); t38_change_state(session, session_media, state, T38_DISABLED); return -1; } @@ -678,6 +684,7 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct /* Ensure that the address provided is valid */ if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_INET) <= 0) { /* The provided host was actually invalid so we error out this negotiation */ + ast_debug(3, "Declining; provided host is invalid\n"); return -1; } @@ -685,6 +692,7 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct if ((ast_sockaddr_is_ipv6(addrs) && !session->endpoint->media.t38.ipv6) || (ast_sockaddr_is_ipv4(addrs) && session->endpoint->media.t38.ipv6)) { /* The address does not match configured */ + ast_debug(3, "Declining, provided host does not match configured address family\n"); return -1; } @@ -713,13 +721,16 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as pj_str_t stmp; if (!session->endpoint->media.t38.enabled) { + ast_debug(3, "Not creating outgoing SDP stream: T.38 not enabled\n"); return 1; } else if ((session->t38state != T38_LOCAL_REINVITE) && (session->t38state != T38_PEER_REINVITE) && (session->t38state != T38_ENABLED)) { + ast_debug(3, "Not creating outgoing SDP stream: T.38 not enabled\n"); return 1; } else if (!(state = t38_state_get_or_alloc(session))) { return -1; } else if (t38_initialize_session(session, session_media)) { + ast_debug(3, "Not creating outgoing SDP stream: Failed to initialize T.38 session\n"); return -1; } @@ -738,6 +749,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as } if (ast_strlen_zero(hostip)) { + ast_debug(3, "Not creating outgoing SDP stream: no known host IP\n"); return -1; } @@ -805,6 +817,7 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct a struct t38_state *state; if (!session_media->udptl) { + ast_debug(3, "Not applying negotiated SDP stream: no UDTPL session\n"); return 0; } @@ -817,6 +830,7 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct a /* Ensure that the address provided is valid */ if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) { /* The provided host was actually invalid so we error out this negotiation */ + ast_debug(3, "Not applying negotiated SDP stream: failed to resolve remote stream host\n"); return -1; } |