Skip to content
This repository has been archived by the owner on Jul 12, 2023. It is now read-only.

Add externalIPv4/externalIPv6 configs and API methods for them #27

Merged
merged 4 commits into from
Sep 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion src/gst-plugins/webrtcendpoint/kmswebrtcendpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ G_DEFINE_TYPE (KmsWebrtcEndpoint, kms_webrtc_endpoint,
#define DEFAULT_PEM_CERTIFICATE NULL
#define DEFAULT_NETWORK_INTERFACES NULL
#define DEFAULT_EXTERNAL_ADDRESS NULL
#define DEFAULT_EXTERNAL_IPV4 NULL
#define DEFAULT_EXTERNAL_IPV6 NULL

enum
{
Expand All @@ -66,6 +68,8 @@ enum
PROP_PEM_CERTIFICATE,
PROP_NETWORK_INTERFACES,
PROP_EXTERNAL_ADDRESS,
PROP_EXTERNAL_IPV4,
PROP_EXTERNAL_IPV6,
N_PROPERTIES
};

Expand Down Expand Up @@ -99,6 +103,8 @@ struct _KmsWebrtcEndpointPrivate
gchar *pem_certificate;
gchar *network_interfaces;
gchar *external_address;
gchar *external_ipv4;
gchar *external_ipv6;
};

/* Internal session management begin */
Expand Down Expand Up @@ -329,13 +335,19 @@ kms_webrtc_endpoint_create_session_internal (KmsBaseSdpEndpoint * base_sdp,
webrtc_sess, "network-interfaces", G_BINDING_DEFAULT);
g_object_bind_property (self, "external-address",
webrtc_sess, "external-address", G_BINDING_DEFAULT);
g_object_bind_property (self, "external-ipv4",
webrtc_sess, "external-ipv4", G_BINDING_DEFAULT);
g_object_bind_property (self, "external-ipv6",
webrtc_sess, "external-ipv6", G_BINDING_DEFAULT);

g_object_set (webrtc_sess, "stun-server", self->priv->stun_server_ip,
"stun-server-port", self->priv->stun_server_port,
"turn-url", self->priv->turn_url,
"pem-certificate", self->priv->pem_certificate,
"network-interfaces", self->priv->network_interfaces,
"external-address", self->priv->external_address, NULL);
"external-address", self->priv->external_address,
"external-ipv4", self->priv->external_ipv4,
"external-ipv6", self->priv->external_ipv6, NULL);

