diff --git a/daemon/call.c b/daemon/call.c index 8f97202d9..8d68c9732 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -2618,29 +2618,8 @@ static void __call_monologue_init_from_flags(struct call_monologue *ml, sdp_ng_f /* consume sdp session parts */ { /* origin (name, version etc.) */ - /* TODO: rework the whole SDP origin into one structure */ - if (!ml->sdp_username && flags->session_sdp_orig.username.len) - { - ml->sdp_username = call_strdup_len(call, flags->session_sdp_orig.username.s, - flags->session_sdp_orig.username.len); - } - if (!ml->sdp_session_id && flags->session_sdp_orig.session_id.len) - { - ml->sdp_session_id = str_to_ui(&flags->session_sdp_orig.session_id, 0); - } - if (!ml->sdp_origin_ip && flags->session_sdp_orig.address.address.len) - { - ml->sdp_origin_ip = call_strdup_len(call, flags->session_sdp_orig.address.address.s, - flags->session_sdp_orig.address.address.len); - } - if (!ml->sdp_origin_ip_family && flags->session_sdp_orig.address.address_type.len) - { - ml->sdp_origin_ip_family = call_strdup_len(call, flags->session_sdp_orig.address.address_type.s, - flags->session_sdp_orig.address.address_type.len); - } - ml->sdp_version = flags->session_sdp_orig.version_num; - if (ml->sdp_version == ULLONG_MAX) - ml->sdp_version = (unsigned int)ssl_random(); + if (!ml->session_sdp_orig && flags->session_sdp_orig.parsed) + ml->session_sdp_orig = sdp_orig_dup(&flags->session_sdp_orig); /* sdp session name */ if (flags->session_sdp_name.len && (!ml->sdp_session_name || /* if not set yet */ @@ -3988,6 +3967,8 @@ void __monologue_free(struct call_monologue *m) { if (m->last_out_sdp) g_string_free(m->last_out_sdp, TRUE); str_free_dup(&m->last_in_sdp); + if (m->session_sdp_orig) + sdp_orig_free(m->session_sdp_orig); sdp_sessions_clear(&m->last_in_sdp_parsed); t_queue_clear_full(&m->sdp_attributes, sdp_attr_free); sdp_streams_clear(&m->last_in_sdp_streams); diff --git a/daemon/sdp.c b/daemon/sdp.c index e11e32c61..83ebadfc8 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -1784,6 +1784,33 @@ void sdp_attr_free(struct sdp_attr *c) { g_free(c); } +sdp_origin *sdp_orig_dup(const sdp_origin *orig) { + sdp_origin *copy = g_slice_alloc0(sizeof(*copy)); + str_init_dup_str(©->username, &orig->username); + str_init_dup_str(©->session_id, &orig->session_id); + str_init_dup_str(©->version_str, &orig->version_str); + copy->version_num = orig->version_num; + copy->version_output_pos = orig->version_output_pos; + copy->parsed = orig->parsed; + /* struct network_address */ + str_init_dup_str(©->address.network_type, &orig->address.network_type); + str_init_dup_str(©->address.address_type, &orig->address.address_type); + str_init_dup_str(©->address.address, &orig->address.address); + copy->address.parsed = orig->address.parsed; + + return copy; +} + +void sdp_orig_free(sdp_origin *o) { + str_free_dup(&o->username); + str_free_dup(&o->session_id); + str_free_dup(&o->version_str); + str_free_dup(&o->address.network_type); + str_free_dup(&o->address.address_type); + str_free_dup(&o->address.address); + g_slice_free1(sizeof(*o), o); +} + // Duplicate all OTHER attributes from the source (parsed SDP attributes list) into // the destination (string-format attribute list) static void sdp_attr_append_other(sdp_attr_q *dst, struct sdp_attributes *src) { @@ -3403,8 +3430,6 @@ static void sdp_out_add_origin(GString *out, struct call_monologue *monologue, struct packet_stream *first_ps, sdp_ng_flags *flags) { struct call_monologue *ml = monologue; - const char *origin_address = NULL; - const char *origin_address_type = first_ps->selected_sfd->local_intf->advertised_address.addr.family->rfc_name; /* for the offer/answer model or subscribe don't use the given monologues SDP, * but try the one of the subscription, because the given monologue itself @@ -3413,35 +3438,27 @@ static void sdp_out_add_origin(GString *out, struct call_monologue *monologue, if (ms && ms->monologue) { ml = ms->monologue; - /* by default set to what's parsed from SDP - * but only if a replacement of origin isn't requested */ - if (!flags->replace_origin) - { - if (ml->sdp_origin_ip) - origin_address = ml->sdp_origin_ip; - if (ml->sdp_origin_ip_family) - origin_address_type = ml->sdp_origin_ip_family; + /* values taken from the monologue (so parsed origin) */ + if (!flags->replace_origin && ml->session_sdp_orig->parsed) { + g_string_append_printf(out, + "o="STR_FORMAT" "STR_FORMAT" %llu IN "STR_FORMAT" "STR_FORMAT"\r\n", + STR_FMT(&ml->session_sdp_orig->username), + STR_FMT(&ml->session_sdp_orig->session_id), + ml->session_sdp_orig->version_num, + STR_FMT(&ml->session_sdp_orig->address.address_type), + STR_FMT(&ml->session_sdp_orig->address.address)); + return; } } - if (!origin_address) - /* by default for PUBLISH */ - origin_address = sockaddr_print_buf(&first_ps->selected_sfd->local_intf->advertised_address.addr); - - if (!ml->sdp_username) - ml->sdp_username = "-"; - if (!ml->sdp_session_id) - ml->sdp_session_id = (unsigned long long) rtpe_now.tv_sec << 32 | rtpe_now.tv_usec; - if (!ml->sdp_version) - ml->sdp_version = ml->sdp_session_id; - + /* default values otherwise for cases like: + * - publish + * - replace_origin flag */ + unsigned long long id = (unsigned long long) rtpe_now.tv_sec << 32 | rtpe_now.tv_usec; g_string_append_printf(out, - "o=%s %llu %llu IN %s %s\r\n", - ml->sdp_username, - ml->sdp_session_id, - ml->sdp_version, - origin_address_type, - origin_address); + "o=- %llu %llu IN %s %s\r\n", id, id, + first_ps->selected_sfd->local_intf->advertised_address.addr.family->rfc_name, + sockaddr_print_buf(&first_ps->selected_sfd->local_intf->advertised_address.addr)); } static void sdp_out_add_session_name(GString *out, struct call_monologue *monologue, diff --git a/include/call.h b/include/call.h index bd52fa6d5..949362ccc 100644 --- a/include/call.h +++ b/include/call.h @@ -334,7 +334,6 @@ struct janus_session; struct audio_player; struct media_subscription; - typedef bencode_buffer_t call_buffer_t; #define call_buffer_alloc bencode_buffer_alloc #define call_buffer_init bencode_buffer_init @@ -614,6 +613,9 @@ struct call_monologue { char *sdp_username; /* sdp origin session name */ char *sdp_origin_ip; /* sdp origin ip */ char *sdp_origin_ip_family; /* sdp origin ip family */ + + sdp_origin * session_sdp_orig; /* whole o= line in a structure */ + char *sdp_session_name; char *sdp_session_timing; struct ssrc_hash *ssrc_hash; diff --git a/include/call_interfaces.h b/include/call_interfaces.h index 3869e4e52..e56c20dca 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -73,6 +73,7 @@ struct sdp_ng_flags { sdp_attr_q session_attributes; // top-level (not part of an m= section) SDP session attributes sdp_origin session_sdp_orig; str session_sdp_name; + str session_timing; /* t= line */ int session_rr, session_rs; /* b= bandwidth per session level */ diff --git a/include/sdp.h b/include/sdp.h index c66bdff23..511e852c3 100644 --- a/include/sdp.h +++ b/include/sdp.h @@ -44,23 +44,6 @@ struct sdp_attr { enum sdp_attr_type type; }; -struct network_address { - str network_type; - str address_type; - str address; - sockaddr_t parsed; -}; - -struct sdp_origin { - str username; - str session_id; - str version_str; - struct network_address address; - unsigned long long version_num; - size_t version_output_pos; - unsigned int parsed:1; -}; - extern const str rtpe_instance_id; void sdp_init(void); @@ -74,6 +57,8 @@ void sdp_append_str_attr(GString *s, const sdp_ng_flags *flags, enum media_type #define sdp_append_attr(s, g, t, n, f, ...) sdp_append_str_attr(s, g, t, &STR_INIT(n), f, ##__VA_ARGS__) void sdp_attr_free(struct sdp_attr *); +sdp_origin *sdp_orig_dup(const sdp_origin *orig); +void sdp_orig_free(sdp_origin *o); int sdp_parse(str *body, sdp_sessions_q *sessions, const sdp_ng_flags *); int sdp_streams(const sdp_sessions_q *sessions, sdp_streams_q *streams, sdp_ng_flags *); diff --git a/include/types.h b/include/types.h index 5ad8207a2..53bcb12c1 100644 --- a/include/types.h +++ b/include/types.h @@ -2,6 +2,7 @@ #define __TYPES__H__ #include +#include "socket.h" typedef struct sdp_ng_flags sdp_ng_flags; typedef struct stats_metric stats_metric; @@ -11,6 +12,24 @@ typedef struct stream_fd stream_fd; typedef struct rtp_payload_type rtp_payload_type; typedef struct sdp_origin sdp_origin; +struct network_address { + str network_type; + str address_type; + str address; + sockaddr_t parsed; +}; + +struct sdp_origin { + str username; + str session_id; + str version_str; + struct network_address address; + unsigned long long version_num; + size_t version_output_pos; + unsigned int parsed:1; +}; +typedef struct sdp_origin sdp_origin; + union sdp_attr_print_arg { struct call_media *cm; struct call_monologue *ml; diff --git a/t/auto-daemon-tests-pubsub.pl b/t/auto-daemon-tests-pubsub.pl index 511799640..04a4fd5d9 100755 --- a/t/auto-daemon-tests-pubsub.pl +++ b/t/auto-daemon-tests-pubsub.pl @@ -67,7 +67,7 @@ SDP ($port_b) = answer('SIPREC pause/resume', { }, < ft(), flags => ['SIPREC', 'replace-origin'] }, < ft(), flags => ['SIPREC'] }, < ['allow asymmetric codecs']}, < [qw/SIPREC all/]}, <