g_signal_connect (webrtc_sess, "on-ice-candidate",
G_CALLBACK (on_ice_candidate), self);
Expand Down Expand Up @@ -511,6 +523,14 @@ kms_webrtc_endpoint_set_property (GObject * object, guint prop_id,
g_free (self->priv->external_address);
self->priv->external_address = g_value_dup_string (value);
break;
case PROP_EXTERNAL_IPV4:
g_free (self->priv->external_ipv4);
self->priv->external_ipv4 = g_value_dup_string (value);
break;
case PROP_EXTERNAL_IPV6:
g_free (self->priv->external_ipv6);
self->priv->external_ipv6 = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
Expand Down Expand Up @@ -546,6 +566,12 @@ kms_webrtc_endpoint_get_property (GObject * object, guint prop_id,
case PROP_EXTERNAL_ADDRESS:
g_value_set_string (value, self->priv->external_address);
break;
case PROP_EXTERNAL_IPV4:
g_value_set_string (value, self->priv->external_ipv4);
break;
case PROP_EXTERNAL_IPV6:
g_value_set_string (value, self->priv->external_ipv6);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
Expand Down Expand Up @@ -583,6 +609,8 @@ kms_webrtc_endpoint_finalize (GObject * object)
g_free (self->priv->pem_certificate);
g_free (self->priv->network_interfaces);
g_free (self->priv->external_address);
g_free (self->priv->external_ipv4);
g_free (self->priv->external_ipv6);

g_main_context_unref (self->priv->context);

Expand Down Expand Up @@ -771,6 +799,18 @@ kms_webrtc_endpoint_class_init (KmsWebrtcEndpointClass * klass)
"External (public) IP address of the media server",
DEFAULT_EXTERNAL_ADDRESS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

g_object_class_install_property (gobject_class, PROP_EXTERNAL_IPV4,
g_param_spec_string ("external-ipv4",
"externalIPv4",
"External (public) IPv4 address of the media server",
DEFAULT_EXTERNAL_IPV4, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

g_object_class_install_property (gobject_class, PROP_EXTERNAL_IPV6,
g_param_spec_string ("external-ipv6",
"externalIPv6",
"External (public) IPv6 address of the media server",
DEFAULT_EXTERNAL_IPV6, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

/**
* KmsWebrtcEndpoint::on-ice-candidate:
* @self: the object which received the signal
Expand Down Expand Up @@ -905,6 +945,8 @@ kms_webrtc_endpoint_init (KmsWebrtcEndpoint * self)
self->priv->pem_certificate = DEFAULT_PEM_CERTIFICATE;
self->priv->network_interfaces = DEFAULT_NETWORK_INTERFACES;
self->priv->external_address = DEFAULT_EXTERNAL_ADDRESS;
self->priv->external_ipv4 = DEFAULT_EXTERNAL_IPV4;
self->priv->external_ipv6 = DEFAULT_EXTERNAL_IPV6;

self->priv->loop = kms_loop_new ();
g_object_get (self->priv->loop, "context", &self->priv->context, NULL);
Expand Down
47 changes: 46 additions & 1 deletion src/gst-plugins/webrtcendpoint/kmswebrtcsession.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ G_DEFINE_TYPE (KmsWebrtcSession, kms_webrtc_session, KMS_TYPE_BASE_RTP_SESSION);
#define DEFAULT_PEM_CERTIFICATE NULL
#define DEFAULT_NETWORK_INTERFACES NULL
#define DEFAULT_EXTERNAL_ADDRESS NULL
#define DEFAULT_EXTERNAL_IPV4 NULL
#define DEFAULT_EXTERNAL_IPV6 NULL

#define IP_VERSION_6 6

Expand Down Expand Up @@ -90,6 +92,8 @@ enum
PROP_PEM_CERTIFICATE,
PROP_NETWORK_INTERFACES,
PROP_EXTERNAL_ADDRESS,
PROP_EXTERNAL_IPV4,
PROP_EXTERNAL_IPV6,
N_PROPERTIES
};

Expand Down Expand Up @@ -583,12 +587,23 @@ kms_webrtc_session_new_candidate (KmsIceBaseAgent * agent,
kms_ice_candidate_get_stream_id (candidate),
kms_ice_candidate_get_component (candidate));

gboolean is_candidate_ipv6 = kms_ice_candidate_get_ip_version (candidate) == IP_VERSION_6;

if (self->external_address != NULL) {
kms_ice_candidate_set_address (candidate, self->external_address);

GST_DEBUG_OBJECT (self,
"[IceCandidateFound] Mangled local: '%s'",
kms_ice_candidate_get_candidate (candidate));
} else if (self->external_ipv4 != NULL && is_candidate_ipv6 == FALSE) {
kms_ice_candidate_set_address (candidate, self->external_ipv4);
GST_DEBUG_OBJECT (self,
"[IceCandidateFound] Mangled local candidate with IPv4: '%s'",
kms_ice_candidate_get_candidate (candidate));
} else if (self->external_ipv6 != NULL && is_candidate_ipv6 == TRUE) {
kms_ice_candidate_set_address (candidate, self->external_ipv6);
GST_DEBUG_OBJECT (self,
"[IceCandidateFound] Mangled local candidate with IPv6: '%s'",
kms_ice_candidate_get_candidate (candidate));
}

kms_webrtc_session_sdp_msg_add_ice_candidate (self, candidate);
Expand Down Expand Up @@ -1733,6 +1748,14 @@ kms_webrtc_session_set_property (GObject * object, guint prop_id,
g_free (self->external_address);
self->external_address = g_value_dup_string (value);
break;
case PROP_EXTERNAL_IPV4:
g_free (self->external_ipv4);
self->external_ipv4 = g_value_dup_string (value);
break;
case PROP_EXTERNAL_IPV6:
g_free (self->external_ipv6);
self->external_ipv6 = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
Expand Down Expand Up @@ -1771,6 +1794,12 @@ kms_webrtc_session_get_property (GObject * object, guint prop_id,
case PROP_EXTERNAL_ADDRESS:
g_value_set_string (value, self->external_address);
break;
case PROP_EXTERNAL_IPV4:
g_value_set_string (value, self->external_ipv4);
break;
case PROP_EXTERNAL_IPV6:
g_value_set_string (value, self->external_ipv6);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
Expand Down Expand Up @@ -1798,6 +1827,8 @@ kms_webrtc_session_finalize (GObject * object)
g_free (self->pem_certificate);
g_free (self->network_interfaces);
g_free (self->external_address);
g_free (self->external_ipv4);
g_free (self->external_ipv6);

if (self->destroy_data != NULL && self->cb_data != NULL) {
self->destroy_data (self->cb_data);
Expand Down Expand Up @@ -1907,6 +1938,8 @@ kms_webrtc_session_init (KmsWebrtcSession * self)
self->pem_certificate = DEFAULT_PEM_CERTIFICATE;
self->network_interfaces = DEFAULT_NETWORK_INTERFACES;
self->external_address = DEFAULT_EXTERNAL_ADDRESS;
self->external_ipv4= DEFAULT_EXTERNAL_IPV4;
self->external_ipv6 = DEFAULT_EXTERNAL_IPV6;
self->gather_started = FALSE;

self->data_channels = g_hash_table_new_full (g_direct_hash,
Expand Down Expand Up @@ -2012,6 +2045,18 @@ kms_webrtc_session_class_init (KmsWebrtcSessionClass * klass)
"External (public) IP address of the media server",
DEFAULT_EXTERNAL_ADDRESS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

g_object_class_install_property (gobject_class, PROP_EXTERNAL_IPV4,
g_param_spec_string ("external-ipv4",
"externalIPv4",
"External (public) IPv4 address of the media server",
DEFAULT_EXTERNAL_IPV4, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

g_object_class_install_property (gobject_class, PROP_EXTERNAL_IPV6,
g_param_spec_string ("external-ipv6",
"externalIPv6",
"External (public) IPv6 address of the media server",
DEFAULT_EXTERNAL_IPV6, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

g_object_class_install_property (gobject_class, PROP_DATA_CHANNEL_SUPPORTED,
g_param_spec_boolean ("data-channel-supported",
"Data channel supported",
Expand Down
2 changes: 2 additions & 0 deletions src/gst-plugins/webrtcendpoint/kmswebrtcsession.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ struct _KmsWebrtcSession
gchar *pem_certificate;
gchar *network_interfaces;
gchar *external_address;
gchar *external_ipv4;
gchar *external_ipv6;

guint16 min_port;
guint16 max_port;
Expand Down
48 changes: 35 additions & 13 deletions src/server/config/WebRtcEndpoint.conf.ini
Original file line number Diff line number Diff line change
Expand Up @@ -80,25 +80,47 @@
;pemCertificateRSA=/path/to/cert+key.pem
;pemCertificateECDSA=/path/to/cert+key.pem

;; External IPv4 and IPv6 addresses of the media server.
;;
;; Forces all local IPv4 and/or IPv6 ICE candidates to have the given address.
;; This is really nothing more than a hack, but it's very effective to force a
;; public IP address when one is known in advance for the media server. In doing
;; so, KMS will not need a STUN or TURN server, but remote peers will still be
;; able to contact it.
;;
;; You can try using these settings if KMS is deployed on a publicly accessible
;; server, without NAT, and with a static public IP address. But if it doesn't
;; work for you, just go back to configuring a STUN or TURN server for ICE.
;;
;; Only set this parameter if you know what you're doing, and you understand
;; 100% WHY you need it. For the majority of cases, you should just prefer to
;; configure a STUN or TURN server.
;;
;; <externalIPv4> is a single IPv4 address.
;; <externalIPv6> is a single IPv6 address.
;;
;externalIPv4=198.51.100.1
;externalIPv6=2001:0db8:85a3:0000:0000:8a2e:0370:7334

;; External IP address of the media server.
;;
;; This setting is normally NOT needed. Only use it if you know what you're
;; doing, and understand 100% WHY you want it. For the majority of cases, you
;; should prefer configuring STUN or TURN servers over using this setting.
;; DEPRECATED: Use "externalIPv4" and/or "externalIPv6" instead.
;;
;; This setting implements a hack that will mangle all local ICE candidates so
;; that their candidate address is replaced with the provided external address,
;; even for candidates of type 'host'. In doing so, this KMS will not need a
;; STUN or TURN server, but remote peers will still be able to contact it.
;; Forces all local IPv4 and IPv6 ICE candidates to have the given address. This
;; is really nothing more than a hack, but it's very effective to force a public
;; IP address when one is known in advance for the media server. In doing so,
;; KMS will not need a STUN or TURN server, but remote peers will still be able
;; to contact it.
;;
;; You can try using this setting if KMS is deployed on a publicly accessible
;; server, without NAT, and with a static public IP address. But if it doesn't
;; work for you, just go back to using the STUN or TURN settings above.
;; work for you, just go back to configuring a STUN or TURN server for ICE.
;;
;; <externalAddress> is an IPv4 or IPv6 address.
;; Only set this parameter if you know what you're doing, and you understand
;; 100% WHY you need it. For the majority of cases, you should just prefer to
;; configure a STUN or TURN server.
;;
;; Examples:
;; externalAddress=10.20.30.40
;; externalAddress=2001:0db8:85a3:0000:0000:8a2e:0370:7334
;; <externalAddress> is a single IPv4 or IPv6 address.
;;
;externalAddress=10.20.30.40
;externalAddress=198.51.100.1
;externalAddress=2001:0db8:85a3:0000:0000:8a2e:0370:7334
74 changes: 74 additions & 0 deletions src/server/implementation/objects/WebRtcEndpointImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,13 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define DEFAULT_PATH "/etc/kurento"

#define PARAM_EXTERNAL_ADDRESS "externalAddress"
#define PARAM_EXTERNAL_IPV4 "externalIPv4"
#define PARAM_EXTERNAL_IPV6 "externalIPv6"
#define PARAM_NETWORK_INTERFACES "networkInterfaces"

#define PROP_EXTERNAL_ADDRESS "external-address"
#define PROP_EXTERNAL_IPV4 "external-ipv4"
#define PROP_EXTERNAL_IPV6 "external-ipv6"
#define PROP_NETWORK_INTERFACES "network-interfaces"

namespace kurento
Expand Down Expand Up @@ -510,6 +514,28 @@ WebRtcEndpointImpl::WebRtcEndpointImpl (const boost::property_tree::ptree &conf,

//set properties

std::string externalIPv4;
if (getConfigValue <std::string, WebRtcEndpoint> (&externalIPv4,
PARAM_EXTERNAL_IPV4)) {
GST_INFO ("Predefined external IPv4 address: %s", externalIPv4.c_str());
g_object_set (G_OBJECT (element), PROP_EXTERNAL_IPV4,
externalIPv4.c_str(), NULL);
} else {
GST_DEBUG ("No predefined external IPv4 address found in config;"
" you can set one or default to STUN automatic discovery");
}

std::string externalIPv6;
if (getConfigValue <std::string, WebRtcEndpoint> (&externalIPv6,
PARAM_EXTERNAL_IPV6)) {
GST_INFO ("Predefined external IPv6 address: %s", externalIPv6.c_str());
g_object_set (G_OBJECT (element), PROP_EXTERNAL_IPV6,
externalIPv6.c_str(), NULL);
} else {
GST_DEBUG ("No predefined external IPv6 address found in config;"
" you can set one or default to STUN automatic discovery");
}

std::string externalAddress;
if (getConfigValue <std::string, WebRtcEndpoint> (&externalAddress,
PARAM_EXTERNAL_ADDRESS)) {
Expand Down Expand Up @@ -624,6 +650,54 @@ WebRtcEndpointImpl::~WebRtcEndpointImpl()
}
}

std::string
WebRtcEndpointImpl::getExternalIPv4 ()
{
std::string externalIPv4;
gchar *ret;

g_object_get (G_OBJECT (element), PROP_EXTERNAL_IPV4, &ret, NULL);

if (ret != nullptr) {
externalIPv4 = std::string (ret);
g_free (ret);
}

return externalIPv4;
}

void
WebRtcEndpointImpl::setExternalIPv4 (const std::string &externalIPv4)
{
GST_INFO ("Set external IPv4 address: %s", externalIPv4.c_str());
g_object_set (G_OBJECT (element), PROP_EXTERNAL_IPV4,
externalIPv4.c_str(), NULL);
}

std::string
WebRtcEndpointImpl::getExternalIPv6 ()
{
std::string externalIPv6;
gchar *ret;

g_object_get (G_OBJECT (element), PROP_EXTERNAL_IPV6, &ret, NULL);

if (ret != nullptr) {
externalIPv6 = std::string (ret);
g_free (ret);
}

return externalIPv6;
}

void
WebRtcEndpointImpl::setExternalIPv6 (const std::string &externalIPv6)
{
GST_INFO ("Set external IPv6 address: %s", externalIPv6.c_str());
g_object_set (G_OBJECT (element), PROP_EXTERNAL_IPV6,
externalIPv6.c_str(), NULL);
}

std::string
WebRtcEndpointImpl::getExternalAddress ()
{
Expand Down
Loading