TURN episode #9
This commit is contained in:
parent
4a39fe9cd1
commit
3fc0c3df85
|
@ -492,8 +492,14 @@ bool MediaSessionMgr::defaultsSetStunEnabled(bool stun_enabled){
|
||||||
bool MediaSessionMgr::defaultsSetIceStunEnabled(bool icestun_enabled){
|
bool MediaSessionMgr::defaultsSetIceStunEnabled(bool icestun_enabled){
|
||||||
return (tmedia_defaults_set_icestun_enabled(icestun_enabled ? tsk_true : tsk_false) == 0);
|
return (tmedia_defaults_set_icestun_enabled(icestun_enabled ? tsk_true : tsk_false) == 0);
|
||||||
}
|
}
|
||||||
bool MediaSessionMgr::defaultsSetStunServer(const char* server_ip, uint16_t server_port, const char* usr_name /*= tsk_null*/, const char* usr_pwd /*= tsk_null*/){
|
bool MediaSessionMgr::defaultsSetIceTurnEnabled(bool iceturn_enabled){
|
||||||
return (tmedia_defaults_set_stun_server(server_ip, server_port, usr_name, usr_pwd) == 0);
|
return (tmedia_defaults_set_iceturn_enabled(iceturn_enabled ? tsk_true : tsk_false) == 0);
|
||||||
|
}
|
||||||
|
bool MediaSessionMgr::defaultsSetStunServer(const char* server_ip, uint16_t server_port){
|
||||||
|
return (tmedia_defaults_set_stun_server(server_ip, server_port) == 0);
|
||||||
|
}
|
||||||
|
bool MediaSessionMgr::defaultsSetStunCred(const char* username, const char* password){
|
||||||
|
return (tmedia_defaults_set_stun_cred(username, password) == 0);
|
||||||
}
|
}
|
||||||
bool MediaSessionMgr::defaultsSetIceEnabled(bool ice_enabled){
|
bool MediaSessionMgr::defaultsSetIceEnabled(bool ice_enabled){
|
||||||
return (tmedia_defaults_set_ice_enabled(ice_enabled ? tsk_true : tsk_false) == 0);
|
return (tmedia_defaults_set_ice_enabled(ice_enabled ? tsk_true : tsk_false) == 0);
|
||||||
|
|
|
@ -142,7 +142,9 @@ public:
|
||||||
static bool defaultsGetRtcpMuxEnabled();
|
static bool defaultsGetRtcpMuxEnabled();
|
||||||
static bool defaultsSetStunEnabled(bool stun_enabled);
|
static bool defaultsSetStunEnabled(bool stun_enabled);
|
||||||
static bool defaultsSetIceStunEnabled(bool icestun_enabled);
|
static bool defaultsSetIceStunEnabled(bool icestun_enabled);
|
||||||
static bool defaultsSetStunServer(const char* server_ip, uint16_t server_port, const char* usr_name = tsk_null, const char* usr_pwd = tsk_null);
|
static bool defaultsSetIceTurnEnabled(bool iceturn_enabled);
|
||||||
|
static bool defaultsSetStunServer(const char* server_ip, uint16_t server_port);
|
||||||
|
static bool defaultsSetStunCred(const char* username, const char* password);
|
||||||
static bool defaultsSetIceEnabled(bool ice_enabled);
|
static bool defaultsSetIceEnabled(bool ice_enabled);
|
||||||
static bool defaultsSetByPassEncoding(bool enabled);
|
static bool defaultsSetByPassEncoding(bool enabled);
|
||||||
static bool defaultsGetByPassEncoding();
|
static bool defaultsGetByPassEncoding();
|
||||||
|
|
|
@ -463,6 +463,46 @@ bool CallSession::setICE(bool enabled)
|
||||||
TSIP_SSESSION_SET_NULL()) == 0);
|
TSIP_SSESSION_SET_NULL()) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CallSession::setICEStun(bool enabled)
|
||||||
|
{
|
||||||
|
return (tsip_ssession_set(m_pHandle,
|
||||||
|
TSIP_SSESSION_SET_MEDIA(
|
||||||
|
TSIP_MSESSION_SET_ICE_STUN(enabled ? tsk_true : tsk_false),
|
||||||
|
TSIP_MSESSION_SET_NULL()
|
||||||
|
),
|
||||||
|
TSIP_SSESSION_SET_NULL()) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CallSession::setICETurn(bool enabled)
|
||||||
|
{
|
||||||
|
return (tsip_ssession_set(m_pHandle,
|
||||||
|
TSIP_SSESSION_SET_MEDIA(
|
||||||
|
TSIP_MSESSION_SET_ICE_TURN(enabled ? tsk_true : tsk_false),
|
||||||
|
TSIP_MSESSION_SET_NULL()
|
||||||
|
),
|
||||||
|
TSIP_SSESSION_SET_NULL()) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CallSession::setSTUNServer(const char* hostname, uint16_t port)
|
||||||
|
{
|
||||||
|
return (tsip_ssession_set(m_pHandle,
|
||||||
|
TSIP_SSESSION_SET_MEDIA(
|
||||||
|
TSIP_MSESSION_SET_STUN_SERVER(hostname, port),
|
||||||
|
TSIP_MSESSION_SET_NULL()
|
||||||
|
),
|
||||||
|
TSIP_SSESSION_SET_NULL()) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CallSession::setSTUNCred(const char* username, const char* password)
|
||||||
|
{
|
||||||
|
return (tsip_ssession_set(m_pHandle,
|
||||||
|
TSIP_SSESSION_SET_MEDIA(
|
||||||
|
TSIP_MSESSION_SET_STUN_CRED(username, password),
|
||||||
|
TSIP_MSESSION_SET_NULL()
|
||||||
|
),
|
||||||
|
TSIP_SSESSION_SET_NULL()) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
bool CallSession::setQoS(tmedia_qos_stype_t type, tmedia_qos_strength_t strength)
|
bool CallSession::setQoS(tmedia_qos_stype_t type, tmedia_qos_strength_t strength)
|
||||||
{
|
{
|
||||||
return (tsip_ssession_set(m_pHandle,
|
return (tsip_ssession_set(m_pHandle,
|
||||||
|
|
|
@ -194,6 +194,10 @@ public: /* Public functions */
|
||||||
bool setSRtpMode(enum tmedia_srtp_mode_e mode);
|
bool setSRtpMode(enum tmedia_srtp_mode_e mode);
|
||||||
bool setAvpfMode(enum tmedia_mode_e mode);
|
bool setAvpfMode(enum tmedia_mode_e mode);
|
||||||
bool setICE(bool enabled);
|
bool setICE(bool enabled);
|
||||||
|
bool setICEStun(bool enabled);
|
||||||
|
bool setICETurn(bool enabled);
|
||||||
|
bool setSTUNServer(const char* hostname, uint16_t port);
|
||||||
|
bool setSTUNCred(const char* username, const char* password);
|
||||||
bool setQoS(tmedia_qos_stype_t type, tmedia_qos_strength_t strength);
|
bool setQoS(tmedia_qos_stype_t type, tmedia_qos_strength_t strength);
|
||||||
bool hold(ActionConfig* config=tsk_null);
|
bool hold(ActionConfig* config=tsk_null);
|
||||||
bool resume(ActionConfig* config=tsk_null);
|
bool resume(ActionConfig* config=tsk_null);
|
||||||
|
|
|
@ -234,27 +234,48 @@ bool SipStack::removeSigCompCompartment(const char* compId)
|
||||||
TSIP_STACK_SET_NULL()) == 0);
|
TSIP_STACK_SET_NULL()) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @deprecated
|
||||||
bool SipStack::setSTUNEnabledForICE(bool enabled)
|
bool SipStack::setSTUNEnabledForICE(bool enabled)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
tsk_bool_t _enabled = enabled ? tsk_true : tsk_false;
|
tsk_bool_t _enabled = enabled ? tsk_true : tsk_false;
|
||||||
return (tsip_stack_set(m_pHandle,
|
return (tsip_stack_set(m_pHandle,
|
||||||
TSIP_STACK_SET_ICE_STUN_ENABLED(_enabled),
|
TSIP_STACK_SET_ICE_STUN_ENABLED(_enabled),
|
||||||
TSIP_STACK_SET_NULL()) == 0);
|
TSIP_STACK_SET_NULL()) == 0);
|
||||||
|
#else
|
||||||
|
// set global value
|
||||||
|
return (tmedia_defaults_set_icestun_enabled(enabled ? tsk_true : tsk_false) == 0);
|
||||||
|
// to set the value per session, use "CallSession::setICEStun()"
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SipStack::setSTUNServer(const char* ip, unsigned short port)
|
// @deprecated
|
||||||
|
bool SipStack::setSTUNServer(const char* hostname, unsigned short port)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
unsigned _port = port;//promote
|
unsigned _port = port;//promote
|
||||||
return (tsip_stack_set(m_pHandle,
|
return (tsip_stack_set(m_pHandle,
|
||||||
TSIP_STACK_SET_STUN_SERVER(ip, _port),
|
TSIP_STACK_SET_STUN_SERVER(hostname, _port),
|
||||||
TSIP_STACK_SET_NULL()) == 0);
|
TSIP_STACK_SET_NULL()) == 0);
|
||||||
|
#else
|
||||||
|
// set global value
|
||||||
|
return (tmedia_defaults_set_stun_server(hostname, port) == 0);
|
||||||
|
// to set the value per session, use "CallSession::setSTUNServer()"
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @deprecated
|
||||||
bool SipStack::setSTUNCred(const char* login, const char* password)
|
bool SipStack::setSTUNCred(const char* login, const char* password)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
return (tsip_stack_set(m_pHandle,
|
return (tsip_stack_set(m_pHandle,
|
||||||
TSIP_STACK_SET_STUN_CRED(login, password),
|
TSIP_STACK_SET_STUN_CRED(login, password),
|
||||||
TSIP_STACK_SET_NULL()) == 0);
|
TSIP_STACK_SET_NULL()) == 0);
|
||||||
|
#else
|
||||||
|
// set global value
|
||||||
|
return (tmedia_defaults_set_stun_cred(login, password) == 0);
|
||||||
|
// to set the value per session, use "CallSession::setSTUNCred()"
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SipStack::setSTUNEnabled(bool enabled)
|
bool SipStack::setSTUNEnabled(bool enabled)
|
||||||
|
|
|
@ -65,9 +65,9 @@ public: /* API functions */
|
||||||
bool addSigCompCompartment(const char* compId);
|
bool addSigCompCompartment(const char* compId);
|
||||||
bool removeSigCompCompartment(const char* compId);
|
bool removeSigCompCompartment(const char* compId);
|
||||||
|
|
||||||
bool setSTUNEnabledForICE(bool enabled);
|
bool setSTUNEnabledForICE(bool enabled); // @deprecated
|
||||||
bool setSTUNServer(const char* ip, unsigned short port);
|
bool setSTUNServer(const char* hostname, unsigned short port); // @deprecated
|
||||||
bool setSTUNCred(const char* login, const char* password);
|
bool setSTUNCred(const char* login, const char* password); // @deprecated
|
||||||
bool setSTUNEnabled(bool enabled);
|
bool setSTUNEnabled(bool enabled);
|
||||||
|
|
||||||
bool setTLSSecAgree(bool enabled);
|
bool setTLSSecAgree(bool enabled);
|
||||||
|
|
|
@ -158,6 +158,26 @@ public class CallSession : InviteSession {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool setICEStun(bool enabled) {
|
||||||
|
bool ret = tinyWRAPPINVOKE.CallSession_setICEStun(swigCPtr, enabled);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool setICETurn(bool enabled) {
|
||||||
|
bool ret = tinyWRAPPINVOKE.CallSession_setICETurn(swigCPtr, enabled);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool setSTUNServer(string hostname, ushort port) {
|
||||||
|
bool ret = tinyWRAPPINVOKE.CallSession_setSTUNServer(swigCPtr, hostname, port);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool setSTUNCred(string username, string password) {
|
||||||
|
bool ret = tinyWRAPPINVOKE.CallSession_setSTUNCred(swigCPtr, username, password);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
public bool setQoS(tmedia_qos_stype_t type, tmedia_qos_strength_t strength) {
|
public bool setQoS(tmedia_qos_stype_t type, tmedia_qos_strength_t strength) {
|
||||||
bool ret = tinyWRAPPINVOKE.CallSession_setQoS(swigCPtr, (int)type, (int)strength);
|
bool ret = tinyWRAPPINVOKE.CallSession_setQoS(swigCPtr, (int)type, (int)strength);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -344,18 +344,18 @@ public class MediaSessionMgr : IDisposable {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool defaultsSetStunServer(string server_ip, ushort server_port, string usr_name, string usr_pwd) {
|
public static bool defaultsSetIceTurnEnabled(bool iceturn_enabled) {
|
||||||
bool ret = tinyWRAPPINVOKE.MediaSessionMgr_defaultsSetStunServer__SWIG_0(server_ip, server_port, usr_name, usr_pwd);
|
bool ret = tinyWRAPPINVOKE.MediaSessionMgr_defaultsSetIceTurnEnabled(iceturn_enabled);
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool defaultsSetStunServer(string server_ip, ushort server_port, string usr_name) {
|
|
||||||
bool ret = tinyWRAPPINVOKE.MediaSessionMgr_defaultsSetStunServer__SWIG_1(server_ip, server_port, usr_name);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool defaultsSetStunServer(string server_ip, ushort server_port) {
|
public static bool defaultsSetStunServer(string server_ip, ushort server_port) {
|
||||||
bool ret = tinyWRAPPINVOKE.MediaSessionMgr_defaultsSetStunServer__SWIG_2(server_ip, server_port);
|
bool ret = tinyWRAPPINVOKE.MediaSessionMgr_defaultsSetStunServer(server_ip, server_port);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool defaultsSetStunCred(string username, string password) {
|
||||||
|
bool ret = tinyWRAPPINVOKE.MediaSessionMgr_defaultsSetStunCred(username, password);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -163,8 +163,8 @@ public class SipStack : SafeObject {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool setSTUNServer(string ip, ushort port) {
|
public bool setSTUNServer(string hostname, ushort port) {
|
||||||
bool ret = tinyWRAPPINVOKE.SipStack_setSTUNServer(swigCPtr, ip, port);
|
bool ret = tinyWRAPPINVOKE.SipStack_setSTUNServer(swigCPtr, hostname, port);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -471,14 +471,14 @@ class tinyWRAPPINVOKE {
|
||||||
[DllImport("tinyWRAP", EntryPoint="CSharp_MediaSessionMgr_defaultsSetIceStunEnabled")]
|
[DllImport("tinyWRAP", EntryPoint="CSharp_MediaSessionMgr_defaultsSetIceStunEnabled")]
|
||||||
public static extern bool MediaSessionMgr_defaultsSetIceStunEnabled(bool jarg1);
|
public static extern bool MediaSessionMgr_defaultsSetIceStunEnabled(bool jarg1);
|
||||||
|
|
||||||
[DllImport("tinyWRAP", EntryPoint="CSharp_MediaSessionMgr_defaultsSetStunServer__SWIG_0")]
|
[DllImport("tinyWRAP", EntryPoint="CSharp_MediaSessionMgr_defaultsSetIceTurnEnabled")]
|
||||||
public static extern bool MediaSessionMgr_defaultsSetStunServer__SWIG_0(string jarg1, ushort jarg2, string jarg3, string jarg4);
|
public static extern bool MediaSessionMgr_defaultsSetIceTurnEnabled(bool jarg1);
|
||||||
|
|
||||||
[DllImport("tinyWRAP", EntryPoint="CSharp_MediaSessionMgr_defaultsSetStunServer__SWIG_1")]
|
[DllImport("tinyWRAP", EntryPoint="CSharp_MediaSessionMgr_defaultsSetStunServer")]
|
||||||
public static extern bool MediaSessionMgr_defaultsSetStunServer__SWIG_1(string jarg1, ushort jarg2, string jarg3);
|
public static extern bool MediaSessionMgr_defaultsSetStunServer(string jarg1, ushort jarg2);
|
||||||
|
|
||||||
[DllImport("tinyWRAP", EntryPoint="CSharp_MediaSessionMgr_defaultsSetStunServer__SWIG_2")]
|
[DllImport("tinyWRAP", EntryPoint="CSharp_MediaSessionMgr_defaultsSetStunCred")]
|
||||||
public static extern bool MediaSessionMgr_defaultsSetStunServer__SWIG_2(string jarg1, ushort jarg2);
|
public static extern bool MediaSessionMgr_defaultsSetStunCred(string jarg1, string jarg2);
|
||||||
|
|
||||||
[DllImport("tinyWRAP", EntryPoint="CSharp_MediaSessionMgr_defaultsSetIceEnabled")]
|
[DllImport("tinyWRAP", EntryPoint="CSharp_MediaSessionMgr_defaultsSetIceEnabled")]
|
||||||
public static extern bool MediaSessionMgr_defaultsSetIceEnabled(bool jarg1);
|
public static extern bool MediaSessionMgr_defaultsSetIceEnabled(bool jarg1);
|
||||||
|
@ -954,6 +954,18 @@ class tinyWRAPPINVOKE {
|
||||||
[DllImport("tinyWRAP", EntryPoint="CSharp_CallSession_setICE")]
|
[DllImport("tinyWRAP", EntryPoint="CSharp_CallSession_setICE")]
|
||||||
public static extern bool CallSession_setICE(HandleRef jarg1, bool jarg2);
|
public static extern bool CallSession_setICE(HandleRef jarg1, bool jarg2);
|
||||||
|
|
||||||
|
[DllImport("tinyWRAP", EntryPoint="CSharp_CallSession_setICEStun")]
|
||||||
|
public static extern bool CallSession_setICEStun(HandleRef jarg1, bool jarg2);
|
||||||
|
|
||||||
|
[DllImport("tinyWRAP", EntryPoint="CSharp_CallSession_setICETurn")]
|
||||||
|
public static extern bool CallSession_setICETurn(HandleRef jarg1, bool jarg2);
|
||||||
|
|
||||||
|
[DllImport("tinyWRAP", EntryPoint="CSharp_CallSession_setSTUNServer")]
|
||||||
|
public static extern bool CallSession_setSTUNServer(HandleRef jarg1, string jarg2, ushort jarg3);
|
||||||
|
|
||||||
|
[DllImport("tinyWRAP", EntryPoint="CSharp_CallSession_setSTUNCred")]
|
||||||
|
public static extern bool CallSession_setSTUNCred(HandleRef jarg1, string jarg2, string jarg3);
|
||||||
|
|
||||||
[DllImport("tinyWRAP", EntryPoint="CSharp_CallSession_setQoS")]
|
[DllImport("tinyWRAP", EntryPoint="CSharp_CallSession_setQoS")]
|
||||||
public static extern bool CallSession_setQoS(HandleRef jarg1, int jarg2, int jarg3);
|
public static extern bool CallSession_setQoS(HandleRef jarg1, int jarg2, int jarg3);
|
||||||
|
|
||||||
|
|
|
@ -2330,41 +2330,19 @@ SWIGEXPORT unsigned int SWIGSTDCALL CSharp_MediaSessionMgr_defaultsSetIceStunEna
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT unsigned int SWIGSTDCALL CSharp_MediaSessionMgr_defaultsSetStunServer__SWIG_0(char * jarg1, unsigned short jarg2, char * jarg3, char * jarg4) {
|
SWIGEXPORT unsigned int SWIGSTDCALL CSharp_MediaSessionMgr_defaultsSetIceTurnEnabled(unsigned int jarg1) {
|
||||||
unsigned int jresult ;
|
unsigned int jresult ;
|
||||||
char *arg1 = (char *) 0 ;
|
bool arg1 ;
|
||||||
uint16_t arg2 ;
|
|
||||||
char *arg3 = (char *) 0 ;
|
|
||||||
char *arg4 = (char *) 0 ;
|
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
arg1 = (char *)jarg1;
|
arg1 = jarg1 ? true : false;
|
||||||
arg2 = (uint16_t)jarg2;
|
result = (bool)MediaSessionMgr::defaultsSetIceTurnEnabled(arg1);
|
||||||
arg3 = (char *)jarg3;
|
|
||||||
arg4 = (char *)jarg4;
|
|
||||||
result = (bool)MediaSessionMgr::defaultsSetStunServer((char const *)arg1,arg2,(char const *)arg3,(char const *)arg4);
|
|
||||||
jresult = result;
|
jresult = result;
|
||||||
return jresult;
|
return jresult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT unsigned int SWIGSTDCALL CSharp_MediaSessionMgr_defaultsSetStunServer__SWIG_1(char * jarg1, unsigned short jarg2, char * jarg3) {
|
SWIGEXPORT unsigned int SWIGSTDCALL CSharp_MediaSessionMgr_defaultsSetStunServer(char * jarg1, unsigned short jarg2) {
|
||||||
unsigned int jresult ;
|
|
||||||
char *arg1 = (char *) 0 ;
|
|
||||||
uint16_t arg2 ;
|
|
||||||
char *arg3 = (char *) 0 ;
|
|
||||||
bool result;
|
|
||||||
|
|
||||||
arg1 = (char *)jarg1;
|
|
||||||
arg2 = (uint16_t)jarg2;
|
|
||||||
arg3 = (char *)jarg3;
|
|
||||||
result = (bool)MediaSessionMgr::defaultsSetStunServer((char const *)arg1,arg2,(char const *)arg3);
|
|
||||||
jresult = result;
|
|
||||||
return jresult;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT unsigned int SWIGSTDCALL CSharp_MediaSessionMgr_defaultsSetStunServer__SWIG_2(char * jarg1, unsigned short jarg2) {
|
|
||||||
unsigned int jresult ;
|
unsigned int jresult ;
|
||||||
char *arg1 = (char *) 0 ;
|
char *arg1 = (char *) 0 ;
|
||||||
uint16_t arg2 ;
|
uint16_t arg2 ;
|
||||||
|
@ -2378,6 +2356,20 @@ SWIGEXPORT unsigned int SWIGSTDCALL CSharp_MediaSessionMgr_defaultsSetStunServer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT unsigned int SWIGSTDCALL CSharp_MediaSessionMgr_defaultsSetStunCred(char * jarg1, char * jarg2) {
|
||||||
|
unsigned int jresult ;
|
||||||
|
char *arg1 = (char *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
arg1 = (char *)jarg1;
|
||||||
|
arg2 = (char *)jarg2;
|
||||||
|
result = (bool)MediaSessionMgr::defaultsSetStunCred((char const *)arg1,(char const *)arg2);
|
||||||
|
jresult = result;
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT unsigned int SWIGSTDCALL CSharp_MediaSessionMgr_defaultsSetIceEnabled(unsigned int jarg1) {
|
SWIGEXPORT unsigned int SWIGSTDCALL CSharp_MediaSessionMgr_defaultsSetIceEnabled(unsigned int jarg1) {
|
||||||
unsigned int jresult ;
|
unsigned int jresult ;
|
||||||
bool arg1 ;
|
bool arg1 ;
|
||||||
|
@ -4364,6 +4356,66 @@ SWIGEXPORT unsigned int SWIGSTDCALL CSharp_CallSession_setICE(void * jarg1, unsi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT unsigned int SWIGSTDCALL CSharp_CallSession_setICEStun(void * jarg1, unsigned int jarg2) {
|
||||||
|
unsigned int jresult ;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
bool arg2 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
arg1 = (CallSession *)jarg1;
|
||||||
|
arg2 = jarg2 ? true : false;
|
||||||
|
result = (bool)(arg1)->setICEStun(arg2);
|
||||||
|
jresult = result;
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT unsigned int SWIGSTDCALL CSharp_CallSession_setICETurn(void * jarg1, unsigned int jarg2) {
|
||||||
|
unsigned int jresult ;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
bool arg2 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
arg1 = (CallSession *)jarg1;
|
||||||
|
arg2 = jarg2 ? true : false;
|
||||||
|
result = (bool)(arg1)->setICETurn(arg2);
|
||||||
|
jresult = result;
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT unsigned int SWIGSTDCALL CSharp_CallSession_setSTUNServer(void * jarg1, char * jarg2, unsigned short jarg3) {
|
||||||
|
unsigned int jresult ;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
uint16_t arg3 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
arg1 = (CallSession *)jarg1;
|
||||||
|
arg2 = (char *)jarg2;
|
||||||
|
arg3 = (uint16_t)jarg3;
|
||||||
|
result = (bool)(arg1)->setSTUNServer((char const *)arg2,arg3);
|
||||||
|
jresult = result;
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT unsigned int SWIGSTDCALL CSharp_CallSession_setSTUNCred(void * jarg1, char * jarg2, char * jarg3) {
|
||||||
|
unsigned int jresult ;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
char *arg3 = (char *) 0 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
arg1 = (CallSession *)jarg1;
|
||||||
|
arg2 = (char *)jarg2;
|
||||||
|
arg3 = (char *)jarg3;
|
||||||
|
result = (bool)(arg1)->setSTUNCred((char const *)arg2,(char const *)arg3);
|
||||||
|
jresult = result;
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT unsigned int SWIGSTDCALL CSharp_CallSession_setQoS(void * jarg1, int jarg2, int jarg3) {
|
SWIGEXPORT unsigned int SWIGSTDCALL CSharp_CallSession_setQoS(void * jarg1, int jarg2, int jarg3) {
|
||||||
unsigned int jresult ;
|
unsigned int jresult ;
|
||||||
CallSession *arg1 = (CallSession *) 0 ;
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
|
|
@ -131,6 +131,22 @@ public class CallSession extends InviteSession {
|
||||||
return tinyWRAPJNI.CallSession_setICE(swigCPtr, this, enabled);
|
return tinyWRAPJNI.CallSession_setICE(swigCPtr, this, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean setICEStun(boolean enabled) {
|
||||||
|
return tinyWRAPJNI.CallSession_setICEStun(swigCPtr, this, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setICETurn(boolean enabled) {
|
||||||
|
return tinyWRAPJNI.CallSession_setICETurn(swigCPtr, this, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setSTUNServer(String hostname, int port) {
|
||||||
|
return tinyWRAPJNI.CallSession_setSTUNServer(swigCPtr, this, hostname, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setSTUNCred(String username, String password) {
|
||||||
|
return tinyWRAPJNI.CallSession_setSTUNCred(swigCPtr, this, username, password);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean setQoS(tmedia_qos_stype_t type, tmedia_qos_strength_t strength) {
|
public boolean setQoS(tmedia_qos_stype_t type, tmedia_qos_strength_t strength) {
|
||||||
return tinyWRAPJNI.CallSession_setQoS(swigCPtr, this, type.swigValue(), strength.swigValue());
|
return tinyWRAPJNI.CallSession_setQoS(swigCPtr, this, type.swigValue(), strength.swigValue());
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,16 +278,16 @@ public class MediaSessionMgr {
|
||||||
return tinyWRAPJNI.MediaSessionMgr_defaultsSetIceStunEnabled(icestun_enabled);
|
return tinyWRAPJNI.MediaSessionMgr_defaultsSetIceStunEnabled(icestun_enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean defaultsSetStunServer(String server_ip, int server_port, String usr_name, String usr_pwd) {
|
public static boolean defaultsSetIceTurnEnabled(boolean iceturn_enabled) {
|
||||||
return tinyWRAPJNI.MediaSessionMgr_defaultsSetStunServer__SWIG_0(server_ip, server_port, usr_name, usr_pwd);
|
return tinyWRAPJNI.MediaSessionMgr_defaultsSetIceTurnEnabled(iceturn_enabled);
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean defaultsSetStunServer(String server_ip, int server_port, String usr_name) {
|
|
||||||
return tinyWRAPJNI.MediaSessionMgr_defaultsSetStunServer__SWIG_1(server_ip, server_port, usr_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean defaultsSetStunServer(String server_ip, int server_port) {
|
public static boolean defaultsSetStunServer(String server_ip, int server_port) {
|
||||||
return tinyWRAPJNI.MediaSessionMgr_defaultsSetStunServer__SWIG_2(server_ip, server_port);
|
return tinyWRAPJNI.MediaSessionMgr_defaultsSetStunServer(server_ip, server_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean defaultsSetStunCred(String username, String password) {
|
||||||
|
return tinyWRAPJNI.MediaSessionMgr_defaultsSetStunCred(username, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean defaultsSetIceEnabled(boolean ice_enabled) {
|
public static boolean defaultsSetIceEnabled(boolean ice_enabled) {
|
||||||
|
|
|
@ -135,8 +135,8 @@ public class SipStack extends SafeObject {
|
||||||
return tinyWRAPJNI.SipStack_setSTUNEnabledForICE(swigCPtr, this, enabled);
|
return tinyWRAPJNI.SipStack_setSTUNEnabledForICE(swigCPtr, this, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setSTUNServer(String ip, int port) {
|
public boolean setSTUNServer(String hostname, int port) {
|
||||||
return tinyWRAPJNI.SipStack_setSTUNServer(swigCPtr, this, ip, port);
|
return tinyWRAPJNI.SipStack_setSTUNServer(swigCPtr, this, hostname, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setSTUNCred(String login, String password) {
|
public boolean setSTUNCred(String login, String password) {
|
||||||
|
|
|
@ -131,6 +131,22 @@ public class CallSession extends InviteSession {
|
||||||
return tinyWRAPJNI.CallSession_setICE(swigCPtr, this, enabled);
|
return tinyWRAPJNI.CallSession_setICE(swigCPtr, this, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean setICEStun(boolean enabled) {
|
||||||
|
return tinyWRAPJNI.CallSession_setICEStun(swigCPtr, this, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setICETurn(boolean enabled) {
|
||||||
|
return tinyWRAPJNI.CallSession_setICETurn(swigCPtr, this, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setSTUNServer(String hostname, int port) {
|
||||||
|
return tinyWRAPJNI.CallSession_setSTUNServer(swigCPtr, this, hostname, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setSTUNCred(String username, String password) {
|
||||||
|
return tinyWRAPJNI.CallSession_setSTUNCred(swigCPtr, this, username, password);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean setQoS(tmedia_qos_stype_t type, tmedia_qos_strength_t strength) {
|
public boolean setQoS(tmedia_qos_stype_t type, tmedia_qos_strength_t strength) {
|
||||||
return tinyWRAPJNI.CallSession_setQoS(swigCPtr, this, type.swigValue(), strength.swigValue());
|
return tinyWRAPJNI.CallSession_setQoS(swigCPtr, this, type.swigValue(), strength.swigValue());
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,16 +278,16 @@ public class MediaSessionMgr {
|
||||||
return tinyWRAPJNI.MediaSessionMgr_defaultsSetIceStunEnabled(icestun_enabled);
|
return tinyWRAPJNI.MediaSessionMgr_defaultsSetIceStunEnabled(icestun_enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean defaultsSetStunServer(String server_ip, int server_port, String usr_name, String usr_pwd) {
|
public static boolean defaultsSetIceTurnEnabled(boolean iceturn_enabled) {
|
||||||
return tinyWRAPJNI.MediaSessionMgr_defaultsSetStunServer__SWIG_0(server_ip, server_port, usr_name, usr_pwd);
|
return tinyWRAPJNI.MediaSessionMgr_defaultsSetIceTurnEnabled(iceturn_enabled);
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean defaultsSetStunServer(String server_ip, int server_port, String usr_name) {
|
|
||||||
return tinyWRAPJNI.MediaSessionMgr_defaultsSetStunServer__SWIG_1(server_ip, server_port, usr_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean defaultsSetStunServer(String server_ip, int server_port) {
|
public static boolean defaultsSetStunServer(String server_ip, int server_port) {
|
||||||
return tinyWRAPJNI.MediaSessionMgr_defaultsSetStunServer__SWIG_2(server_ip, server_port);
|
return tinyWRAPJNI.MediaSessionMgr_defaultsSetStunServer(server_ip, server_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean defaultsSetStunCred(String username, String password) {
|
||||||
|
return tinyWRAPJNI.MediaSessionMgr_defaultsSetStunCred(username, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean defaultsSetIceEnabled(boolean ice_enabled) {
|
public static boolean defaultsSetIceEnabled(boolean ice_enabled) {
|
||||||
|
|
|
@ -135,8 +135,8 @@ public class SipStack extends SafeObject {
|
||||||
return tinyWRAPJNI.SipStack_setSTUNEnabledForICE(swigCPtr, this, enabled);
|
return tinyWRAPJNI.SipStack_setSTUNEnabledForICE(swigCPtr, this, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setSTUNServer(String ip, int port) {
|
public boolean setSTUNServer(String hostname, int port) {
|
||||||
return tinyWRAPJNI.SipStack_setSTUNServer(swigCPtr, this, ip, port);
|
return tinyWRAPJNI.SipStack_setSTUNServer(swigCPtr, this, hostname, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setSTUNCred(String login, String password) {
|
public boolean setSTUNCred(String login, String password) {
|
||||||
|
|
|
@ -104,9 +104,9 @@ public class tinyWRAPJNI {
|
||||||
public final static native boolean MediaSessionMgr_defaultsGetRtcpMuxEnabled();
|
public final static native boolean MediaSessionMgr_defaultsGetRtcpMuxEnabled();
|
||||||
public final static native boolean MediaSessionMgr_defaultsSetStunEnabled(boolean jarg1);
|
public final static native boolean MediaSessionMgr_defaultsSetStunEnabled(boolean jarg1);
|
||||||
public final static native boolean MediaSessionMgr_defaultsSetIceStunEnabled(boolean jarg1);
|
public final static native boolean MediaSessionMgr_defaultsSetIceStunEnabled(boolean jarg1);
|
||||||
public final static native boolean MediaSessionMgr_defaultsSetStunServer__SWIG_0(String jarg1, int jarg2, String jarg3, String jarg4);
|
public final static native boolean MediaSessionMgr_defaultsSetIceTurnEnabled(boolean jarg1);
|
||||||
public final static native boolean MediaSessionMgr_defaultsSetStunServer__SWIG_1(String jarg1, int jarg2, String jarg3);
|
public final static native boolean MediaSessionMgr_defaultsSetStunServer(String jarg1, int jarg2);
|
||||||
public final static native boolean MediaSessionMgr_defaultsSetStunServer__SWIG_2(String jarg1, int jarg2);
|
public final static native boolean MediaSessionMgr_defaultsSetStunCred(String jarg1, String jarg2);
|
||||||
public final static native boolean MediaSessionMgr_defaultsSetIceEnabled(boolean jarg1);
|
public final static native boolean MediaSessionMgr_defaultsSetIceEnabled(boolean jarg1);
|
||||||
public final static native boolean MediaSessionMgr_defaultsSetByPassEncoding(boolean jarg1);
|
public final static native boolean MediaSessionMgr_defaultsSetByPassEncoding(boolean jarg1);
|
||||||
public final static native boolean MediaSessionMgr_defaultsGetByPassEncoding();
|
public final static native boolean MediaSessionMgr_defaultsGetByPassEncoding();
|
||||||
|
@ -266,6 +266,10 @@ public class tinyWRAPJNI {
|
||||||
public final static native boolean CallSession_setSRtpMode(long jarg1, CallSession jarg1_, int jarg2);
|
public final static native boolean CallSession_setSRtpMode(long jarg1, CallSession jarg1_, int jarg2);
|
||||||
public final static native boolean CallSession_setAvpfMode(long jarg1, CallSession jarg1_, int jarg2);
|
public final static native boolean CallSession_setAvpfMode(long jarg1, CallSession jarg1_, int jarg2);
|
||||||
public final static native boolean CallSession_setICE(long jarg1, CallSession jarg1_, boolean jarg2);
|
public final static native boolean CallSession_setICE(long jarg1, CallSession jarg1_, boolean jarg2);
|
||||||
|
public final static native boolean CallSession_setICEStun(long jarg1, CallSession jarg1_, boolean jarg2);
|
||||||
|
public final static native boolean CallSession_setICETurn(long jarg1, CallSession jarg1_, boolean jarg2);
|
||||||
|
public final static native boolean CallSession_setSTUNServer(long jarg1, CallSession jarg1_, String jarg2, int jarg3);
|
||||||
|
public final static native boolean CallSession_setSTUNCred(long jarg1, CallSession jarg1_, String jarg2, String jarg3);
|
||||||
public final static native boolean CallSession_setQoS(long jarg1, CallSession jarg1_, int jarg2, int jarg3);
|
public final static native boolean CallSession_setQoS(long jarg1, CallSession jarg1_, int jarg2, int jarg3);
|
||||||
public final static native boolean CallSession_hold__SWIG_0(long jarg1, CallSession jarg1_, long jarg2, ActionConfig jarg2_);
|
public final static native boolean CallSession_hold__SWIG_0(long jarg1, CallSession jarg1_, long jarg2, ActionConfig jarg2_);
|
||||||
public final static native boolean CallSession_hold__SWIG_1(long jarg1, CallSession jarg1_);
|
public final static native boolean CallSession_hold__SWIG_1(long jarg1, CallSession jarg1_);
|
||||||
|
|
|
@ -3460,70 +3460,21 @@ SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionM
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetStunServer_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jstring jarg1, jint jarg2, jstring jarg3, jstring jarg4) {
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetIceTurnEnabled(JNIEnv *jenv, jclass jcls, jboolean jarg1) {
|
||||||
jboolean jresult = 0 ;
|
jboolean jresult = 0 ;
|
||||||
char *arg1 = (char *) 0 ;
|
bool arg1 ;
|
||||||
uint16_t arg2 ;
|
|
||||||
char *arg3 = (char *) 0 ;
|
|
||||||
char *arg4 = (char *) 0 ;
|
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
(void)jenv;
|
(void)jenv;
|
||||||
(void)jcls;
|
(void)jcls;
|
||||||
arg1 = 0;
|
arg1 = jarg1 ? true : false;
|
||||||
if (jarg1) {
|
result = (bool)MediaSessionMgr::defaultsSetIceTurnEnabled(arg1);
|
||||||
arg1 = (char *)jenv->GetStringUTFChars(jarg1, 0);
|
|
||||||
if (!arg1) return 0;
|
|
||||||
}
|
|
||||||
arg2 = (uint16_t)jarg2;
|
|
||||||
arg3 = 0;
|
|
||||||
if (jarg3) {
|
|
||||||
arg3 = (char *)jenv->GetStringUTFChars(jarg3, 0);
|
|
||||||
if (!arg3) return 0;
|
|
||||||
}
|
|
||||||
arg4 = 0;
|
|
||||||
if (jarg4) {
|
|
||||||
arg4 = (char *)jenv->GetStringUTFChars(jarg4, 0);
|
|
||||||
if (!arg4) return 0;
|
|
||||||
}
|
|
||||||
result = (bool)MediaSessionMgr::defaultsSetStunServer((char const *)arg1,arg2,(char const *)arg3,(char const *)arg4);
|
|
||||||
jresult = (jboolean)result;
|
jresult = (jboolean)result;
|
||||||
if (arg1) jenv->ReleaseStringUTFChars(jarg1, (const char *)arg1);
|
|
||||||
if (arg3) jenv->ReleaseStringUTFChars(jarg3, (const char *)arg3);
|
|
||||||
if (arg4) jenv->ReleaseStringUTFChars(jarg4, (const char *)arg4);
|
|
||||||
return jresult;
|
return jresult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetStunServer_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jstring jarg1, jint jarg2, jstring jarg3) {
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetStunServer(JNIEnv *jenv, jclass jcls, jstring jarg1, jint jarg2) {
|
||||||
jboolean jresult = 0 ;
|
|
||||||
char *arg1 = (char *) 0 ;
|
|
||||||
uint16_t arg2 ;
|
|
||||||
char *arg3 = (char *) 0 ;
|
|
||||||
bool result;
|
|
||||||
|
|
||||||
(void)jenv;
|
|
||||||
(void)jcls;
|
|
||||||
arg1 = 0;
|
|
||||||
if (jarg1) {
|
|
||||||
arg1 = (char *)jenv->GetStringUTFChars(jarg1, 0);
|
|
||||||
if (!arg1) return 0;
|
|
||||||
}
|
|
||||||
arg2 = (uint16_t)jarg2;
|
|
||||||
arg3 = 0;
|
|
||||||
if (jarg3) {
|
|
||||||
arg3 = (char *)jenv->GetStringUTFChars(jarg3, 0);
|
|
||||||
if (!arg3) return 0;
|
|
||||||
}
|
|
||||||
result = (bool)MediaSessionMgr::defaultsSetStunServer((char const *)arg1,arg2,(char const *)arg3);
|
|
||||||
jresult = (jboolean)result;
|
|
||||||
if (arg1) jenv->ReleaseStringUTFChars(jarg1, (const char *)arg1);
|
|
||||||
if (arg3) jenv->ReleaseStringUTFChars(jarg3, (const char *)arg3);
|
|
||||||
return jresult;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetStunServer_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jstring jarg1, jint jarg2) {
|
|
||||||
jboolean jresult = 0 ;
|
jboolean jresult = 0 ;
|
||||||
char *arg1 = (char *) 0 ;
|
char *arg1 = (char *) 0 ;
|
||||||
uint16_t arg2 ;
|
uint16_t arg2 ;
|
||||||
|
@ -3544,6 +3495,32 @@ SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionM
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetStunCred(JNIEnv *jenv, jclass jcls, jstring jarg1, jstring jarg2) {
|
||||||
|
jboolean jresult = 0 ;
|
||||||
|
char *arg1 = (char *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
(void)jenv;
|
||||||
|
(void)jcls;
|
||||||
|
arg1 = 0;
|
||||||
|
if (jarg1) {
|
||||||
|
arg1 = (char *)jenv->GetStringUTFChars(jarg1, 0);
|
||||||
|
if (!arg1) return 0;
|
||||||
|
}
|
||||||
|
arg2 = 0;
|
||||||
|
if (jarg2) {
|
||||||
|
arg2 = (char *)jenv->GetStringUTFChars(jarg2, 0);
|
||||||
|
if (!arg2) return 0;
|
||||||
|
}
|
||||||
|
result = (bool)MediaSessionMgr::defaultsSetStunCred((char const *)arg1,(char const *)arg2);
|
||||||
|
jresult = (jboolean)result;
|
||||||
|
if (arg1) jenv->ReleaseStringUTFChars(jarg1, (const char *)arg1);
|
||||||
|
if (arg2) jenv->ReleaseStringUTFChars(jarg2, (const char *)arg2);
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetIceEnabled(JNIEnv *jenv, jclass jcls, jboolean jarg1) {
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetIceEnabled(JNIEnv *jenv, jclass jcls, jboolean jarg1) {
|
||||||
jboolean jresult = 0 ;
|
jboolean jresult = 0 ;
|
||||||
bool arg1 ;
|
bool arg1 ;
|
||||||
|
@ -6195,6 +6172,93 @@ SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_CallSession_1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_CallSession_1setICEStun(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jboolean jarg2) {
|
||||||
|
jboolean jresult = 0 ;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
bool arg2 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
(void)jenv;
|
||||||
|
(void)jcls;
|
||||||
|
(void)jarg1_;
|
||||||
|
arg1 = *(CallSession **)&jarg1;
|
||||||
|
arg2 = jarg2 ? true : false;
|
||||||
|
result = (bool)(arg1)->setICEStun(arg2);
|
||||||
|
jresult = (jboolean)result;
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_CallSession_1setICETurn(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jboolean jarg2) {
|
||||||
|
jboolean jresult = 0 ;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
bool arg2 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
(void)jenv;
|
||||||
|
(void)jcls;
|
||||||
|
(void)jarg1_;
|
||||||
|
arg1 = *(CallSession **)&jarg1;
|
||||||
|
arg2 = jarg2 ? true : false;
|
||||||
|
result = (bool)(arg1)->setICETurn(arg2);
|
||||||
|
jresult = (jboolean)result;
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_CallSession_1setSTUNServer(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2, jint jarg3) {
|
||||||
|
jboolean jresult = 0 ;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
uint16_t arg3 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
(void)jenv;
|
||||||
|
(void)jcls;
|
||||||
|
(void)jarg1_;
|
||||||
|
arg1 = *(CallSession **)&jarg1;
|
||||||
|
arg2 = 0;
|
||||||
|
if (jarg2) {
|
||||||
|
arg2 = (char *)jenv->GetStringUTFChars(jarg2, 0);
|
||||||
|
if (!arg2) return 0;
|
||||||
|
}
|
||||||
|
arg3 = (uint16_t)jarg3;
|
||||||
|
result = (bool)(arg1)->setSTUNServer((char const *)arg2,arg3);
|
||||||
|
jresult = (jboolean)result;
|
||||||
|
if (arg2) jenv->ReleaseStringUTFChars(jarg2, (const char *)arg2);
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_CallSession_1setSTUNCred(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2, jstring jarg3) {
|
||||||
|
jboolean jresult = 0 ;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
char *arg3 = (char *) 0 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
(void)jenv;
|
||||||
|
(void)jcls;
|
||||||
|
(void)jarg1_;
|
||||||
|
arg1 = *(CallSession **)&jarg1;
|
||||||
|
arg2 = 0;
|
||||||
|
if (jarg2) {
|
||||||
|
arg2 = (char *)jenv->GetStringUTFChars(jarg2, 0);
|
||||||
|
if (!arg2) return 0;
|
||||||
|
}
|
||||||
|
arg3 = 0;
|
||||||
|
if (jarg3) {
|
||||||
|
arg3 = (char *)jenv->GetStringUTFChars(jarg3, 0);
|
||||||
|
if (!arg3) return 0;
|
||||||
|
}
|
||||||
|
result = (bool)(arg1)->setSTUNCred((char const *)arg2,(char const *)arg3);
|
||||||
|
jresult = (jboolean)result;
|
||||||
|
if (arg2) jenv->ReleaseStringUTFChars(jarg2, (const char *)arg2);
|
||||||
|
if (arg3) jenv->ReleaseStringUTFChars(jarg3, (const char *)arg3);
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_CallSession_1setQoS(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3) {
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_CallSession_1setQoS(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3) {
|
||||||
jboolean jresult = 0 ;
|
jboolean jresult = 0 ;
|
||||||
CallSession *arg1 = (CallSession *) 0 ;
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
|
|
@ -104,9 +104,9 @@ public class tinyWRAPJNI {
|
||||||
public final static native boolean MediaSessionMgr_defaultsGetRtcpMuxEnabled();
|
public final static native boolean MediaSessionMgr_defaultsGetRtcpMuxEnabled();
|
||||||
public final static native boolean MediaSessionMgr_defaultsSetStunEnabled(boolean jarg1);
|
public final static native boolean MediaSessionMgr_defaultsSetStunEnabled(boolean jarg1);
|
||||||
public final static native boolean MediaSessionMgr_defaultsSetIceStunEnabled(boolean jarg1);
|
public final static native boolean MediaSessionMgr_defaultsSetIceStunEnabled(boolean jarg1);
|
||||||
public final static native boolean MediaSessionMgr_defaultsSetStunServer__SWIG_0(String jarg1, int jarg2, String jarg3, String jarg4);
|
public final static native boolean MediaSessionMgr_defaultsSetIceTurnEnabled(boolean jarg1);
|
||||||
public final static native boolean MediaSessionMgr_defaultsSetStunServer__SWIG_1(String jarg1, int jarg2, String jarg3);
|
public final static native boolean MediaSessionMgr_defaultsSetStunServer(String jarg1, int jarg2);
|
||||||
public final static native boolean MediaSessionMgr_defaultsSetStunServer__SWIG_2(String jarg1, int jarg2);
|
public final static native boolean MediaSessionMgr_defaultsSetStunCred(String jarg1, String jarg2);
|
||||||
public final static native boolean MediaSessionMgr_defaultsSetIceEnabled(boolean jarg1);
|
public final static native boolean MediaSessionMgr_defaultsSetIceEnabled(boolean jarg1);
|
||||||
public final static native boolean MediaSessionMgr_defaultsSetByPassEncoding(boolean jarg1);
|
public final static native boolean MediaSessionMgr_defaultsSetByPassEncoding(boolean jarg1);
|
||||||
public final static native boolean MediaSessionMgr_defaultsGetByPassEncoding();
|
public final static native boolean MediaSessionMgr_defaultsGetByPassEncoding();
|
||||||
|
@ -266,6 +266,10 @@ public class tinyWRAPJNI {
|
||||||
public final static native boolean CallSession_setSRtpMode(long jarg1, CallSession jarg1_, int jarg2);
|
public final static native boolean CallSession_setSRtpMode(long jarg1, CallSession jarg1_, int jarg2);
|
||||||
public final static native boolean CallSession_setAvpfMode(long jarg1, CallSession jarg1_, int jarg2);
|
public final static native boolean CallSession_setAvpfMode(long jarg1, CallSession jarg1_, int jarg2);
|
||||||
public final static native boolean CallSession_setICE(long jarg1, CallSession jarg1_, boolean jarg2);
|
public final static native boolean CallSession_setICE(long jarg1, CallSession jarg1_, boolean jarg2);
|
||||||
|
public final static native boolean CallSession_setICEStun(long jarg1, CallSession jarg1_, boolean jarg2);
|
||||||
|
public final static native boolean CallSession_setICETurn(long jarg1, CallSession jarg1_, boolean jarg2);
|
||||||
|
public final static native boolean CallSession_setSTUNServer(long jarg1, CallSession jarg1_, String jarg2, int jarg3);
|
||||||
|
public final static native boolean CallSession_setSTUNCred(long jarg1, CallSession jarg1_, String jarg2, String jarg3);
|
||||||
public final static native boolean CallSession_setQoS(long jarg1, CallSession jarg1_, int jarg2, int jarg3);
|
public final static native boolean CallSession_setQoS(long jarg1, CallSession jarg1_, int jarg2, int jarg3);
|
||||||
public final static native boolean CallSession_hold__SWIG_0(long jarg1, CallSession jarg1_, long jarg2, ActionConfig jarg2_);
|
public final static native boolean CallSession_hold__SWIG_0(long jarg1, CallSession jarg1_, long jarg2, ActionConfig jarg2_);
|
||||||
public final static native boolean CallSession_hold__SWIG_1(long jarg1, CallSession jarg1_);
|
public final static native boolean CallSession_hold__SWIG_1(long jarg1, CallSession jarg1_);
|
||||||
|
|
|
@ -3460,70 +3460,21 @@ SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionM
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetStunServer_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jstring jarg1, jint jarg2, jstring jarg3, jstring jarg4) {
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetIceTurnEnabled(JNIEnv *jenv, jclass jcls, jboolean jarg1) {
|
||||||
jboolean jresult = 0 ;
|
jboolean jresult = 0 ;
|
||||||
char *arg1 = (char *) 0 ;
|
bool arg1 ;
|
||||||
uint16_t arg2 ;
|
|
||||||
char *arg3 = (char *) 0 ;
|
|
||||||
char *arg4 = (char *) 0 ;
|
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
(void)jenv;
|
(void)jenv;
|
||||||
(void)jcls;
|
(void)jcls;
|
||||||
arg1 = 0;
|
arg1 = jarg1 ? true : false;
|
||||||
if (jarg1) {
|
result = (bool)MediaSessionMgr::defaultsSetIceTurnEnabled(arg1);
|
||||||
arg1 = (char *)jenv->GetStringUTFChars(jarg1, 0);
|
|
||||||
if (!arg1) return 0;
|
|
||||||
}
|
|
||||||
arg2 = (uint16_t)jarg2;
|
|
||||||
arg3 = 0;
|
|
||||||
if (jarg3) {
|
|
||||||
arg3 = (char *)jenv->GetStringUTFChars(jarg3, 0);
|
|
||||||
if (!arg3) return 0;
|
|
||||||
}
|
|
||||||
arg4 = 0;
|
|
||||||
if (jarg4) {
|
|
||||||
arg4 = (char *)jenv->GetStringUTFChars(jarg4, 0);
|
|
||||||
if (!arg4) return 0;
|
|
||||||
}
|
|
||||||
result = (bool)MediaSessionMgr::defaultsSetStunServer((char const *)arg1,arg2,(char const *)arg3,(char const *)arg4);
|
|
||||||
jresult = (jboolean)result;
|
jresult = (jboolean)result;
|
||||||
if (arg1) jenv->ReleaseStringUTFChars(jarg1, (const char *)arg1);
|
|
||||||
if (arg3) jenv->ReleaseStringUTFChars(jarg3, (const char *)arg3);
|
|
||||||
if (arg4) jenv->ReleaseStringUTFChars(jarg4, (const char *)arg4);
|
|
||||||
return jresult;
|
return jresult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetStunServer_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jstring jarg1, jint jarg2, jstring jarg3) {
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetStunServer(JNIEnv *jenv, jclass jcls, jstring jarg1, jint jarg2) {
|
||||||
jboolean jresult = 0 ;
|
|
||||||
char *arg1 = (char *) 0 ;
|
|
||||||
uint16_t arg2 ;
|
|
||||||
char *arg3 = (char *) 0 ;
|
|
||||||
bool result;
|
|
||||||
|
|
||||||
(void)jenv;
|
|
||||||
(void)jcls;
|
|
||||||
arg1 = 0;
|
|
||||||
if (jarg1) {
|
|
||||||
arg1 = (char *)jenv->GetStringUTFChars(jarg1, 0);
|
|
||||||
if (!arg1) return 0;
|
|
||||||
}
|
|
||||||
arg2 = (uint16_t)jarg2;
|
|
||||||
arg3 = 0;
|
|
||||||
if (jarg3) {
|
|
||||||
arg3 = (char *)jenv->GetStringUTFChars(jarg3, 0);
|
|
||||||
if (!arg3) return 0;
|
|
||||||
}
|
|
||||||
result = (bool)MediaSessionMgr::defaultsSetStunServer((char const *)arg1,arg2,(char const *)arg3);
|
|
||||||
jresult = (jboolean)result;
|
|
||||||
if (arg1) jenv->ReleaseStringUTFChars(jarg1, (const char *)arg1);
|
|
||||||
if (arg3) jenv->ReleaseStringUTFChars(jarg3, (const char *)arg3);
|
|
||||||
return jresult;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetStunServer_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jstring jarg1, jint jarg2) {
|
|
||||||
jboolean jresult = 0 ;
|
jboolean jresult = 0 ;
|
||||||
char *arg1 = (char *) 0 ;
|
char *arg1 = (char *) 0 ;
|
||||||
uint16_t arg2 ;
|
uint16_t arg2 ;
|
||||||
|
@ -3544,6 +3495,32 @@ SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionM
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetStunCred(JNIEnv *jenv, jclass jcls, jstring jarg1, jstring jarg2) {
|
||||||
|
jboolean jresult = 0 ;
|
||||||
|
char *arg1 = (char *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
(void)jenv;
|
||||||
|
(void)jcls;
|
||||||
|
arg1 = 0;
|
||||||
|
if (jarg1) {
|
||||||
|
arg1 = (char *)jenv->GetStringUTFChars(jarg1, 0);
|
||||||
|
if (!arg1) return 0;
|
||||||
|
}
|
||||||
|
arg2 = 0;
|
||||||
|
if (jarg2) {
|
||||||
|
arg2 = (char *)jenv->GetStringUTFChars(jarg2, 0);
|
||||||
|
if (!arg2) return 0;
|
||||||
|
}
|
||||||
|
result = (bool)MediaSessionMgr::defaultsSetStunCred((char const *)arg1,(char const *)arg2);
|
||||||
|
jresult = (jboolean)result;
|
||||||
|
if (arg1) jenv->ReleaseStringUTFChars(jarg1, (const char *)arg1);
|
||||||
|
if (arg2) jenv->ReleaseStringUTFChars(jarg2, (const char *)arg2);
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetIceEnabled(JNIEnv *jenv, jclass jcls, jboolean jarg1) {
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_MediaSessionMgr_1defaultsSetIceEnabled(JNIEnv *jenv, jclass jcls, jboolean jarg1) {
|
||||||
jboolean jresult = 0 ;
|
jboolean jresult = 0 ;
|
||||||
bool arg1 ;
|
bool arg1 ;
|
||||||
|
@ -6195,6 +6172,93 @@ SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_CallSession_1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_CallSession_1setICEStun(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jboolean jarg2) {
|
||||||
|
jboolean jresult = 0 ;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
bool arg2 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
(void)jenv;
|
||||||
|
(void)jcls;
|
||||||
|
(void)jarg1_;
|
||||||
|
arg1 = *(CallSession **)&jarg1;
|
||||||
|
arg2 = jarg2 ? true : false;
|
||||||
|
result = (bool)(arg1)->setICEStun(arg2);
|
||||||
|
jresult = (jboolean)result;
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_CallSession_1setICETurn(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jboolean jarg2) {
|
||||||
|
jboolean jresult = 0 ;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
bool arg2 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
(void)jenv;
|
||||||
|
(void)jcls;
|
||||||
|
(void)jarg1_;
|
||||||
|
arg1 = *(CallSession **)&jarg1;
|
||||||
|
arg2 = jarg2 ? true : false;
|
||||||
|
result = (bool)(arg1)->setICETurn(arg2);
|
||||||
|
jresult = (jboolean)result;
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_CallSession_1setSTUNServer(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2, jint jarg3) {
|
||||||
|
jboolean jresult = 0 ;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
uint16_t arg3 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
(void)jenv;
|
||||||
|
(void)jcls;
|
||||||
|
(void)jarg1_;
|
||||||
|
arg1 = *(CallSession **)&jarg1;
|
||||||
|
arg2 = 0;
|
||||||
|
if (jarg2) {
|
||||||
|
arg2 = (char *)jenv->GetStringUTFChars(jarg2, 0);
|
||||||
|
if (!arg2) return 0;
|
||||||
|
}
|
||||||
|
arg3 = (uint16_t)jarg3;
|
||||||
|
result = (bool)(arg1)->setSTUNServer((char const *)arg2,arg3);
|
||||||
|
jresult = (jboolean)result;
|
||||||
|
if (arg2) jenv->ReleaseStringUTFChars(jarg2, (const char *)arg2);
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_CallSession_1setSTUNCred(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2, jstring jarg3) {
|
||||||
|
jboolean jresult = 0 ;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
char *arg3 = (char *) 0 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
(void)jenv;
|
||||||
|
(void)jcls;
|
||||||
|
(void)jarg1_;
|
||||||
|
arg1 = *(CallSession **)&jarg1;
|
||||||
|
arg2 = 0;
|
||||||
|
if (jarg2) {
|
||||||
|
arg2 = (char *)jenv->GetStringUTFChars(jarg2, 0);
|
||||||
|
if (!arg2) return 0;
|
||||||
|
}
|
||||||
|
arg3 = 0;
|
||||||
|
if (jarg3) {
|
||||||
|
arg3 = (char *)jenv->GetStringUTFChars(jarg3, 0);
|
||||||
|
if (!arg3) return 0;
|
||||||
|
}
|
||||||
|
result = (bool)(arg1)->setSTUNCred((char const *)arg2,(char const *)arg3);
|
||||||
|
jresult = (jboolean)result;
|
||||||
|
if (arg2) jenv->ReleaseStringUTFChars(jarg2, (const char *)arg2);
|
||||||
|
if (arg3) jenv->ReleaseStringUTFChars(jarg3, (const char *)arg3);
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_CallSession_1setQoS(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3) {
|
SWIGEXPORT jboolean JNICALL Java_org_doubango_tinyWRAP_tinyWRAPJNI_CallSession_1setQoS(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3) {
|
||||||
jboolean jresult = 0 ;
|
jboolean jresult = 0 ;
|
||||||
CallSession *arg1 = (CallSession *) 0 ;
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
|
|
@ -291,7 +291,9 @@ sub DESTROY {
|
||||||
*defaultsGetRtcpMuxEnabled = *tinyWRAPc::MediaSessionMgr_defaultsGetRtcpMuxEnabled;
|
*defaultsGetRtcpMuxEnabled = *tinyWRAPc::MediaSessionMgr_defaultsGetRtcpMuxEnabled;
|
||||||
*defaultsSetStunEnabled = *tinyWRAPc::MediaSessionMgr_defaultsSetStunEnabled;
|
*defaultsSetStunEnabled = *tinyWRAPc::MediaSessionMgr_defaultsSetStunEnabled;
|
||||||
*defaultsSetIceStunEnabled = *tinyWRAPc::MediaSessionMgr_defaultsSetIceStunEnabled;
|
*defaultsSetIceStunEnabled = *tinyWRAPc::MediaSessionMgr_defaultsSetIceStunEnabled;
|
||||||
|
*defaultsSetIceTurnEnabled = *tinyWRAPc::MediaSessionMgr_defaultsSetIceTurnEnabled;
|
||||||
*defaultsSetStunServer = *tinyWRAPc::MediaSessionMgr_defaultsSetStunServer;
|
*defaultsSetStunServer = *tinyWRAPc::MediaSessionMgr_defaultsSetStunServer;
|
||||||
|
*defaultsSetStunCred = *tinyWRAPc::MediaSessionMgr_defaultsSetStunCred;
|
||||||
*defaultsSetIceEnabled = *tinyWRAPc::MediaSessionMgr_defaultsSetIceEnabled;
|
*defaultsSetIceEnabled = *tinyWRAPc::MediaSessionMgr_defaultsSetIceEnabled;
|
||||||
*defaultsSetByPassEncoding = *tinyWRAPc::MediaSessionMgr_defaultsSetByPassEncoding;
|
*defaultsSetByPassEncoding = *tinyWRAPc::MediaSessionMgr_defaultsSetByPassEncoding;
|
||||||
*defaultsGetByPassEncoding = *tinyWRAPc::MediaSessionMgr_defaultsGetByPassEncoding;
|
*defaultsGetByPassEncoding = *tinyWRAPc::MediaSessionMgr_defaultsGetByPassEncoding;
|
||||||
|
@ -1058,6 +1060,10 @@ sub DESTROY {
|
||||||
*setSRtpMode = *tinyWRAPc::CallSession_setSRtpMode;
|
*setSRtpMode = *tinyWRAPc::CallSession_setSRtpMode;
|
||||||
*setAvpfMode = *tinyWRAPc::CallSession_setAvpfMode;
|
*setAvpfMode = *tinyWRAPc::CallSession_setAvpfMode;
|
||||||
*setICE = *tinyWRAPc::CallSession_setICE;
|
*setICE = *tinyWRAPc::CallSession_setICE;
|
||||||
|
*setICEStun = *tinyWRAPc::CallSession_setICEStun;
|
||||||
|
*setICETurn = *tinyWRAPc::CallSession_setICETurn;
|
||||||
|
*setSTUNServer = *tinyWRAPc::CallSession_setSTUNServer;
|
||||||
|
*setSTUNCred = *tinyWRAPc::CallSession_setSTUNCred;
|
||||||
*setQoS = *tinyWRAPc::CallSession_setQoS;
|
*setQoS = *tinyWRAPc::CallSession_setQoS;
|
||||||
*hold = *tinyWRAPc::CallSession_hold;
|
*hold = *tinyWRAPc::CallSession_hold;
|
||||||
*resume = *tinyWRAPc::CallSession_resume;
|
*resume = *tinyWRAPc::CallSession_resume;
|
||||||
|
|
|
@ -5158,118 +5158,35 @@ XS(_wrap_MediaSessionMgr_defaultsSetIceStunEnabled) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XS(_wrap_MediaSessionMgr_defaultsSetStunServer__SWIG_0) {
|
XS(_wrap_MediaSessionMgr_defaultsSetIceTurnEnabled) {
|
||||||
{
|
{
|
||||||
char *arg1 = (char *) 0 ;
|
bool arg1 ;
|
||||||
uint16_t arg2 ;
|
bool val1 ;
|
||||||
char *arg3 = (char *) 0 ;
|
int ecode1 = 0 ;
|
||||||
char *arg4 = (char *) 0 ;
|
|
||||||
int res1 ;
|
|
||||||
char *buf1 = 0 ;
|
|
||||||
int alloc1 = 0 ;
|
|
||||||
unsigned short val2 ;
|
|
||||||
int ecode2 = 0 ;
|
|
||||||
int res3 ;
|
|
||||||
char *buf3 = 0 ;
|
|
||||||
int alloc3 = 0 ;
|
|
||||||
int res4 ;
|
|
||||||
char *buf4 = 0 ;
|
|
||||||
int alloc4 = 0 ;
|
|
||||||
int argvi = 0;
|
int argvi = 0;
|
||||||
bool result;
|
bool result;
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
|
|
||||||
if ((items < 4) || (items > 4)) {
|
if ((items < 1) || (items > 1)) {
|
||||||
SWIG_croak("Usage: MediaSessionMgr_defaultsSetStunServer(server_ip,server_port,usr_name,usr_pwd);");
|
SWIG_croak("Usage: MediaSessionMgr_defaultsSetIceTurnEnabled(iceturn_enabled);");
|
||||||
}
|
}
|
||||||
res1 = SWIG_AsCharPtrAndSize(ST(0), &buf1, NULL, &alloc1);
|
ecode1 = SWIG_AsVal_bool SWIG_PERL_CALL_ARGS_2(ST(0), &val1);
|
||||||
if (!SWIG_IsOK(res1)) {
|
if (!SWIG_IsOK(ecode1)) {
|
||||||
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MediaSessionMgr_defaultsSetStunServer" "', argument " "1"" of type '" "char const *""'");
|
SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "MediaSessionMgr_defaultsSetIceTurnEnabled" "', argument " "1"" of type '" "bool""'");
|
||||||
}
|
}
|
||||||
arg1 = reinterpret_cast< char * >(buf1);
|
arg1 = static_cast< bool >(val1);
|
||||||
ecode2 = SWIG_AsVal_unsigned_SS_short SWIG_PERL_CALL_ARGS_2(ST(1), &val2);
|
result = (bool)MediaSessionMgr::defaultsSetIceTurnEnabled(arg1);
|
||||||
if (!SWIG_IsOK(ecode2)) {
|
|
||||||
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MediaSessionMgr_defaultsSetStunServer" "', argument " "2"" of type '" "uint16_t""'");
|
|
||||||
}
|
|
||||||
arg2 = static_cast< uint16_t >(val2);
|
|
||||||
res3 = SWIG_AsCharPtrAndSize(ST(2), &buf3, NULL, &alloc3);
|
|
||||||
if (!SWIG_IsOK(res3)) {
|
|
||||||
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "MediaSessionMgr_defaultsSetStunServer" "', argument " "3"" of type '" "char const *""'");
|
|
||||||
}
|
|
||||||
arg3 = reinterpret_cast< char * >(buf3);
|
|
||||||
res4 = SWIG_AsCharPtrAndSize(ST(3), &buf4, NULL, &alloc4);
|
|
||||||
if (!SWIG_IsOK(res4)) {
|
|
||||||
SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "MediaSessionMgr_defaultsSetStunServer" "', argument " "4"" of type '" "char const *""'");
|
|
||||||
}
|
|
||||||
arg4 = reinterpret_cast< char * >(buf4);
|
|
||||||
result = (bool)MediaSessionMgr::defaultsSetStunServer((char const *)arg1,arg2,(char const *)arg3,(char const *)arg4);
|
|
||||||
ST(argvi) = SWIG_From_bool SWIG_PERL_CALL_ARGS_1(static_cast< bool >(result)); argvi++ ;
|
ST(argvi) = SWIG_From_bool SWIG_PERL_CALL_ARGS_1(static_cast< bool >(result)); argvi++ ;
|
||||||
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
|
||||||
|
|
||||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
|
||||||
if (alloc4 == SWIG_NEWOBJ) delete[] buf4;
|
|
||||||
XSRETURN(argvi);
|
XSRETURN(argvi);
|
||||||
fail:
|
fail:
|
||||||
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
|
||||||
|
|
||||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
|
||||||
if (alloc4 == SWIG_NEWOBJ) delete[] buf4;
|
|
||||||
SWIG_croak_null();
|
SWIG_croak_null();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XS(_wrap_MediaSessionMgr_defaultsSetStunServer__SWIG_1) {
|
XS(_wrap_MediaSessionMgr_defaultsSetStunServer) {
|
||||||
{
|
|
||||||
char *arg1 = (char *) 0 ;
|
|
||||||
uint16_t arg2 ;
|
|
||||||
char *arg3 = (char *) 0 ;
|
|
||||||
int res1 ;
|
|
||||||
char *buf1 = 0 ;
|
|
||||||
int alloc1 = 0 ;
|
|
||||||
unsigned short val2 ;
|
|
||||||
int ecode2 = 0 ;
|
|
||||||
int res3 ;
|
|
||||||
char *buf3 = 0 ;
|
|
||||||
int alloc3 = 0 ;
|
|
||||||
int argvi = 0;
|
|
||||||
bool result;
|
|
||||||
dXSARGS;
|
|
||||||
|
|
||||||
if ((items < 3) || (items > 3)) {
|
|
||||||
SWIG_croak("Usage: MediaSessionMgr_defaultsSetStunServer(server_ip,server_port,usr_name);");
|
|
||||||
}
|
|
||||||
res1 = SWIG_AsCharPtrAndSize(ST(0), &buf1, NULL, &alloc1);
|
|
||||||
if (!SWIG_IsOK(res1)) {
|
|
||||||
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MediaSessionMgr_defaultsSetStunServer" "', argument " "1"" of type '" "char const *""'");
|
|
||||||
}
|
|
||||||
arg1 = reinterpret_cast< char * >(buf1);
|
|
||||||
ecode2 = SWIG_AsVal_unsigned_SS_short SWIG_PERL_CALL_ARGS_2(ST(1), &val2);
|
|
||||||
if (!SWIG_IsOK(ecode2)) {
|
|
||||||
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MediaSessionMgr_defaultsSetStunServer" "', argument " "2"" of type '" "uint16_t""'");
|
|
||||||
}
|
|
||||||
arg2 = static_cast< uint16_t >(val2);
|
|
||||||
res3 = SWIG_AsCharPtrAndSize(ST(2), &buf3, NULL, &alloc3);
|
|
||||||
if (!SWIG_IsOK(res3)) {
|
|
||||||
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "MediaSessionMgr_defaultsSetStunServer" "', argument " "3"" of type '" "char const *""'");
|
|
||||||
}
|
|
||||||
arg3 = reinterpret_cast< char * >(buf3);
|
|
||||||
result = (bool)MediaSessionMgr::defaultsSetStunServer((char const *)arg1,arg2,(char const *)arg3);
|
|
||||||
ST(argvi) = SWIG_From_bool SWIG_PERL_CALL_ARGS_1(static_cast< bool >(result)); argvi++ ;
|
|
||||||
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
|
||||||
|
|
||||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
|
||||||
XSRETURN(argvi);
|
|
||||||
fail:
|
|
||||||
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
|
||||||
|
|
||||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
|
||||||
SWIG_croak_null();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
XS(_wrap_MediaSessionMgr_defaultsSetStunServer__SWIG_2) {
|
|
||||||
{
|
{
|
||||||
char *arg1 = (char *) 0 ;
|
char *arg1 = (char *) 0 ;
|
||||||
uint16_t arg2 ;
|
uint16_t arg2 ;
|
||||||
|
@ -5308,139 +5225,43 @@ XS(_wrap_MediaSessionMgr_defaultsSetStunServer__SWIG_2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XS(_wrap_MediaSessionMgr_defaultsSetStunServer) {
|
XS(_wrap_MediaSessionMgr_defaultsSetStunCred) {
|
||||||
|
{
|
||||||
|
char *arg1 = (char *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
int res1 ;
|
||||||
|
char *buf1 = 0 ;
|
||||||
|
int alloc1 = 0 ;
|
||||||
|
int res2 ;
|
||||||
|
char *buf2 = 0 ;
|
||||||
|
int alloc2 = 0 ;
|
||||||
|
int argvi = 0;
|
||||||
|
bool result;
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
|
|
||||||
{
|
if ((items < 2) || (items > 2)) {
|
||||||
unsigned long _index = 0;
|
SWIG_croak("Usage: MediaSessionMgr_defaultsSetStunCred(username,password);");
|
||||||
SWIG_TypeRank _rank = 0;
|
|
||||||
if (items == 2) {
|
|
||||||
SWIG_TypeRank _ranki = 0;
|
|
||||||
SWIG_TypeRank _rankm = 0;
|
|
||||||
SWIG_TypeRank _pi = 1;
|
|
||||||
int _v = 0;
|
|
||||||
{
|
|
||||||
int res = SWIG_AsCharPtrAndSize(ST(0), 0, NULL, 0);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
}
|
}
|
||||||
if (!_v) goto check_1;
|
res1 = SWIG_AsCharPtrAndSize(ST(0), &buf1, NULL, &alloc1);
|
||||||
_ranki += _v*_pi;
|
if (!SWIG_IsOK(res1)) {
|
||||||
_rankm += _pi;
|
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MediaSessionMgr_defaultsSetStunCred" "', argument " "1"" of type '" "char const *""'");
|
||||||
_pi *= SWIG_MAXCASTRANK;
|
|
||||||
{
|
|
||||||
{
|
|
||||||
int res = SWIG_AsVal_unsigned_SS_short SWIG_PERL_CALL_ARGS_2(ST(1), NULL);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
}
|
}
|
||||||
|
arg1 = reinterpret_cast< char * >(buf1);
|
||||||
|
res2 = SWIG_AsCharPtrAndSize(ST(1), &buf2, NULL, &alloc2);
|
||||||
|
if (!SWIG_IsOK(res2)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MediaSessionMgr_defaultsSetStunCred" "', argument " "2"" of type '" "char const *""'");
|
||||||
}
|
}
|
||||||
if (!_v) goto check_1;
|
arg2 = reinterpret_cast< char * >(buf2);
|
||||||
_ranki += _v*_pi;
|
result = (bool)MediaSessionMgr::defaultsSetStunCred((char const *)arg1,(char const *)arg2);
|
||||||
_rankm += _pi;
|
ST(argvi) = SWIG_From_bool SWIG_PERL_CALL_ARGS_1(static_cast< bool >(result)); argvi++ ;
|
||||||
_pi *= SWIG_MAXCASTRANK;
|
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
||||||
if (!_index || (_ranki < _rank)) {
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
_rank = _ranki; _index = 1;
|
XSRETURN(argvi);
|
||||||
if (_rank == _rankm) goto dispatch;
|
fail:
|
||||||
|
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
||||||
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
|
SWIG_croak_null();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
check_1:
|
|
||||||
|
|
||||||
if (items == 3) {
|
|
||||||
SWIG_TypeRank _ranki = 0;
|
|
||||||
SWIG_TypeRank _rankm = 0;
|
|
||||||
SWIG_TypeRank _pi = 1;
|
|
||||||
int _v = 0;
|
|
||||||
{
|
|
||||||
int res = SWIG_AsCharPtrAndSize(ST(0), 0, NULL, 0);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
}
|
|
||||||
if (!_v) goto check_2;
|
|
||||||
_ranki += _v*_pi;
|
|
||||||
_rankm += _pi;
|
|
||||||
_pi *= SWIG_MAXCASTRANK;
|
|
||||||
{
|
|
||||||
{
|
|
||||||
int res = SWIG_AsVal_unsigned_SS_short SWIG_PERL_CALL_ARGS_2(ST(1), NULL);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!_v) goto check_2;
|
|
||||||
_ranki += _v*_pi;
|
|
||||||
_rankm += _pi;
|
|
||||||
_pi *= SWIG_MAXCASTRANK;
|
|
||||||
{
|
|
||||||
int res = SWIG_AsCharPtrAndSize(ST(2), 0, NULL, 0);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
}
|
|
||||||
if (!_v) goto check_2;
|
|
||||||
_ranki += _v*_pi;
|
|
||||||
_rankm += _pi;
|
|
||||||
_pi *= SWIG_MAXCASTRANK;
|
|
||||||
if (!_index || (_ranki < _rank)) {
|
|
||||||
_rank = _ranki; _index = 2;
|
|
||||||
if (_rank == _rankm) goto dispatch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
check_2:
|
|
||||||
|
|
||||||
if (items == 4) {
|
|
||||||
SWIG_TypeRank _ranki = 0;
|
|
||||||
SWIG_TypeRank _rankm = 0;
|
|
||||||
SWIG_TypeRank _pi = 1;
|
|
||||||
int _v = 0;
|
|
||||||
{
|
|
||||||
int res = SWIG_AsCharPtrAndSize(ST(0), 0, NULL, 0);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
}
|
|
||||||
if (!_v) goto check_3;
|
|
||||||
_ranki += _v*_pi;
|
|
||||||
_rankm += _pi;
|
|
||||||
_pi *= SWIG_MAXCASTRANK;
|
|
||||||
{
|
|
||||||
{
|
|
||||||
int res = SWIG_AsVal_unsigned_SS_short SWIG_PERL_CALL_ARGS_2(ST(1), NULL);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!_v) goto check_3;
|
|
||||||
_ranki += _v*_pi;
|
|
||||||
_rankm += _pi;
|
|
||||||
_pi *= SWIG_MAXCASTRANK;
|
|
||||||
{
|
|
||||||
int res = SWIG_AsCharPtrAndSize(ST(2), 0, NULL, 0);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
}
|
|
||||||
if (!_v) goto check_3;
|
|
||||||
_ranki += _v*_pi;
|
|
||||||
_rankm += _pi;
|
|
||||||
_pi *= SWIG_MAXCASTRANK;
|
|
||||||
{
|
|
||||||
int res = SWIG_AsCharPtrAndSize(ST(3), 0, NULL, 0);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
}
|
|
||||||
if (!_v) goto check_3;
|
|
||||||
_ranki += _v*_pi;
|
|
||||||
_rankm += _pi;
|
|
||||||
_pi *= SWIG_MAXCASTRANK;
|
|
||||||
if (!_index || (_ranki < _rank)) {
|
|
||||||
_rank = _ranki; _index = 3;
|
|
||||||
if (_rank == _rankm) goto dispatch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
check_3:
|
|
||||||
|
|
||||||
dispatch:
|
|
||||||
switch(_index) {
|
|
||||||
case 1:
|
|
||||||
PUSHMARK(MARK); SWIG_CALLXS(_wrap_MediaSessionMgr_defaultsSetStunServer__SWIG_2); return;
|
|
||||||
case 2:
|
|
||||||
PUSHMARK(MARK); SWIG_CALLXS(_wrap_MediaSessionMgr_defaultsSetStunServer__SWIG_1); return;
|
|
||||||
case 3:
|
|
||||||
PUSHMARK(MARK); SWIG_CALLXS(_wrap_MediaSessionMgr_defaultsSetStunServer__SWIG_0); return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
croak("No matching function for overloaded 'MediaSessionMgr_defaultsSetStunServer'");
|
|
||||||
XSRETURN(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -12422,6 +12243,181 @@ XS(_wrap_CallSession_setICE) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
XS(_wrap_CallSession_setICEStun) {
|
||||||
|
{
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
bool arg2 ;
|
||||||
|
void *argp1 = 0 ;
|
||||||
|
int res1 = 0 ;
|
||||||
|
bool val2 ;
|
||||||
|
int ecode2 = 0 ;
|
||||||
|
int argvi = 0;
|
||||||
|
bool result;
|
||||||
|
dXSARGS;
|
||||||
|
|
||||||
|
if ((items < 2) || (items > 2)) {
|
||||||
|
SWIG_croak("Usage: CallSession_setICEStun(self,enabled);");
|
||||||
|
}
|
||||||
|
res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_CallSession, 0 | 0 );
|
||||||
|
if (!SWIG_IsOK(res1)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CallSession_setICEStun" "', argument " "1"" of type '" "CallSession *""'");
|
||||||
|
}
|
||||||
|
arg1 = reinterpret_cast< CallSession * >(argp1);
|
||||||
|
ecode2 = SWIG_AsVal_bool SWIG_PERL_CALL_ARGS_2(ST(1), &val2);
|
||||||
|
if (!SWIG_IsOK(ecode2)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "CallSession_setICEStun" "', argument " "2"" of type '" "bool""'");
|
||||||
|
}
|
||||||
|
arg2 = static_cast< bool >(val2);
|
||||||
|
result = (bool)(arg1)->setICEStun(arg2);
|
||||||
|
ST(argvi) = SWIG_From_bool SWIG_PERL_CALL_ARGS_1(static_cast< bool >(result)); argvi++ ;
|
||||||
|
|
||||||
|
|
||||||
|
XSRETURN(argvi);
|
||||||
|
fail:
|
||||||
|
|
||||||
|
|
||||||
|
SWIG_croak_null();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
XS(_wrap_CallSession_setICETurn) {
|
||||||
|
{
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
bool arg2 ;
|
||||||
|
void *argp1 = 0 ;
|
||||||
|
int res1 = 0 ;
|
||||||
|
bool val2 ;
|
||||||
|
int ecode2 = 0 ;
|
||||||
|
int argvi = 0;
|
||||||
|
bool result;
|
||||||
|
dXSARGS;
|
||||||
|
|
||||||
|
if ((items < 2) || (items > 2)) {
|
||||||
|
SWIG_croak("Usage: CallSession_setICETurn(self,enabled);");
|
||||||
|
}
|
||||||
|
res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_CallSession, 0 | 0 );
|
||||||
|
if (!SWIG_IsOK(res1)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CallSession_setICETurn" "', argument " "1"" of type '" "CallSession *""'");
|
||||||
|
}
|
||||||
|
arg1 = reinterpret_cast< CallSession * >(argp1);
|
||||||
|
ecode2 = SWIG_AsVal_bool SWIG_PERL_CALL_ARGS_2(ST(1), &val2);
|
||||||
|
if (!SWIG_IsOK(ecode2)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "CallSession_setICETurn" "', argument " "2"" of type '" "bool""'");
|
||||||
|
}
|
||||||
|
arg2 = static_cast< bool >(val2);
|
||||||
|
result = (bool)(arg1)->setICETurn(arg2);
|
||||||
|
ST(argvi) = SWIG_From_bool SWIG_PERL_CALL_ARGS_1(static_cast< bool >(result)); argvi++ ;
|
||||||
|
|
||||||
|
|
||||||
|
XSRETURN(argvi);
|
||||||
|
fail:
|
||||||
|
|
||||||
|
|
||||||
|
SWIG_croak_null();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
XS(_wrap_CallSession_setSTUNServer) {
|
||||||
|
{
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
uint16_t arg3 ;
|
||||||
|
void *argp1 = 0 ;
|
||||||
|
int res1 = 0 ;
|
||||||
|
int res2 ;
|
||||||
|
char *buf2 = 0 ;
|
||||||
|
int alloc2 = 0 ;
|
||||||
|
unsigned short val3 ;
|
||||||
|
int ecode3 = 0 ;
|
||||||
|
int argvi = 0;
|
||||||
|
bool result;
|
||||||
|
dXSARGS;
|
||||||
|
|
||||||
|
if ((items < 3) || (items > 3)) {
|
||||||
|
SWIG_croak("Usage: CallSession_setSTUNServer(self,hostname,port);");
|
||||||
|
}
|
||||||
|
res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_CallSession, 0 | 0 );
|
||||||
|
if (!SWIG_IsOK(res1)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CallSession_setSTUNServer" "', argument " "1"" of type '" "CallSession *""'");
|
||||||
|
}
|
||||||
|
arg1 = reinterpret_cast< CallSession * >(argp1);
|
||||||
|
res2 = SWIG_AsCharPtrAndSize(ST(1), &buf2, NULL, &alloc2);
|
||||||
|
if (!SWIG_IsOK(res2)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CallSession_setSTUNServer" "', argument " "2"" of type '" "char const *""'");
|
||||||
|
}
|
||||||
|
arg2 = reinterpret_cast< char * >(buf2);
|
||||||
|
ecode3 = SWIG_AsVal_unsigned_SS_short SWIG_PERL_CALL_ARGS_2(ST(2), &val3);
|
||||||
|
if (!SWIG_IsOK(ecode3)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "CallSession_setSTUNServer" "', argument " "3"" of type '" "uint16_t""'");
|
||||||
|
}
|
||||||
|
arg3 = static_cast< uint16_t >(val3);
|
||||||
|
result = (bool)(arg1)->setSTUNServer((char const *)arg2,arg3);
|
||||||
|
ST(argvi) = SWIG_From_bool SWIG_PERL_CALL_ARGS_1(static_cast< bool >(result)); argvi++ ;
|
||||||
|
|
||||||
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
|
|
||||||
|
XSRETURN(argvi);
|
||||||
|
fail:
|
||||||
|
|
||||||
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
|
|
||||||
|
SWIG_croak_null();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
XS(_wrap_CallSession_setSTUNCred) {
|
||||||
|
{
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
char *arg3 = (char *) 0 ;
|
||||||
|
void *argp1 = 0 ;
|
||||||
|
int res1 = 0 ;
|
||||||
|
int res2 ;
|
||||||
|
char *buf2 = 0 ;
|
||||||
|
int alloc2 = 0 ;
|
||||||
|
int res3 ;
|
||||||
|
char *buf3 = 0 ;
|
||||||
|
int alloc3 = 0 ;
|
||||||
|
int argvi = 0;
|
||||||
|
bool result;
|
||||||
|
dXSARGS;
|
||||||
|
|
||||||
|
if ((items < 3) || (items > 3)) {
|
||||||
|
SWIG_croak("Usage: CallSession_setSTUNCred(self,username,password);");
|
||||||
|
}
|
||||||
|
res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_CallSession, 0 | 0 );
|
||||||
|
if (!SWIG_IsOK(res1)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CallSession_setSTUNCred" "', argument " "1"" of type '" "CallSession *""'");
|
||||||
|
}
|
||||||
|
arg1 = reinterpret_cast< CallSession * >(argp1);
|
||||||
|
res2 = SWIG_AsCharPtrAndSize(ST(1), &buf2, NULL, &alloc2);
|
||||||
|
if (!SWIG_IsOK(res2)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CallSession_setSTUNCred" "', argument " "2"" of type '" "char const *""'");
|
||||||
|
}
|
||||||
|
arg2 = reinterpret_cast< char * >(buf2);
|
||||||
|
res3 = SWIG_AsCharPtrAndSize(ST(2), &buf3, NULL, &alloc3);
|
||||||
|
if (!SWIG_IsOK(res3)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "CallSession_setSTUNCred" "', argument " "3"" of type '" "char const *""'");
|
||||||
|
}
|
||||||
|
arg3 = reinterpret_cast< char * >(buf3);
|
||||||
|
result = (bool)(arg1)->setSTUNCred((char const *)arg2,(char const *)arg3);
|
||||||
|
ST(argvi) = SWIG_From_bool SWIG_PERL_CALL_ARGS_1(static_cast< bool >(result)); argvi++ ;
|
||||||
|
|
||||||
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
|
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||||
|
XSRETURN(argvi);
|
||||||
|
fail:
|
||||||
|
|
||||||
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
|
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||||
|
SWIG_croak_null();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
XS(_wrap_CallSession_setQoS) {
|
XS(_wrap_CallSession_setQoS) {
|
||||||
{
|
{
|
||||||
CallSession *arg1 = (CallSession *) 0 ;
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
@ -22411,7 +22407,7 @@ XS(_wrap_SipStack_setSTUNServer) {
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
|
|
||||||
if ((items < 3) || (items > 3)) {
|
if ((items < 3) || (items > 3)) {
|
||||||
SWIG_croak("Usage: SipStack_setSTUNServer(self,ip,port);");
|
SWIG_croak("Usage: SipStack_setSTUNServer(self,hostname,port);");
|
||||||
}
|
}
|
||||||
res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_SipStack, 0 | 0 );
|
res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_SipStack, 0 | 0 );
|
||||||
if (!SWIG_IsOK(res1)) {
|
if (!SWIG_IsOK(res1)) {
|
||||||
|
@ -27772,7 +27768,9 @@ static swig_command_info swig_commands[] = {
|
||||||
{"tinyWRAPc::MediaSessionMgr_defaultsGetRtcpMuxEnabled", _wrap_MediaSessionMgr_defaultsGetRtcpMuxEnabled},
|
{"tinyWRAPc::MediaSessionMgr_defaultsGetRtcpMuxEnabled", _wrap_MediaSessionMgr_defaultsGetRtcpMuxEnabled},
|
||||||
{"tinyWRAPc::MediaSessionMgr_defaultsSetStunEnabled", _wrap_MediaSessionMgr_defaultsSetStunEnabled},
|
{"tinyWRAPc::MediaSessionMgr_defaultsSetStunEnabled", _wrap_MediaSessionMgr_defaultsSetStunEnabled},
|
||||||
{"tinyWRAPc::MediaSessionMgr_defaultsSetIceStunEnabled", _wrap_MediaSessionMgr_defaultsSetIceStunEnabled},
|
{"tinyWRAPc::MediaSessionMgr_defaultsSetIceStunEnabled", _wrap_MediaSessionMgr_defaultsSetIceStunEnabled},
|
||||||
|
{"tinyWRAPc::MediaSessionMgr_defaultsSetIceTurnEnabled", _wrap_MediaSessionMgr_defaultsSetIceTurnEnabled},
|
||||||
{"tinyWRAPc::MediaSessionMgr_defaultsSetStunServer", _wrap_MediaSessionMgr_defaultsSetStunServer},
|
{"tinyWRAPc::MediaSessionMgr_defaultsSetStunServer", _wrap_MediaSessionMgr_defaultsSetStunServer},
|
||||||
|
{"tinyWRAPc::MediaSessionMgr_defaultsSetStunCred", _wrap_MediaSessionMgr_defaultsSetStunCred},
|
||||||
{"tinyWRAPc::MediaSessionMgr_defaultsSetIceEnabled", _wrap_MediaSessionMgr_defaultsSetIceEnabled},
|
{"tinyWRAPc::MediaSessionMgr_defaultsSetIceEnabled", _wrap_MediaSessionMgr_defaultsSetIceEnabled},
|
||||||
{"tinyWRAPc::MediaSessionMgr_defaultsSetByPassEncoding", _wrap_MediaSessionMgr_defaultsSetByPassEncoding},
|
{"tinyWRAPc::MediaSessionMgr_defaultsSetByPassEncoding", _wrap_MediaSessionMgr_defaultsSetByPassEncoding},
|
||||||
{"tinyWRAPc::MediaSessionMgr_defaultsGetByPassEncoding", _wrap_MediaSessionMgr_defaultsGetByPassEncoding},
|
{"tinyWRAPc::MediaSessionMgr_defaultsGetByPassEncoding", _wrap_MediaSessionMgr_defaultsGetByPassEncoding},
|
||||||
|
@ -27904,6 +27902,10 @@ static swig_command_info swig_commands[] = {
|
||||||
{"tinyWRAPc::CallSession_setSRtpMode", _wrap_CallSession_setSRtpMode},
|
{"tinyWRAPc::CallSession_setSRtpMode", _wrap_CallSession_setSRtpMode},
|
||||||
{"tinyWRAPc::CallSession_setAvpfMode", _wrap_CallSession_setAvpfMode},
|
{"tinyWRAPc::CallSession_setAvpfMode", _wrap_CallSession_setAvpfMode},
|
||||||
{"tinyWRAPc::CallSession_setICE", _wrap_CallSession_setICE},
|
{"tinyWRAPc::CallSession_setICE", _wrap_CallSession_setICE},
|
||||||
|
{"tinyWRAPc::CallSession_setICEStun", _wrap_CallSession_setICEStun},
|
||||||
|
{"tinyWRAPc::CallSession_setICETurn", _wrap_CallSession_setICETurn},
|
||||||
|
{"tinyWRAPc::CallSession_setSTUNServer", _wrap_CallSession_setSTUNServer},
|
||||||
|
{"tinyWRAPc::CallSession_setSTUNCred", _wrap_CallSession_setSTUNCred},
|
||||||
{"tinyWRAPc::CallSession_setQoS", _wrap_CallSession_setQoS},
|
{"tinyWRAPc::CallSession_setQoS", _wrap_CallSession_setQoS},
|
||||||
{"tinyWRAPc::CallSession_hold", _wrap_CallSession_hold},
|
{"tinyWRAPc::CallSession_hold", _wrap_CallSession_hold},
|
||||||
{"tinyWRAPc::CallSession_resume", _wrap_CallSession_resume},
|
{"tinyWRAPc::CallSession_resume", _wrap_CallSession_resume},
|
||||||
|
|
|
@ -289,8 +289,12 @@ class MediaSessionMgr(_object):
|
||||||
if _newclass:defaultsSetStunEnabled = staticmethod(_tinyWRAP.MediaSessionMgr_defaultsSetStunEnabled)
|
if _newclass:defaultsSetStunEnabled = staticmethod(_tinyWRAP.MediaSessionMgr_defaultsSetStunEnabled)
|
||||||
__swig_getmethods__["defaultsSetIceStunEnabled"] = lambda x: _tinyWRAP.MediaSessionMgr_defaultsSetIceStunEnabled
|
__swig_getmethods__["defaultsSetIceStunEnabled"] = lambda x: _tinyWRAP.MediaSessionMgr_defaultsSetIceStunEnabled
|
||||||
if _newclass:defaultsSetIceStunEnabled = staticmethod(_tinyWRAP.MediaSessionMgr_defaultsSetIceStunEnabled)
|
if _newclass:defaultsSetIceStunEnabled = staticmethod(_tinyWRAP.MediaSessionMgr_defaultsSetIceStunEnabled)
|
||||||
|
__swig_getmethods__["defaultsSetIceTurnEnabled"] = lambda x: _tinyWRAP.MediaSessionMgr_defaultsSetIceTurnEnabled
|
||||||
|
if _newclass:defaultsSetIceTurnEnabled = staticmethod(_tinyWRAP.MediaSessionMgr_defaultsSetIceTurnEnabled)
|
||||||
__swig_getmethods__["defaultsSetStunServer"] = lambda x: _tinyWRAP.MediaSessionMgr_defaultsSetStunServer
|
__swig_getmethods__["defaultsSetStunServer"] = lambda x: _tinyWRAP.MediaSessionMgr_defaultsSetStunServer
|
||||||
if _newclass:defaultsSetStunServer = staticmethod(_tinyWRAP.MediaSessionMgr_defaultsSetStunServer)
|
if _newclass:defaultsSetStunServer = staticmethod(_tinyWRAP.MediaSessionMgr_defaultsSetStunServer)
|
||||||
|
__swig_getmethods__["defaultsSetStunCred"] = lambda x: _tinyWRAP.MediaSessionMgr_defaultsSetStunCred
|
||||||
|
if _newclass:defaultsSetStunCred = staticmethod(_tinyWRAP.MediaSessionMgr_defaultsSetStunCred)
|
||||||
__swig_getmethods__["defaultsSetIceEnabled"] = lambda x: _tinyWRAP.MediaSessionMgr_defaultsSetIceEnabled
|
__swig_getmethods__["defaultsSetIceEnabled"] = lambda x: _tinyWRAP.MediaSessionMgr_defaultsSetIceEnabled
|
||||||
if _newclass:defaultsSetIceEnabled = staticmethod(_tinyWRAP.MediaSessionMgr_defaultsSetIceEnabled)
|
if _newclass:defaultsSetIceEnabled = staticmethod(_tinyWRAP.MediaSessionMgr_defaultsSetIceEnabled)
|
||||||
__swig_getmethods__["defaultsSetByPassEncoding"] = lambda x: _tinyWRAP.MediaSessionMgr_defaultsSetByPassEncoding
|
__swig_getmethods__["defaultsSetByPassEncoding"] = lambda x: _tinyWRAP.MediaSessionMgr_defaultsSetByPassEncoding
|
||||||
|
@ -526,10 +530,18 @@ def MediaSessionMgr_defaultsSetIceStunEnabled(*args):
|
||||||
return _tinyWRAP.MediaSessionMgr_defaultsSetIceStunEnabled(*args)
|
return _tinyWRAP.MediaSessionMgr_defaultsSetIceStunEnabled(*args)
|
||||||
MediaSessionMgr_defaultsSetIceStunEnabled = _tinyWRAP.MediaSessionMgr_defaultsSetIceStunEnabled
|
MediaSessionMgr_defaultsSetIceStunEnabled = _tinyWRAP.MediaSessionMgr_defaultsSetIceStunEnabled
|
||||||
|
|
||||||
|
def MediaSessionMgr_defaultsSetIceTurnEnabled(*args):
|
||||||
|
return _tinyWRAP.MediaSessionMgr_defaultsSetIceTurnEnabled(*args)
|
||||||
|
MediaSessionMgr_defaultsSetIceTurnEnabled = _tinyWRAP.MediaSessionMgr_defaultsSetIceTurnEnabled
|
||||||
|
|
||||||
def MediaSessionMgr_defaultsSetStunServer(*args):
|
def MediaSessionMgr_defaultsSetStunServer(*args):
|
||||||
return _tinyWRAP.MediaSessionMgr_defaultsSetStunServer(*args)
|
return _tinyWRAP.MediaSessionMgr_defaultsSetStunServer(*args)
|
||||||
MediaSessionMgr_defaultsSetStunServer = _tinyWRAP.MediaSessionMgr_defaultsSetStunServer
|
MediaSessionMgr_defaultsSetStunServer = _tinyWRAP.MediaSessionMgr_defaultsSetStunServer
|
||||||
|
|
||||||
|
def MediaSessionMgr_defaultsSetStunCred(*args):
|
||||||
|
return _tinyWRAP.MediaSessionMgr_defaultsSetStunCred(*args)
|
||||||
|
MediaSessionMgr_defaultsSetStunCred = _tinyWRAP.MediaSessionMgr_defaultsSetStunCred
|
||||||
|
|
||||||
def MediaSessionMgr_defaultsSetIceEnabled(*args):
|
def MediaSessionMgr_defaultsSetIceEnabled(*args):
|
||||||
return _tinyWRAP.MediaSessionMgr_defaultsSetIceEnabled(*args)
|
return _tinyWRAP.MediaSessionMgr_defaultsSetIceEnabled(*args)
|
||||||
MediaSessionMgr_defaultsSetIceEnabled = _tinyWRAP.MediaSessionMgr_defaultsSetIceEnabled
|
MediaSessionMgr_defaultsSetIceEnabled = _tinyWRAP.MediaSessionMgr_defaultsSetIceEnabled
|
||||||
|
@ -977,6 +989,10 @@ class CallSession(InviteSession):
|
||||||
def setSRtpMode(self, *args): return _tinyWRAP.CallSession_setSRtpMode(self, *args)
|
def setSRtpMode(self, *args): return _tinyWRAP.CallSession_setSRtpMode(self, *args)
|
||||||
def setAvpfMode(self, *args): return _tinyWRAP.CallSession_setAvpfMode(self, *args)
|
def setAvpfMode(self, *args): return _tinyWRAP.CallSession_setAvpfMode(self, *args)
|
||||||
def setICE(self, *args): return _tinyWRAP.CallSession_setICE(self, *args)
|
def setICE(self, *args): return _tinyWRAP.CallSession_setICE(self, *args)
|
||||||
|
def setICEStun(self, *args): return _tinyWRAP.CallSession_setICEStun(self, *args)
|
||||||
|
def setICETurn(self, *args): return _tinyWRAP.CallSession_setICETurn(self, *args)
|
||||||
|
def setSTUNServer(self, *args): return _tinyWRAP.CallSession_setSTUNServer(self, *args)
|
||||||
|
def setSTUNCred(self, *args): return _tinyWRAP.CallSession_setSTUNCred(self, *args)
|
||||||
def setQoS(self, *args): return _tinyWRAP.CallSession_setQoS(self, *args)
|
def setQoS(self, *args): return _tinyWRAP.CallSession_setQoS(self, *args)
|
||||||
def hold(self, *args): return _tinyWRAP.CallSession_hold(self, *args)
|
def hold(self, *args): return _tinyWRAP.CallSession_hold(self, *args)
|
||||||
def resume(self, *args): return _tinyWRAP.CallSession_resume(self, *args)
|
def resume(self, *args): return _tinyWRAP.CallSession_resume(self, *args)
|
||||||
|
|
|
@ -7915,111 +7915,29 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGINTERN PyObject *_wrap_MediaSessionMgr_defaultsSetStunServer__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
SWIGINTERN PyObject *_wrap_MediaSessionMgr_defaultsSetIceTurnEnabled(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||||
PyObject *resultobj = 0;
|
PyObject *resultobj = 0;
|
||||||
char *arg1 = (char *) 0 ;
|
bool arg1 ;
|
||||||
uint16_t arg2 ;
|
bool val1 ;
|
||||||
char *arg3 = (char *) 0 ;
|
int ecode1 = 0 ;
|
||||||
char *arg4 = (char *) 0 ;
|
|
||||||
int res1 ;
|
|
||||||
char *buf1 = 0 ;
|
|
||||||
int alloc1 = 0 ;
|
|
||||||
unsigned short val2 ;
|
|
||||||
int ecode2 = 0 ;
|
|
||||||
int res3 ;
|
|
||||||
char *buf3 = 0 ;
|
|
||||||
int alloc3 = 0 ;
|
|
||||||
int res4 ;
|
|
||||||
char *buf4 = 0 ;
|
|
||||||
int alloc4 = 0 ;
|
|
||||||
PyObject * obj0 = 0 ;
|
PyObject * obj0 = 0 ;
|
||||||
PyObject * obj1 = 0 ;
|
|
||||||
PyObject * obj2 = 0 ;
|
|
||||||
PyObject * obj3 = 0 ;
|
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args,(char *)"OOOO:MediaSessionMgr_defaultsSetStunServer",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
|
if (!PyArg_ParseTuple(args,(char *)"O:MediaSessionMgr_defaultsSetIceTurnEnabled",&obj0)) SWIG_fail;
|
||||||
res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
|
ecode1 = SWIG_AsVal_bool(obj0, &val1);
|
||||||
if (!SWIG_IsOK(res1)) {
|
if (!SWIG_IsOK(ecode1)) {
|
||||||
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MediaSessionMgr_defaultsSetStunServer" "', argument " "1"" of type '" "char const *""'");
|
SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "MediaSessionMgr_defaultsSetIceTurnEnabled" "', argument " "1"" of type '" "bool""'");
|
||||||
}
|
}
|
||||||
arg1 = reinterpret_cast< char * >(buf1);
|
arg1 = static_cast< bool >(val1);
|
||||||
ecode2 = SWIG_AsVal_unsigned_SS_short(obj1, &val2);
|
result = (bool)MediaSessionMgr::defaultsSetIceTurnEnabled(arg1);
|
||||||
if (!SWIG_IsOK(ecode2)) {
|
|
||||||
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MediaSessionMgr_defaultsSetStunServer" "', argument " "2"" of type '" "uint16_t""'");
|
|
||||||
}
|
|
||||||
arg2 = static_cast< uint16_t >(val2);
|
|
||||||
res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
|
|
||||||
if (!SWIG_IsOK(res3)) {
|
|
||||||
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "MediaSessionMgr_defaultsSetStunServer" "', argument " "3"" of type '" "char const *""'");
|
|
||||||
}
|
|
||||||
arg3 = reinterpret_cast< char * >(buf3);
|
|
||||||
res4 = SWIG_AsCharPtrAndSize(obj3, &buf4, NULL, &alloc4);
|
|
||||||
if (!SWIG_IsOK(res4)) {
|
|
||||||
SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "MediaSessionMgr_defaultsSetStunServer" "', argument " "4"" of type '" "char const *""'");
|
|
||||||
}
|
|
||||||
arg4 = reinterpret_cast< char * >(buf4);
|
|
||||||
result = (bool)MediaSessionMgr::defaultsSetStunServer((char const *)arg1,arg2,(char const *)arg3,(char const *)arg4);
|
|
||||||
resultobj = SWIG_From_bool(static_cast< bool >(result));
|
resultobj = SWIG_From_bool(static_cast< bool >(result));
|
||||||
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
|
||||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
|
||||||
if (alloc4 == SWIG_NEWOBJ) delete[] buf4;
|
|
||||||
return resultobj;
|
return resultobj;
|
||||||
fail:
|
fail:
|
||||||
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
|
||||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
|
||||||
if (alloc4 == SWIG_NEWOBJ) delete[] buf4;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGINTERN PyObject *_wrap_MediaSessionMgr_defaultsSetStunServer__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
SWIGINTERN PyObject *_wrap_MediaSessionMgr_defaultsSetStunServer(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||||
PyObject *resultobj = 0;
|
|
||||||
char *arg1 = (char *) 0 ;
|
|
||||||
uint16_t arg2 ;
|
|
||||||
char *arg3 = (char *) 0 ;
|
|
||||||
int res1 ;
|
|
||||||
char *buf1 = 0 ;
|
|
||||||
int alloc1 = 0 ;
|
|
||||||
unsigned short val2 ;
|
|
||||||
int ecode2 = 0 ;
|
|
||||||
int res3 ;
|
|
||||||
char *buf3 = 0 ;
|
|
||||||
int alloc3 = 0 ;
|
|
||||||
PyObject * obj0 = 0 ;
|
|
||||||
PyObject * obj1 = 0 ;
|
|
||||||
PyObject * obj2 = 0 ;
|
|
||||||
bool result;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args,(char *)"OOO:MediaSessionMgr_defaultsSetStunServer",&obj0,&obj1,&obj2)) SWIG_fail;
|
|
||||||
res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
|
|
||||||
if (!SWIG_IsOK(res1)) {
|
|
||||||
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MediaSessionMgr_defaultsSetStunServer" "', argument " "1"" of type '" "char const *""'");
|
|
||||||
}
|
|
||||||
arg1 = reinterpret_cast< char * >(buf1);
|
|
||||||
ecode2 = SWIG_AsVal_unsigned_SS_short(obj1, &val2);
|
|
||||||
if (!SWIG_IsOK(ecode2)) {
|
|
||||||
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MediaSessionMgr_defaultsSetStunServer" "', argument " "2"" of type '" "uint16_t""'");
|
|
||||||
}
|
|
||||||
arg2 = static_cast< uint16_t >(val2);
|
|
||||||
res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
|
|
||||||
if (!SWIG_IsOK(res3)) {
|
|
||||||
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "MediaSessionMgr_defaultsSetStunServer" "', argument " "3"" of type '" "char const *""'");
|
|
||||||
}
|
|
||||||
arg3 = reinterpret_cast< char * >(buf3);
|
|
||||||
result = (bool)MediaSessionMgr::defaultsSetStunServer((char const *)arg1,arg2,(char const *)arg3);
|
|
||||||
resultobj = SWIG_From_bool(static_cast< bool >(result));
|
|
||||||
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
|
||||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
|
||||||
return resultobj;
|
|
||||||
fail:
|
|
||||||
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
|
||||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SWIGINTERN PyObject *_wrap_MediaSessionMgr_defaultsSetStunServer__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
|
||||||
PyObject *resultobj = 0;
|
PyObject *resultobj = 0;
|
||||||
char *arg1 = (char *) 0 ;
|
char *arg1 = (char *) 0 ;
|
||||||
uint16_t arg2 ;
|
uint16_t arg2 ;
|
||||||
|
@ -8053,78 +7971,40 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGINTERN PyObject *_wrap_MediaSessionMgr_defaultsSetStunServer(PyObject *self, PyObject *args) {
|
SWIGINTERN PyObject *_wrap_MediaSessionMgr_defaultsSetStunCred(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||||
int argc;
|
PyObject *resultobj = 0;
|
||||||
PyObject *argv[5];
|
char *arg1 = (char *) 0 ;
|
||||||
int ii;
|
char *arg2 = (char *) 0 ;
|
||||||
|
int res1 ;
|
||||||
|
char *buf1 = 0 ;
|
||||||
|
int alloc1 = 0 ;
|
||||||
|
int res2 ;
|
||||||
|
char *buf2 = 0 ;
|
||||||
|
int alloc2 = 0 ;
|
||||||
|
PyObject * obj0 = 0 ;
|
||||||
|
PyObject * obj1 = 0 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
if (!PyTuple_Check(args)) SWIG_fail;
|
if (!PyArg_ParseTuple(args,(char *)"OO:MediaSessionMgr_defaultsSetStunCred",&obj0,&obj1)) SWIG_fail;
|
||||||
argc = args ? (int)PyObject_Length(args) : 0;
|
res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
|
||||||
for (ii = 0; (ii < 4) && (ii < argc); ii++) {
|
if (!SWIG_IsOK(res1)) {
|
||||||
argv[ii] = PyTuple_GET_ITEM(args,ii);
|
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MediaSessionMgr_defaultsSetStunCred" "', argument " "1"" of type '" "char const *""'");
|
||||||
}
|
}
|
||||||
if (argc == 2) {
|
arg1 = reinterpret_cast< char * >(buf1);
|
||||||
int _v;
|
res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
|
||||||
int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0);
|
if (!SWIG_IsOK(res2)) {
|
||||||
_v = SWIG_CheckState(res);
|
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "MediaSessionMgr_defaultsSetStunCred" "', argument " "2"" of type '" "char const *""'");
|
||||||
if (_v) {
|
|
||||||
{
|
|
||||||
int res = SWIG_AsVal_unsigned_SS_short(argv[1], NULL);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
}
|
}
|
||||||
if (_v) {
|
arg2 = reinterpret_cast< char * >(buf2);
|
||||||
return _wrap_MediaSessionMgr_defaultsSetStunServer__SWIG_2(self, args);
|
result = (bool)MediaSessionMgr::defaultsSetStunCred((char const *)arg1,(char const *)arg2);
|
||||||
}
|
resultobj = SWIG_From_bool(static_cast< bool >(result));
|
||||||
}
|
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
||||||
}
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
if (argc == 3) {
|
return resultobj;
|
||||||
int _v;
|
|
||||||
int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
if (_v) {
|
|
||||||
{
|
|
||||||
int res = SWIG_AsVal_unsigned_SS_short(argv[1], NULL);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
}
|
|
||||||
if (_v) {
|
|
||||||
int res = SWIG_AsCharPtrAndSize(argv[2], 0, NULL, 0);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
if (_v) {
|
|
||||||
return _wrap_MediaSessionMgr_defaultsSetStunServer__SWIG_1(self, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (argc == 4) {
|
|
||||||
int _v;
|
|
||||||
int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
if (_v) {
|
|
||||||
{
|
|
||||||
int res = SWIG_AsVal_unsigned_SS_short(argv[1], NULL);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
}
|
|
||||||
if (_v) {
|
|
||||||
int res = SWIG_AsCharPtrAndSize(argv[2], 0, NULL, 0);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
if (_v) {
|
|
||||||
int res = SWIG_AsCharPtrAndSize(argv[3], 0, NULL, 0);
|
|
||||||
_v = SWIG_CheckState(res);
|
|
||||||
if (_v) {
|
|
||||||
return _wrap_MediaSessionMgr_defaultsSetStunServer__SWIG_0(self, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'MediaSessionMgr_defaultsSetStunServer'.\n"
|
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
||||||
" Possible C/C++ prototypes are:\n"
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
" MediaSessionMgr::defaultsSetStunServer(char const *,uint16_t,char const *,char const *)\n"
|
return NULL;
|
||||||
" MediaSessionMgr::defaultsSetStunServer(char const *,uint16_t,char const *)\n"
|
|
||||||
" MediaSessionMgr::defaultsSetStunServer(char const *,uint16_t)\n");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13594,6 +13474,157 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGINTERN PyObject *_wrap_CallSession_setICEStun(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||||
|
PyObject *resultobj = 0;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
bool arg2 ;
|
||||||
|
void *argp1 = 0 ;
|
||||||
|
int res1 = 0 ;
|
||||||
|
bool val2 ;
|
||||||
|
int ecode2 = 0 ;
|
||||||
|
PyObject * obj0 = 0 ;
|
||||||
|
PyObject * obj1 = 0 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args,(char *)"OO:CallSession_setICEStun",&obj0,&obj1)) SWIG_fail;
|
||||||
|
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CallSession, 0 | 0 );
|
||||||
|
if (!SWIG_IsOK(res1)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CallSession_setICEStun" "', argument " "1"" of type '" "CallSession *""'");
|
||||||
|
}
|
||||||
|
arg1 = reinterpret_cast< CallSession * >(argp1);
|
||||||
|
ecode2 = SWIG_AsVal_bool(obj1, &val2);
|
||||||
|
if (!SWIG_IsOK(ecode2)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "CallSession_setICEStun" "', argument " "2"" of type '" "bool""'");
|
||||||
|
}
|
||||||
|
arg2 = static_cast< bool >(val2);
|
||||||
|
result = (bool)(arg1)->setICEStun(arg2);
|
||||||
|
resultobj = SWIG_From_bool(static_cast< bool >(result));
|
||||||
|
return resultobj;
|
||||||
|
fail:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGINTERN PyObject *_wrap_CallSession_setICETurn(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||||
|
PyObject *resultobj = 0;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
bool arg2 ;
|
||||||
|
void *argp1 = 0 ;
|
||||||
|
int res1 = 0 ;
|
||||||
|
bool val2 ;
|
||||||
|
int ecode2 = 0 ;
|
||||||
|
PyObject * obj0 = 0 ;
|
||||||
|
PyObject * obj1 = 0 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args,(char *)"OO:CallSession_setICETurn",&obj0,&obj1)) SWIG_fail;
|
||||||
|
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CallSession, 0 | 0 );
|
||||||
|
if (!SWIG_IsOK(res1)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CallSession_setICETurn" "', argument " "1"" of type '" "CallSession *""'");
|
||||||
|
}
|
||||||
|
arg1 = reinterpret_cast< CallSession * >(argp1);
|
||||||
|
ecode2 = SWIG_AsVal_bool(obj1, &val2);
|
||||||
|
if (!SWIG_IsOK(ecode2)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "CallSession_setICETurn" "', argument " "2"" of type '" "bool""'");
|
||||||
|
}
|
||||||
|
arg2 = static_cast< bool >(val2);
|
||||||
|
result = (bool)(arg1)->setICETurn(arg2);
|
||||||
|
resultobj = SWIG_From_bool(static_cast< bool >(result));
|
||||||
|
return resultobj;
|
||||||
|
fail:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGINTERN PyObject *_wrap_CallSession_setSTUNServer(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||||
|
PyObject *resultobj = 0;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
uint16_t arg3 ;
|
||||||
|
void *argp1 = 0 ;
|
||||||
|
int res1 = 0 ;
|
||||||
|
int res2 ;
|
||||||
|
char *buf2 = 0 ;
|
||||||
|
int alloc2 = 0 ;
|
||||||
|
unsigned short val3 ;
|
||||||
|
int ecode3 = 0 ;
|
||||||
|
PyObject * obj0 = 0 ;
|
||||||
|
PyObject * obj1 = 0 ;
|
||||||
|
PyObject * obj2 = 0 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args,(char *)"OOO:CallSession_setSTUNServer",&obj0,&obj1,&obj2)) SWIG_fail;
|
||||||
|
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CallSession, 0 | 0 );
|
||||||
|
if (!SWIG_IsOK(res1)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CallSession_setSTUNServer" "', argument " "1"" of type '" "CallSession *""'");
|
||||||
|
}
|
||||||
|
arg1 = reinterpret_cast< CallSession * >(argp1);
|
||||||
|
res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
|
||||||
|
if (!SWIG_IsOK(res2)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CallSession_setSTUNServer" "', argument " "2"" of type '" "char const *""'");
|
||||||
|
}
|
||||||
|
arg2 = reinterpret_cast< char * >(buf2);
|
||||||
|
ecode3 = SWIG_AsVal_unsigned_SS_short(obj2, &val3);
|
||||||
|
if (!SWIG_IsOK(ecode3)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "CallSession_setSTUNServer" "', argument " "3"" of type '" "uint16_t""'");
|
||||||
|
}
|
||||||
|
arg3 = static_cast< uint16_t >(val3);
|
||||||
|
result = (bool)(arg1)->setSTUNServer((char const *)arg2,arg3);
|
||||||
|
resultobj = SWIG_From_bool(static_cast< bool >(result));
|
||||||
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
|
return resultobj;
|
||||||
|
fail:
|
||||||
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGINTERN PyObject *_wrap_CallSession_setSTUNCred(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||||
|
PyObject *resultobj = 0;
|
||||||
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
char *arg3 = (char *) 0 ;
|
||||||
|
void *argp1 = 0 ;
|
||||||
|
int res1 = 0 ;
|
||||||
|
int res2 ;
|
||||||
|
char *buf2 = 0 ;
|
||||||
|
int alloc2 = 0 ;
|
||||||
|
int res3 ;
|
||||||
|
char *buf3 = 0 ;
|
||||||
|
int alloc3 = 0 ;
|
||||||
|
PyObject * obj0 = 0 ;
|
||||||
|
PyObject * obj1 = 0 ;
|
||||||
|
PyObject * obj2 = 0 ;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args,(char *)"OOO:CallSession_setSTUNCred",&obj0,&obj1,&obj2)) SWIG_fail;
|
||||||
|
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CallSession, 0 | 0 );
|
||||||
|
if (!SWIG_IsOK(res1)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CallSession_setSTUNCred" "', argument " "1"" of type '" "CallSession *""'");
|
||||||
|
}
|
||||||
|
arg1 = reinterpret_cast< CallSession * >(argp1);
|
||||||
|
res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
|
||||||
|
if (!SWIG_IsOK(res2)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CallSession_setSTUNCred" "', argument " "2"" of type '" "char const *""'");
|
||||||
|
}
|
||||||
|
arg2 = reinterpret_cast< char * >(buf2);
|
||||||
|
res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
|
||||||
|
if (!SWIG_IsOK(res3)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "CallSession_setSTUNCred" "', argument " "3"" of type '" "char const *""'");
|
||||||
|
}
|
||||||
|
arg3 = reinterpret_cast< char * >(buf3);
|
||||||
|
result = (bool)(arg1)->setSTUNCred((char const *)arg2,(char const *)arg3);
|
||||||
|
resultobj = SWIG_From_bool(static_cast< bool >(result));
|
||||||
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
|
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||||
|
return resultobj;
|
||||||
|
fail:
|
||||||
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
|
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGINTERN PyObject *_wrap_CallSession_setQoS(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
SWIGINTERN PyObject *_wrap_CallSession_setQoS(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||||
PyObject *resultobj = 0;
|
PyObject *resultobj = 0;
|
||||||
CallSession *arg1 = (CallSession *) 0 ;
|
CallSession *arg1 = (CallSession *) 0 ;
|
||||||
|
@ -26134,7 +26165,9 @@ static PyMethodDef SwigMethods[] = {
|
||||||
{ (char *)"MediaSessionMgr_defaultsGetRtcpMuxEnabled", _wrap_MediaSessionMgr_defaultsGetRtcpMuxEnabled, METH_VARARGS, NULL},
|
{ (char *)"MediaSessionMgr_defaultsGetRtcpMuxEnabled", _wrap_MediaSessionMgr_defaultsGetRtcpMuxEnabled, METH_VARARGS, NULL},
|
||||||
{ (char *)"MediaSessionMgr_defaultsSetStunEnabled", _wrap_MediaSessionMgr_defaultsSetStunEnabled, METH_VARARGS, NULL},
|
{ (char *)"MediaSessionMgr_defaultsSetStunEnabled", _wrap_MediaSessionMgr_defaultsSetStunEnabled, METH_VARARGS, NULL},
|
||||||
{ (char *)"MediaSessionMgr_defaultsSetIceStunEnabled", _wrap_MediaSessionMgr_defaultsSetIceStunEnabled, METH_VARARGS, NULL},
|
{ (char *)"MediaSessionMgr_defaultsSetIceStunEnabled", _wrap_MediaSessionMgr_defaultsSetIceStunEnabled, METH_VARARGS, NULL},
|
||||||
|
{ (char *)"MediaSessionMgr_defaultsSetIceTurnEnabled", _wrap_MediaSessionMgr_defaultsSetIceTurnEnabled, METH_VARARGS, NULL},
|
||||||
{ (char *)"MediaSessionMgr_defaultsSetStunServer", _wrap_MediaSessionMgr_defaultsSetStunServer, METH_VARARGS, NULL},
|
{ (char *)"MediaSessionMgr_defaultsSetStunServer", _wrap_MediaSessionMgr_defaultsSetStunServer, METH_VARARGS, NULL},
|
||||||
|
{ (char *)"MediaSessionMgr_defaultsSetStunCred", _wrap_MediaSessionMgr_defaultsSetStunCred, METH_VARARGS, NULL},
|
||||||
{ (char *)"MediaSessionMgr_defaultsSetIceEnabled", _wrap_MediaSessionMgr_defaultsSetIceEnabled, METH_VARARGS, NULL},
|
{ (char *)"MediaSessionMgr_defaultsSetIceEnabled", _wrap_MediaSessionMgr_defaultsSetIceEnabled, METH_VARARGS, NULL},
|
||||||
{ (char *)"MediaSessionMgr_defaultsSetByPassEncoding", _wrap_MediaSessionMgr_defaultsSetByPassEncoding, METH_VARARGS, NULL},
|
{ (char *)"MediaSessionMgr_defaultsSetByPassEncoding", _wrap_MediaSessionMgr_defaultsSetByPassEncoding, METH_VARARGS, NULL},
|
||||||
{ (char *)"MediaSessionMgr_defaultsGetByPassEncoding", _wrap_MediaSessionMgr_defaultsGetByPassEncoding, METH_VARARGS, NULL},
|
{ (char *)"MediaSessionMgr_defaultsGetByPassEncoding", _wrap_MediaSessionMgr_defaultsGetByPassEncoding, METH_VARARGS, NULL},
|
||||||
|
@ -26287,6 +26320,10 @@ static PyMethodDef SwigMethods[] = {
|
||||||
{ (char *)"CallSession_setSRtpMode", _wrap_CallSession_setSRtpMode, METH_VARARGS, NULL},
|
{ (char *)"CallSession_setSRtpMode", _wrap_CallSession_setSRtpMode, METH_VARARGS, NULL},
|
||||||
{ (char *)"CallSession_setAvpfMode", _wrap_CallSession_setAvpfMode, METH_VARARGS, NULL},
|
{ (char *)"CallSession_setAvpfMode", _wrap_CallSession_setAvpfMode, METH_VARARGS, NULL},
|
||||||
{ (char *)"CallSession_setICE", _wrap_CallSession_setICE, METH_VARARGS, NULL},
|
{ (char *)"CallSession_setICE", _wrap_CallSession_setICE, METH_VARARGS, NULL},
|
||||||
|
{ (char *)"CallSession_setICEStun", _wrap_CallSession_setICEStun, METH_VARARGS, NULL},
|
||||||
|
{ (char *)"CallSession_setICETurn", _wrap_CallSession_setICETurn, METH_VARARGS, NULL},
|
||||||
|
{ (char *)"CallSession_setSTUNServer", _wrap_CallSession_setSTUNServer, METH_VARARGS, NULL},
|
||||||
|
{ (char *)"CallSession_setSTUNCred", _wrap_CallSession_setSTUNCred, METH_VARARGS, NULL},
|
||||||
{ (char *)"CallSession_setQoS", _wrap_CallSession_setQoS, METH_VARARGS, NULL},
|
{ (char *)"CallSession_setQoS", _wrap_CallSession_setQoS, METH_VARARGS, NULL},
|
||||||
{ (char *)"CallSession_hold", _wrap_CallSession_hold, METH_VARARGS, NULL},
|
{ (char *)"CallSession_hold", _wrap_CallSession_hold, METH_VARARGS, NULL},
|
||||||
{ (char *)"CallSession_resume", _wrap_CallSession_resume, METH_VARARGS, NULL},
|
{ (char *)"CallSession_resume", _wrap_CallSession_resume, METH_VARARGS, NULL},
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
AC_PREREQ([2.0])
|
AC_PREREQ([2.0])
|
||||||
AC_INIT(libdoubango, 2.0.1062, doubango(at)googlegroups(dot)com)
|
AC_INIT(libdoubango, 2.0.1086, doubango(at)googlegroups(dot)com)
|
||||||
AC_CANONICAL_SYSTEM
|
AC_CANONICAL_SYSTEM
|
||||||
AM_INIT_AUTOMAKE
|
AM_INIT_AUTOMAKE
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
|
@ -37,7 +37,7 @@ TINYBFCP_API int tbfcp_session_prepare(struct tbfcp_session_s* p_self);
|
||||||
TINYBFCP_API int tbfcp_session_start(struct tbfcp_session_s* p_self);
|
TINYBFCP_API int tbfcp_session_start(struct tbfcp_session_s* p_self);
|
||||||
TINYBFCP_API int tbfcp_session_pause(struct tbfcp_session_s* p_self);
|
TINYBFCP_API int tbfcp_session_pause(struct tbfcp_session_s* p_self);
|
||||||
TINYBFCP_API int tbfcp_session_stop(struct tbfcp_session_s* p_self);
|
TINYBFCP_API int tbfcp_session_stop(struct tbfcp_session_s* p_self);
|
||||||
TINYBFCP_API int tbfcp_session_set_natt_ctx(struct tbfcp_session_s* p_self, struct tnet_nat_context_s* p_natt_ctx);
|
TINYBFCP_API int tbfcp_session_set_natt_ctx(struct tbfcp_session_s* p_self, struct tnet_nat_ctx_s* p_natt_ctx);
|
||||||
TINYBFCP_API int tbfcp_session_set_remote_address(struct tbfcp_session_s* p_self, const char* pc_ip, tnet_port_t u_port);
|
TINYBFCP_API int tbfcp_session_set_remote_address(struct tbfcp_session_s* p_self, const char* pc_ip, tnet_port_t u_port);
|
||||||
TINYBFCP_API int tbfcp_session_set_remote_role(struct tbfcp_session_s* p_self, enum tbfcp_role_e e_role_remote);
|
TINYBFCP_API int tbfcp_session_set_remote_role(struct tbfcp_session_s* p_self, enum tbfcp_role_e e_role_remote);
|
||||||
TINYBFCP_API int tbfcp_session_set_remote_setup(struct tbfcp_session_s* p_self, enum tbfcp_setup_e e_setup_remote);
|
TINYBFCP_API int tbfcp_session_set_remote_setup(struct tbfcp_session_s* p_self, enum tbfcp_setup_e e_setup_remote);
|
||||||
|
|
|
@ -59,7 +59,7 @@ typedef struct tbfcp_session_s {
|
||||||
tnet_port_t u_remote_port;
|
tnet_port_t u_remote_port;
|
||||||
struct sockaddr_storage remote_addr;
|
struct sockaddr_storage remote_addr;
|
||||||
|
|
||||||
struct tnet_nat_context_s* p_natt_ctx;
|
struct tnet_nat_ctx_s* p_natt_ctx;
|
||||||
struct tnet_ice_ctx_s* p_ice_ctx;
|
struct tnet_ice_ctx_s* p_ice_ctx;
|
||||||
struct tnet_transport_s* p_transport;
|
struct tnet_transport_s* p_transport;
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ bail:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tbfcp_session_set_natt_ctx(tbfcp_session_t* p_self, struct tnet_nat_context_s* p_natt_ctx)
|
int tbfcp_session_set_natt_ctx(tbfcp_session_t* p_self, struct tnet_nat_ctx_s* p_natt_ctx)
|
||||||
{
|
{
|
||||||
if (!p_self) {
|
if (!p_self) {
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
|
|
@ -73,7 +73,7 @@ typedef struct tdav_session_msrp_s
|
||||||
//uint16_t local_port;
|
//uint16_t local_port;
|
||||||
|
|
||||||
/* NAT Traversal context */
|
/* NAT Traversal context */
|
||||||
tnet_nat_context_handle_t* natt_ctx;
|
struct tnet_nat_ctx_s* natt_ctx;
|
||||||
|
|
||||||
char* remote_ip;
|
char* remote_ip;
|
||||||
uint16_t remote_port;
|
uint16_t remote_port;
|
||||||
|
|
|
@ -64,7 +64,7 @@ typedef struct tdav_session_av_s
|
||||||
struct tdav_sdp_caps_s* sdp_caps;
|
struct tdav_sdp_caps_s* sdp_caps;
|
||||||
|
|
||||||
/* NAT Traversal context */
|
/* NAT Traversal context */
|
||||||
tnet_nat_context_handle_t* natt_ctx;
|
struct tnet_nat_ctx_s* natt_ctx;
|
||||||
struct tnet_ice_ctx_s* ice_ctx;
|
struct tnet_ice_ctx_s* ice_ctx;
|
||||||
|
|
||||||
char* local_ip;
|
char* local_ip;
|
||||||
|
|
|
@ -49,7 +49,7 @@ typedef struct tdav_session_bfcp_s
|
||||||
//uint16_t local_port;
|
//uint16_t local_port;
|
||||||
|
|
||||||
/* NAT Traversal context */
|
/* NAT Traversal context */
|
||||||
struct tnet_nat_context_s* p_natt_ctx;
|
struct tnet_nat_ctx_s* p_natt_ctx;
|
||||||
|
|
||||||
char* p_remote_ip;
|
char* p_remote_ip;
|
||||||
uint16_t u_remote_port;
|
uint16_t u_remote_port;
|
||||||
|
|
|
@ -1160,7 +1160,7 @@ const tsdp_header_M_t* tdav_session_av_get_lo(tdav_session_av_t* self, tsk_bool_
|
||||||
// FIXME: for RTCP, use "RFC 3605"in addition to "rtcp-mux"
|
// FIXME: for RTCP, use "RFC 3605"in addition to "rtcp-mux"
|
||||||
|
|
||||||
// "a=ice-mismatch" if "C=" line is not included in the candidates
|
// "a=ice-mismatch" if "C=" line is not included in the candidates
|
||||||
if((candidate = tnet_ice_ctx_get_local_candidate_at(self->ice_ctx, 0))){ // at least one candidate
|
if ((candidate = tnet_ice_ctx_get_local_candidate_first(self->ice_ctx))) { // at least one candidate
|
||||||
base->M.lo->port = candidate->socket->port;
|
base->M.lo->port = candidate->socket->port;
|
||||||
|
|
||||||
tsdp_header_M_remove(base->M.lo, tsdp_htype_C);
|
tsdp_header_M_remove(base->M.lo, tsdp_htype_C);
|
||||||
|
@ -1177,10 +1177,15 @@ const tsdp_header_M_t* tdav_session_av_get_lo(tdav_session_av_t* self, tsk_bool_
|
||||||
// TSDP_HEADER_A_VA_ARGS("mid", self->media_type & tmedia_audio ? "audio" : "video"),
|
// TSDP_HEADER_A_VA_ARGS("mid", self->media_type & tmedia_audio ? "audio" : "video"),
|
||||||
// tsk_null);
|
// tsk_null);
|
||||||
|
|
||||||
while((candidate = tnet_ice_ctx_get_local_candidate_at(self->ice_ctx, index++))){
|
while ((candidate = tnet_ice_ctx_get_local_candidate_at(self->ice_ctx, index++))) {
|
||||||
if(self->use_rtcpmux && remote_use_rtcpmux && candidate->comp_id == TNET_ICE_CANDIDATE_COMPID_RTCP){
|
if (self->use_rtcpmux && remote_use_rtcpmux && candidate->comp_id == TNET_ICE_CANDIDATE_COMPID_RTCP) {
|
||||||
continue; // do not add RTCP candidates if RTCP-MUX is activated (local + remote)
|
continue; // do not add RTCP candidates if RTCP-MUX is activated (local + remote)
|
||||||
}
|
}
|
||||||
|
#if 0 //TURN:FORCE
|
||||||
|
if (candidate->type_e != tnet_ice_cand_type_relay) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
tsdp_header_M_add_headers(base->M.lo,
|
tsdp_header_M_add_headers(base->M.lo,
|
||||||
TSDP_HEADER_A_VA_ARGS("candidate", tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate)),
|
TSDP_HEADER_A_VA_ARGS("candidate", tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate)),
|
||||||
tsk_null);
|
tsk_null);
|
||||||
|
@ -1652,15 +1657,15 @@ static int _tdav_session_av_raise_error_async(struct tdav_session_av_s* self, ts
|
||||||
|
|
||||||
tsk_safeobj_lock(self);
|
tsk_safeobj_lock(self);
|
||||||
|
|
||||||
tsk_object_ref(self); // see _tdav_session_av_error_async_thread()
|
tsk_object_ref(self); // do not unref(), see _tdav_session_av_error_async_thread()
|
||||||
|
|
||||||
if(self->last_error.tid[0]){
|
if (self->last_error.tid[0]) {
|
||||||
tsk_thread_join(self->last_error.tid);
|
tsk_thread_join(self->last_error.tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
self->last_error.is_fatal = is_fatal;
|
self->last_error.is_fatal = is_fatal;
|
||||||
tsk_strupdate(&self->last_error.reason, reason);
|
tsk_strupdate(&self->last_error.reason, reason);
|
||||||
if((ret = tsk_thread_create(self->last_error.tid, _tdav_session_av_error_async_thread, self)) != 0){
|
if ((ret = tsk_thread_create(self->last_error.tid, _tdav_session_av_error_async_thread, self)) != 0) {
|
||||||
tsk_object_unref(self);
|
tsk_object_unref(self);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -1674,7 +1679,7 @@ bail:
|
||||||
#if HAVE_SRTP
|
#if HAVE_SRTP
|
||||||
static int _tdav_session_av_srtp_dtls_cb(const void* usrdata, enum trtp_srtp_dtls_event_type_e type, const char* reason)
|
static int _tdav_session_av_srtp_dtls_cb(const void* usrdata, enum trtp_srtp_dtls_event_type_e type, const char* reason)
|
||||||
{
|
{
|
||||||
tdav_session_av_t* self = (tdav_session_av_t*)usrdata;
|
tdav_session_av_t* self = tsk_object_ref((tdav_session_av_t*)usrdata);
|
||||||
|
|
||||||
tsk_safeobj_lock(self);
|
tsk_safeobj_lock(self);
|
||||||
switch(type){
|
switch(type){
|
||||||
|
@ -1702,6 +1707,7 @@ static int _tdav_session_av_srtp_dtls_cb(const void* usrdata, enum trtp_srtp_dtl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tsk_safeobj_unlock(self);
|
tsk_safeobj_unlock(self);
|
||||||
|
tsk_object_unref(self);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,12 +101,16 @@ TINYMEDIA_API tsk_bool_t tmedia_defaults_get_rtcp_enabled();
|
||||||
TINYMEDIA_API int tmedia_defaults_set_rtcp_enabled(tsk_bool_t rtcp_enabled);
|
TINYMEDIA_API int tmedia_defaults_set_rtcp_enabled(tsk_bool_t rtcp_enabled);
|
||||||
TINYMEDIA_API tsk_bool_t tmedia_defaults_get_rtcpmux_enabled();
|
TINYMEDIA_API tsk_bool_t tmedia_defaults_get_rtcpmux_enabled();
|
||||||
TINYMEDIA_API int tmedia_defaults_set_rtcpmux_enabled(tsk_bool_t rtcpmux_enabled);
|
TINYMEDIA_API int tmedia_defaults_set_rtcpmux_enabled(tsk_bool_t rtcpmux_enabled);
|
||||||
TINYMEDIA_API int tmedia_defaults_set_stun_server(const char* server_ip, uint16_t server_port, const char* usr_name, const char* usr_pwd);
|
TINYMEDIA_API int tmedia_defaults_set_stun_server(const char* server_ip, uint16_t server_port);
|
||||||
TINYMEDIA_API int tmedia_defaults_get_stun_server(const char** server_ip, uint16_t*const server_port, const char** usr_name, const char** usr_pwd);
|
TINYMEDIA_API int tmedia_defaults_get_stun_server(const char** server_ip, uint16_t*const server_port);
|
||||||
|
TINYMEDIA_API int tmedia_defaults_set_stun_cred(const char* usr_name, const char* usr_pwd);
|
||||||
|
TINYMEDIA_API int tmedia_defaults_get_stun_cred(const char** usr_name, const char** usr_pwd);
|
||||||
TINYMEDIA_API int tmedia_defaults_set_stun_enabled(tsk_bool_t stun_enabled);
|
TINYMEDIA_API int tmedia_defaults_set_stun_enabled(tsk_bool_t stun_enabled);
|
||||||
TINYMEDIA_API tsk_bool_t tmedia_defaults_get_stun_enabled();
|
TINYMEDIA_API tsk_bool_t tmedia_defaults_get_stun_enabled();
|
||||||
TINYMEDIA_API int tmedia_defaults_set_icestun_enabled(tsk_bool_t icestun_enabled);
|
TINYMEDIA_API int tmedia_defaults_set_icestun_enabled(tsk_bool_t icestun_enabled);
|
||||||
TINYMEDIA_API tsk_bool_t tmedia_defaults_get_icestun_enabled();
|
TINYMEDIA_API tsk_bool_t tmedia_defaults_get_icestun_enabled();
|
||||||
|
TINYMEDIA_API int tmedia_defaults_set_iceturn_enabled(tsk_bool_t iceturn_enabled);
|
||||||
|
TINYMEDIA_API tsk_bool_t tmedia_defaults_get_iceturn_enabled();
|
||||||
TINYMEDIA_API int tmedia_defaults_set_ice_enabled(tsk_bool_t ice_enabled);
|
TINYMEDIA_API int tmedia_defaults_set_ice_enabled(tsk_bool_t ice_enabled);
|
||||||
TINYMEDIA_API tsk_bool_t tmedia_defaults_get_ice_enabled();
|
TINYMEDIA_API tsk_bool_t tmedia_defaults_get_ice_enabled();
|
||||||
TINYMEDIA_API int tmedia_defaults_set_bypass_encoding(tsk_bool_t enabled);
|
TINYMEDIA_API int tmedia_defaults_set_bypass_encoding(tsk_bool_t enabled);
|
||||||
|
|
|
@ -302,7 +302,7 @@ typedef struct tmedia_session_mgr_s
|
||||||
tmedia_bandwidth_level_t bl;
|
tmedia_bandwidth_level_t bl;
|
||||||
|
|
||||||
/* NAT Traversal context */
|
/* NAT Traversal context */
|
||||||
tnet_nat_context_handle_t* natt_ctx;
|
struct tnet_nat_ctx_s* natt_ctx;
|
||||||
struct {
|
struct {
|
||||||
struct tnet_ice_ctx_s *ctx_audio;
|
struct tnet_ice_ctx_s *ctx_audio;
|
||||||
struct tnet_ice_ctx_s *ctx_video;
|
struct tnet_ice_ctx_s *ctx_video;
|
||||||
|
@ -506,7 +506,7 @@ TINYMEDIA_API tmedia_session_mgr_t* tmedia_session_mgr_create(tmedia_type_t type
|
||||||
TINYMEDIA_API int tmedia_session_mgr_set_media_type(tmedia_session_mgr_t* self, tmedia_type_t type);
|
TINYMEDIA_API int tmedia_session_mgr_set_media_type(tmedia_session_mgr_t* self, tmedia_type_t type);
|
||||||
TINYMEDIA_API int tmedia_session_mgr_set_codecs_supported(tmedia_session_mgr_t* self, tmedia_codec_id_t codecs_supported);
|
TINYMEDIA_API int tmedia_session_mgr_set_codecs_supported(tmedia_session_mgr_t* self, tmedia_codec_id_t codecs_supported);
|
||||||
TINYMEDIA_API tmedia_session_t* tmedia_session_mgr_find(tmedia_session_mgr_t* self, tmedia_type_t type);
|
TINYMEDIA_API tmedia_session_t* tmedia_session_mgr_find(tmedia_session_mgr_t* self, tmedia_type_t type);
|
||||||
TINYMEDIA_API int tmedia_session_mgr_set_natt_ctx(tmedia_session_mgr_t* self, tnet_nat_context_handle_t* natt_ctx, const char* public_addr);
|
TINYMEDIA_API int tmedia_session_mgr_set_natt_ctx(tmedia_session_mgr_t* self, struct tnet_nat_ctx_s* natt_ctx, const char* public_addr);
|
||||||
TINYMEDIA_API int tmedia_session_mgr_set_ice_ctx(tmedia_session_mgr_t* self, struct tnet_ice_ctx_s* ctx_audio, struct tnet_ice_ctx_s* ctx_video);
|
TINYMEDIA_API int tmedia_session_mgr_set_ice_ctx(tmedia_session_mgr_t* self, struct tnet_ice_ctx_s* ctx_audio, struct tnet_ice_ctx_s* ctx_video);
|
||||||
TINYMEDIA_API int tmedia_session_mgr_start(tmedia_session_mgr_t* self);
|
TINYMEDIA_API int tmedia_session_mgr_start(tmedia_session_mgr_t* self);
|
||||||
TINYMEDIA_API int tmedia_session_mgr_set(tmedia_session_mgr_t* self, ...);
|
TINYMEDIA_API int tmedia_session_mgr_set(tmedia_session_mgr_t* self, ...);
|
||||||
|
|
|
@ -73,6 +73,7 @@ static char* __stun_usr_name = tsk_null; // STUN/TURN credentials
|
||||||
static char* __stun_usr_pwd = tsk_null; // STUN/TURN credentials
|
static char* __stun_usr_pwd = tsk_null; // STUN/TURN credentials
|
||||||
static tsk_bool_t __stun_enabled = tsk_false; // Whether STUN for SIP headers is enabled
|
static tsk_bool_t __stun_enabled = tsk_false; // Whether STUN for SIP headers is enabled
|
||||||
static tsk_bool_t __icestun_enabled = tsk_true; // Whether STUN for ICE (reflexive candidates) is enabled
|
static tsk_bool_t __icestun_enabled = tsk_true; // Whether STUN for ICE (reflexive candidates) is enabled
|
||||||
|
static tsk_bool_t __iceturn_enabled = tsk_false; // Whether TURN for ICE (relay candidates) is enabled
|
||||||
static tsk_bool_t __bypass_encoding_enabled = tsk_false;
|
static tsk_bool_t __bypass_encoding_enabled = tsk_false;
|
||||||
static tsk_bool_t __bypass_decoding_enabled = tsk_false;
|
static tsk_bool_t __bypass_decoding_enabled = tsk_false;
|
||||||
static tsk_bool_t __videojb_enabled = tsk_true;
|
static tsk_bool_t __videojb_enabled = tsk_true;
|
||||||
|
@ -424,17 +425,24 @@ int tmedia_defaults_set_rtcpmux_enabled(tsk_bool_t rtcpmux_enabled){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tmedia_defaults_set_stun_server(const char* server_ip, uint16_t server_port, const char* usr_name, const char* usr_pwd){
|
int tmedia_defaults_set_stun_server(const char* server_ip, uint16_t server_port){
|
||||||
tsk_strupdate(&__stun_server_ip, server_ip);
|
tsk_strupdate(&__stun_server_ip, server_ip);
|
||||||
__stun_server_port = server_port;
|
__stun_server_port = server_port;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int tmedia_defaults_get_stun_server(const char** server_ip, uint16_t*const server_port){
|
||||||
|
static const char* __stun_server_ip_default = "numb.viagenie.ca"; // default server for backward compatibility
|
||||||
|
if(server_ip) *server_ip = tsk_strnullORempty(__stun_server_ip) ? __stun_server_ip_default : __stun_server_ip;
|
||||||
|
if(server_port) *server_port = __stun_server_port;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tmedia_defaults_set_stun_cred(const char* usr_name, const char* usr_pwd) {
|
||||||
tsk_strupdate(&__stun_usr_name, usr_name);
|
tsk_strupdate(&__stun_usr_name, usr_name);
|
||||||
tsk_strupdate(&__stun_usr_pwd, usr_pwd);
|
tsk_strupdate(&__stun_usr_pwd, usr_pwd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int tmedia_defaults_get_stun_server(const char** server_ip, uint16_t*const server_port, const char** usr_name, const char** usr_pwd){
|
int tmedia_defaults_get_stun_cred(const char** usr_name, const char** usr_pwd){
|
||||||
static const char* __stun_server_ip_default = "numb.viagenie.ca"; // default server for backward compatibility
|
|
||||||
if(server_ip) *server_ip = tsk_strnullORempty(__stun_server_ip) ? __stun_server_ip_default : __stun_server_ip;
|
|
||||||
if(server_port) *server_port = __stun_server_port;
|
|
||||||
if(usr_name) *usr_name = __stun_usr_name;
|
if(usr_name) *usr_name = __stun_usr_name;
|
||||||
if(usr_pwd) *usr_pwd = __stun_usr_pwd;
|
if(usr_pwd) *usr_pwd = __stun_usr_pwd;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -456,6 +464,14 @@ tsk_bool_t tmedia_defaults_get_icestun_enabled(){
|
||||||
return __icestun_enabled;
|
return __icestun_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tmedia_defaults_set_iceturn_enabled(tsk_bool_t iceturn_enabled){
|
||||||
|
__iceturn_enabled = iceturn_enabled;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
tsk_bool_t tmedia_defaults_get_iceturn_enabled(){
|
||||||
|
return __iceturn_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
int tmedia_defaults_set_ice_enabled(tsk_bool_t ice_enabled){
|
int tmedia_defaults_set_ice_enabled(tsk_bool_t ice_enabled){
|
||||||
__ice_enabled = ice_enabled;
|
__ice_enabled = ice_enabled;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -829,7 +829,7 @@ tmedia_session_t* tmedia_session_mgr_find(tmedia_session_mgr_t* self, tmedia_typ
|
||||||
|
|
||||||
/**@ingroup tmedia_session_group
|
/**@ingroup tmedia_session_group
|
||||||
*/
|
*/
|
||||||
int tmedia_session_mgr_set_natt_ctx(tmedia_session_mgr_t* self, tnet_nat_context_handle_t* natt_ctx, const char* public_addr)
|
int tmedia_session_mgr_set_natt_ctx(tmedia_session_mgr_t* self, struct tnet_nat_ctx_s* natt_ctx, const char* public_addr)
|
||||||
{
|
{
|
||||||
if(!self || !natt_ctx){
|
if(!self || !natt_ctx){
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
|
|
@ -57,6 +57,7 @@ libtinyNET_la_SOURCES += src/ice/tnet_ice_candidate.c\
|
||||||
|
|
||||||
libtinyNET_la_SOURCES += src/stun/tnet_stun.c\
|
libtinyNET_la_SOURCES += src/stun/tnet_stun.c\
|
||||||
src/stun/tnet_stun_attr.c\
|
src/stun/tnet_stun_attr.c\
|
||||||
|
src/stun/tnet_stun_binding.c\
|
||||||
src/stun/tnet_stun_pkt.c\
|
src/stun/tnet_stun_pkt.c\
|
||||||
src/stun/tnet_stun_utils.c\
|
src/stun/tnet_stun_utils.c\
|
||||||
\
|
\
|
||||||
|
|
|
@ -44,8 +44,8 @@ static int _tnet_ice_candidate_tostring(
|
||||||
const tsk_params_L_t *extension_att_list,
|
const tsk_params_L_t *extension_att_list,
|
||||||
char** output);
|
char** output);
|
||||||
static const char* _tnet_ice_candidate_get_foundation(tnet_ice_cand_type_t type);
|
static const char* _tnet_ice_candidate_get_foundation(tnet_ice_cand_type_t type);
|
||||||
static tnet_stun_message_t * _tnet_ice_candidate_stun_create_bind_request(tnet_ice_candidate_t* self, const char* username, const char* password);
|
static tnet_stun_pkt_t * _tnet_ice_candidate_stun_create_bind_request(tnet_ice_candidate_t* self, const char* username, const char* password);
|
||||||
static tsk_bool_t _tnet_ice_candidate_stun_transac_id_equals(const tnet_stun_transacid_t id1, const tnet_stun_transacid_t id2);
|
static tsk_bool_t _tnet_ice_candidate_stun_transac_id_equals(const tnet_stun_transac_id_t id1, const tnet_stun_transac_id_t id2);
|
||||||
static const char* _tnet_ice_candidate_get_transport_str(tnet_socket_type_t transport_e);
|
static const char* _tnet_ice_candidate_get_transport_str(tnet_socket_type_t transport_e);
|
||||||
static tnet_socket_type_t _tnet_ice_candidate_get_transport_type(tsk_bool_t ipv6, const char* transport_str);
|
static tnet_socket_type_t _tnet_ice_candidate_get_transport_type(tsk_bool_t ipv6, const char* transport_str);
|
||||||
static const char* _tnet_ice_candidate_get_candtype_str(tnet_ice_cand_type_t candtype_e);
|
static const char* _tnet_ice_candidate_get_candtype_str(tnet_ice_cand_type_t candtype_e);
|
||||||
|
@ -69,10 +69,14 @@ static tsk_object_t* tnet_ice_candidate_dtor(tsk_object_t * self)
|
||||||
TSK_OBJECT_SAFE_FREE(candidate->extension_att_list);
|
TSK_OBJECT_SAFE_FREE(candidate->extension_att_list);
|
||||||
TSK_OBJECT_SAFE_FREE(candidate->socket);
|
TSK_OBJECT_SAFE_FREE(candidate->socket);
|
||||||
|
|
||||||
|
|
||||||
TSK_SAFE_FREE(candidate->stun.nonce);
|
TSK_SAFE_FREE(candidate->stun.nonce);
|
||||||
TSK_SAFE_FREE(candidate->stun.realm);
|
TSK_SAFE_FREE(candidate->stun.realm);
|
||||||
TSK_SAFE_FREE(candidate->stun.srflx_addr);
|
TSK_SAFE_FREE(candidate->stun.srflx_addr);
|
||||||
|
|
||||||
|
TSK_SAFE_FREE(candidate->turn.relay_addr);
|
||||||
|
TSK_OBJECT_SAFE_FREE(candidate->turn.ss);
|
||||||
|
|
||||||
TSK_SAFE_FREE(candidate->ufrag);
|
TSK_SAFE_FREE(candidate->ufrag);
|
||||||
TSK_SAFE_FREE(candidate->pwd);
|
TSK_SAFE_FREE(candidate->pwd);
|
||||||
|
|
||||||
|
@ -342,7 +346,7 @@ const char* tnet_ice_candidate_tostring(tnet_ice_candidate_t* self)
|
||||||
|
|
||||||
int tnet_ice_candidate_send_stun_bind_request(tnet_ice_candidate_t* self, struct sockaddr_storage* server_addr, const char* username, const char* password)
|
int tnet_ice_candidate_send_stun_bind_request(tnet_ice_candidate_t* self, struct sockaddr_storage* server_addr, const char* username, const char* password)
|
||||||
{
|
{
|
||||||
tnet_stun_message_t *request = tsk_null;
|
tnet_stun_pkt_t *request = tsk_null;
|
||||||
tsk_buffer_t *buffer = tsk_null;
|
tsk_buffer_t *buffer = tsk_null;
|
||||||
int ret, sendBytes;
|
int ret, sendBytes;
|
||||||
|
|
||||||
|
@ -358,15 +362,14 @@ int tnet_ice_candidate_send_stun_bind_request(tnet_ice_candidate_t* self, struct
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(buffer = tnet_stun_message_serialize(request))){
|
if((ret = tnet_stun_pkt_write_with_padding_2(request, &buffer))){
|
||||||
TSK_DEBUG_ERROR("Failed to serialize STUN request");
|
TSK_DEBUG_ERROR("Failed to serialize STUN request");
|
||||||
ret = -3;
|
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendBytes = tnet_sockfd_sendto(self->socket->fd, (const struct sockaddr*)server_addr, buffer->data, buffer->size);// return number of sent bytes
|
sendBytes = tnet_sockfd_sendto(self->socket->fd, (const struct sockaddr*)server_addr, buffer->data, buffer->size);// return number of sent bytes
|
||||||
if(sendBytes == buffer->size){
|
if(sendBytes == buffer->size){
|
||||||
memcpy(self->stun.transac_id, request->transaction_id, sizeof(tnet_stun_transacid_t));
|
memcpy(self->stun.transac_id, request->transac_id, sizeof(tnet_stun_transac_id_t));
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -382,7 +385,7 @@ bail:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tnet_ice_candidate_process_stun_response(tnet_ice_candidate_t* self, const tnet_stun_response_t* response, tnet_fd_t fd)
|
int tnet_ice_candidate_process_stun_response(tnet_ice_candidate_t* self, const tnet_stun_pkt_resp_t* response, tnet_fd_t fd)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -391,45 +394,49 @@ int tnet_ice_candidate_process_stun_response(tnet_ice_candidate_t* self, const
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if(!(_tnet_ice_candidate_stun_transac_id_equals(response->transaction_id, self->stun.transac_id))){
|
//if(!(_tnet_ice_candidate_stun_transac_id_equals(response->transac_id, self->stun.transac_id))){
|
||||||
// TSK_DEBUG_ERROR("Transaction id mismatch");
|
// TSK_DEBUG_ERROR("Transaction id mismatch");
|
||||||
// return -2;
|
// return -2;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if(TNET_STUN_RESPONSE_IS_ERROR(response)){
|
if (TNET_STUN_PKT_RESP_IS_ERROR(response)) {
|
||||||
short code = tnet_stun_message_get_errorcode(response);
|
uint16_t u_code;
|
||||||
const char* realm = tnet_stun_message_get_realm(response);
|
if ((ret = tnet_stun_pkt_get_errorcode(response, &u_code))) {
|
||||||
const char* nonce = tnet_stun_message_get_nonce(response);
|
return ret;
|
||||||
|
|
||||||
if(code == 401 && realm && nonce){
|
|
||||||
if(!self->stun.nonce){
|
|
||||||
/* First time we get a nonce */
|
|
||||||
tsk_strupdate(&self->stun.nonce, nonce);
|
|
||||||
tsk_strupdate(&self->stun.realm, realm);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
else{
|
if (u_code == kStunErrCodeUnauthorized || u_code == kStunErrCodeStaleNonce) {
|
||||||
TSK_DEBUG_ERROR("Authentication failed");
|
const tnet_stun_attr_vdata_t* pc_attr;
|
||||||
|
if (u_code == kStunErrCodeUnauthorized) {
|
||||||
|
// Make sure this is not an authentication failure (#2 401)
|
||||||
|
// Do not send another req to avoid endless messages
|
||||||
|
if ((tnet_stun_pkt_attr_exists(response, tnet_stun_attr_type_message_integrity))) { // already has a MESSAGE-INTEGRITY?
|
||||||
|
TSK_DEBUG_ERROR("TURN authentication failed");
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
if ((ret = tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr)) == 0 && pc_attr) {
|
||||||
TSK_DEBUG_ERROR("STUN error: %hi", code);
|
tsk_strupdate(&self->stun.nonce, pc_attr->p_data_ptr);
|
||||||
|
}
|
||||||
|
if ((ret = tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_realm, (const tnet_stun_attr_t**)&pc_attr)) == 0 && pc_attr) {
|
||||||
|
tsk_strupdate(&self->stun.realm, pc_attr->p_data_ptr);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TSK_DEBUG_ERROR("STUN error: %hu", u_code);
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(TNET_STUN_RESPONSE_IS_SUCCESS(response)){
|
else if(TNET_STUN_PKT_RESP_IS_SUCCESS(response)) {
|
||||||
const tnet_stun_attribute_t *attribute;
|
const tnet_stun_attr_address_t* pc_attr_addr;
|
||||||
|
if (((ret = tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_xor_mapped_address, (const tnet_stun_attr_t**)&pc_attr_addr)) == 0 && pc_attr_addr)
|
||||||
if((attribute = tnet_stun_message_get_attribute(response, stun_xor_mapped_address))){
|
|| ((ret = tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_mapped_address, (const tnet_stun_attr_t**)&pc_attr_addr)) == 0 && pc_attr_addr)) {
|
||||||
const tnet_stun_attribute_xmapped_addr_t *xmaddr = (const tnet_stun_attribute_xmapped_addr_t *)attribute;
|
tnet_ip_t ip;
|
||||||
tnet_ice_utils_stun_address_tostring(xmaddr->xaddress, xmaddr->family, &self->stun.srflx_addr);
|
if ((ret = tnet_stun_utils_inet_ntop((pc_attr_addr->e_family == tnet_stun_address_family_ipv6), &pc_attr_addr->address, &ip))) {
|
||||||
self->stun.srflx_port = xmaddr->xport;
|
return ret;
|
||||||
}
|
}
|
||||||
else if((attribute = tnet_stun_message_get_attribute(response, stun_mapped_address))){
|
tsk_strupdate(&self->stun.srflx_addr, ip);
|
||||||
const tnet_stun_attribute_mapped_addr_t *maddr = (const tnet_stun_attribute_mapped_addr_t *)attribute;
|
self->stun.srflx_port = pc_attr_addr->u_port;
|
||||||
ret = tnet_ice_utils_stun_address_tostring(maddr->address, maddr->family, &self->stun.srflx_addr);
|
|
||||||
self->stun.srflx_port = maddr->port;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,10 +524,10 @@ static const char* _tnet_ice_candidate_get_foundation(tnet_ice_cand_type_t type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static tsk_bool_t _tnet_ice_candidate_stun_transac_id_equals(const tnet_stun_transacid_t id1, const tnet_stun_transacid_t id2)
|
static tsk_bool_t _tnet_ice_candidate_stun_transac_id_equals(const tnet_stun_transac_id_t id1, const tnet_stun_transac_id_t id2)
|
||||||
{
|
{
|
||||||
tsk_size_t i;
|
tsk_size_t i;
|
||||||
static const tsk_size_t size = sizeof(tnet_stun_transacid_t);
|
static const tsk_size_t size = sizeof(tnet_stun_transac_id_t);
|
||||||
for(i = 0; i < size; i++){
|
for(i = 0; i < size; i++){
|
||||||
if(id1[i] != id2[i]){
|
if(id1[i] != id2[i]){
|
||||||
return tsk_false;
|
return tsk_false;
|
||||||
|
@ -529,31 +536,38 @@ static tsk_bool_t _tnet_ice_candidate_stun_transac_id_equals(const tnet_stun_tra
|
||||||
return tsk_true;
|
return tsk_true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static tnet_stun_message_t * _tnet_ice_candidate_stun_create_bind_request(tnet_ice_candidate_t* self, const char* username, const char* password)
|
static tnet_stun_pkt_t * _tnet_ice_candidate_stun_create_bind_request(tnet_ice_candidate_t* self, const char* username, const char* password)
|
||||||
{
|
{
|
||||||
tnet_stun_message_t *request = tsk_null;
|
tnet_stun_pkt_t *request = tsk_null;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if(!self){
|
if (!self) {
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return tsk_null;
|
return tsk_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
request = tnet_stun_message_create(username, password);
|
if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_binding_request, &request))) {
|
||||||
|
TSK_DEBUG_ERROR("Failed to create STUN Bind request");
|
||||||
if(request){
|
goto bail;
|
||||||
tnet_stun_attribute_t* attribute;
|
}
|
||||||
request->realm = tsk_strdup(self->stun.realm);
|
// add attributes
|
||||||
request->nonce = tsk_strdup(self->stun.nonce);
|
request->opt.dontfrag = 0;
|
||||||
|
ret = tnet_stun_pkt_attrs_add(request,
|
||||||
/* Set the request type (RFC 5389 defines only one type) */
|
TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(kStunSoftware),
|
||||||
request->type = stun_binding_request;
|
TNET_STUN_PKT_ATTR_ADD_NULL());
|
||||||
|
if (ret) {
|
||||||
/* Add software attribute */
|
goto bail;
|
||||||
if((attribute = (tnet_stun_attribute_t*)tnet_stun_attribute_software_create(TNET_SOFTWARE, tsk_strlen(TNET_SOFTWARE)))){
|
}
|
||||||
tnet_stun_message_add_attribute(request, &attribute);
|
if (username && self->stun.realm && self->stun.nonce) {
|
||||||
|
if ((ret = tnet_stun_pkt_auth_prepare(request, username, password, self->stun.realm, self->stun.nonce))) {
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bail:
|
||||||
|
if (ret) {
|
||||||
|
TSK_OBJECT_SAFE_FREE(request);
|
||||||
|
}
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,10 +611,10 @@ static const char* _tnet_ice_candidate_get_candtype_str(tnet_ice_cand_type_t can
|
||||||
switch(candtype_e){
|
switch(candtype_e){
|
||||||
case tnet_ice_cand_type_unknown:
|
case tnet_ice_cand_type_unknown:
|
||||||
default: return "unknown";
|
default: return "unknown";
|
||||||
case tnet_ice_cand_type_host: return "host";
|
case tnet_ice_cand_type_host: return TNET_ICE_CANDIDATE_TYPE_HOST;
|
||||||
case tnet_ice_cand_type_srflx: return "srflx";
|
case tnet_ice_cand_type_srflx: return TNET_ICE_CANDIDATE_TYPE_SRFLX;
|
||||||
case tnet_ice_cand_type_prflx: return "prflx";
|
case tnet_ice_cand_type_prflx: return TNET_ICE_CANDIDATE_TYPE_PRFLX;
|
||||||
case tnet_ice_cand_type_relay: return "relay";
|
case tnet_ice_cand_type_relay: return TNET_ICE_CANDIDATE_TYPE_RELAY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,9 @@
|
||||||
|
|
||||||
#include "tinynet_config.h"
|
#include "tinynet_config.h"
|
||||||
|
|
||||||
#include "stun/tnet_stun_message.h"
|
#include "stun/tnet_stun_pkt.h"
|
||||||
|
#include "stun/tnet_stun_attr.h"
|
||||||
|
#include "stun/tnet_stun_utils.h"
|
||||||
#include "tnet_socket.h"
|
#include "tnet_socket.h"
|
||||||
|
|
||||||
#include "tsk_params.h"
|
#include "tsk_params.h"
|
||||||
|
@ -56,7 +58,7 @@ TNET_BEGIN_DECLS
|
||||||
#define TNET_ICE_CANDIDATE_COMPID_RTP 1
|
#define TNET_ICE_CANDIDATE_COMPID_RTP 1
|
||||||
#define TNET_ICE_CANDIDATE_COMPID_RTCP 2
|
#define TNET_ICE_CANDIDATE_COMPID_RTCP 2
|
||||||
|
|
||||||
#define TNET_ICE_CANDIDATE_FOUND_SIZE_PREF 9
|
#define TNET_ICE_CANDIDATE_FOUND_SIZE_PREF 15
|
||||||
|
|
||||||
typedef enum tnet_ice_cand_type_e
|
typedef enum tnet_ice_cand_type_e
|
||||||
{
|
{
|
||||||
|
@ -96,9 +98,14 @@ typedef struct tnet_ice_candidate_s
|
||||||
char* nonce;
|
char* nonce;
|
||||||
char* realm;
|
char* realm;
|
||||||
char* srflx_addr;
|
char* srflx_addr;
|
||||||
tnet_stun_transacid_t transac_id;
|
tnet_stun_transac_id_t transac_id;
|
||||||
tnet_port_t srflx_port;
|
tnet_port_t srflx_port;
|
||||||
} stun;
|
} stun;
|
||||||
|
struct {
|
||||||
|
struct tnet_turn_session_s* ss;
|
||||||
|
char* relay_addr;
|
||||||
|
tnet_port_t relay_port;
|
||||||
|
} turn;
|
||||||
|
|
||||||
char *tostring;
|
char *tostring;
|
||||||
}
|
}
|
||||||
|
@ -114,7 +121,7 @@ TINYNET_API const char* tnet_ice_candidate_get_att_value(const tnet_ice_candidat
|
||||||
int tnet_ice_candidate_set_local_pref(tnet_ice_candidate_t* self, uint16_t local_pref);
|
int tnet_ice_candidate_set_local_pref(tnet_ice_candidate_t* self, uint16_t local_pref);
|
||||||
TINYNET_API const char* tnet_ice_candidate_tostring(tnet_ice_candidate_t* self);
|
TINYNET_API const char* tnet_ice_candidate_tostring(tnet_ice_candidate_t* self);
|
||||||
int tnet_ice_candidate_send_stun_bind_request(tnet_ice_candidate_t* self, struct sockaddr_storage* server_addr, const char* username, const char* password);
|
int tnet_ice_candidate_send_stun_bind_request(tnet_ice_candidate_t* self, struct sockaddr_storage* server_addr, const char* username, const char* password);
|
||||||
int tnet_ice_candidate_process_stun_response(tnet_ice_candidate_t* self, const tnet_stun_response_t* response, tnet_fd_t fd);
|
int tnet_ice_candidate_process_stun_response(tnet_ice_candidate_t* self, const tnet_stun_pkt_resp_t* response, tnet_fd_t fd);
|
||||||
const tnet_ice_candidate_t* tnet_ice_candidate_find_by_fd(tnet_ice_candidates_L_t* candidates, tnet_fd_t fd);
|
const tnet_ice_candidate_t* tnet_ice_candidate_find_by_fd(tnet_ice_candidates_L_t* candidates, tnet_fd_t fd);
|
||||||
const char* tnet_ice_candidate_get_ufrag(const tnet_ice_candidate_t* self);
|
const char* tnet_ice_candidate_get_ufrag(const tnet_ice_candidate_t* self);
|
||||||
const char* tnet_ice_candidate_get_pwd(const tnet_ice_candidate_t* self);
|
const char* tnet_ice_candidate_get_pwd(const tnet_ice_candidate_t* self);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -52,6 +52,8 @@ TINYNET_API int tnet_ice_ctx_set_stun(
|
||||||
const char* password);
|
const char* password);
|
||||||
TINYNET_API int tnet_ice_ctx_set_sync_mode(struct tnet_ice_ctx_s* self, tsk_bool_t sync_mode);
|
TINYNET_API int tnet_ice_ctx_set_sync_mode(struct tnet_ice_ctx_s* self, tsk_bool_t sync_mode);
|
||||||
TINYNET_API int tnet_ice_ctx_set_silent_mode(struct tnet_ice_ctx_s* self, tsk_bool_t silent_mode);
|
TINYNET_API int tnet_ice_ctx_set_silent_mode(struct tnet_ice_ctx_s* self, tsk_bool_t silent_mode);
|
||||||
|
TINYNET_API int tnet_ice_ctx_set_stun_enabled(struct tnet_ice_ctx_s* self, tsk_bool_t stun_enabled);
|
||||||
|
TINYNET_API int tnet_ice_ctx_set_turn_enabled(struct tnet_ice_ctx_s* self, tsk_bool_t turn_enabled);
|
||||||
TINYNET_API int tnet_ice_ctx_start(struct tnet_ice_ctx_s* self);
|
TINYNET_API int tnet_ice_ctx_start(struct tnet_ice_ctx_s* self);
|
||||||
TINYNET_API int tnet_ice_ctx_rtp_callback(struct tnet_ice_ctx_s* self, tnet_ice_rtp_callback_f rtp_callback, const void* rtp_callback_data);
|
TINYNET_API int tnet_ice_ctx_rtp_callback(struct tnet_ice_ctx_s* self, tnet_ice_rtp_callback_f rtp_callback, const void* rtp_callback_data);
|
||||||
TINYNET_API int tnet_ice_ctx_set_concheck_timeout(struct tnet_ice_ctx_s* self, int64_t timeout);
|
TINYNET_API int tnet_ice_ctx_set_concheck_timeout(struct tnet_ice_ctx_s* self, int64_t timeout);
|
||||||
|
@ -60,8 +62,11 @@ TINYNET_API int tnet_ice_ctx_set_rtcpmux(struct tnet_ice_ctx_s* self, tsk_bool_t
|
||||||
TINYNET_API tsk_size_t tnet_ice_ctx_count_local_candidates(const struct tnet_ice_ctx_s* self);
|
TINYNET_API tsk_size_t tnet_ice_ctx_count_local_candidates(const struct tnet_ice_ctx_s* self);
|
||||||
TINYNET_API tsk_bool_t tnet_ice_ctx_got_local_candidates(const struct tnet_ice_ctx_s* self);
|
TINYNET_API tsk_bool_t tnet_ice_ctx_got_local_candidates(const struct tnet_ice_ctx_s* self);
|
||||||
TINYNET_API const struct tnet_ice_candidate_s* tnet_ice_ctx_get_local_candidate_at(const struct tnet_ice_ctx_s* self, tsk_size_t index);
|
TINYNET_API const struct tnet_ice_candidate_s* tnet_ice_ctx_get_local_candidate_at(const struct tnet_ice_ctx_s* self, tsk_size_t index);
|
||||||
|
#define tnet_ice_ctx_get_local_candidate_first(self) tnet_ice_ctx_get_local_candidate_at((self), 0)
|
||||||
TINYNET_API tsk_bool_t tnet_ice_ctx_is_started(const struct tnet_ice_ctx_s* self);
|
TINYNET_API tsk_bool_t tnet_ice_ctx_is_started(const struct tnet_ice_ctx_s* self);
|
||||||
TINYNET_API tsk_bool_t tnet_ice_ctx_is_active(const struct tnet_ice_ctx_s* self);
|
TINYNET_API tsk_bool_t tnet_ice_ctx_is_active(const struct tnet_ice_ctx_s* self);
|
||||||
|
TINYNET_API tsk_bool_t tnet_ice_ctx_is_turn_rtp_active(const struct tnet_ice_ctx_s* self);
|
||||||
|
TINYNET_API tsk_bool_t tnet_ice_ctx_is_turn_rtcp_active(const struct tnet_ice_ctx_s* self);
|
||||||
TINYNET_API tsk_bool_t tnet_ice_ctx_is_connected(const struct tnet_ice_ctx_s* self);
|
TINYNET_API tsk_bool_t tnet_ice_ctx_is_connected(const struct tnet_ice_ctx_s* self);
|
||||||
TINYNET_API tsk_bool_t tnet_ice_ctx_is_can_send(const struct tnet_ice_ctx_s* self);
|
TINYNET_API tsk_bool_t tnet_ice_ctx_is_can_send(const struct tnet_ice_ctx_s* self);
|
||||||
TINYNET_API tsk_bool_t tnet_ice_ctx_is_can_recv(const struct tnet_ice_ctx_s* self);
|
TINYNET_API tsk_bool_t tnet_ice_ctx_is_can_recv(const struct tnet_ice_ctx_s* self);
|
||||||
|
@ -72,6 +77,8 @@ TINYNET_API int tnet_ice_ctx_get_nominated_symetric_candidates(const struct tnet
|
||||||
const struct tnet_ice_candidate_s** candidate_answer_src,
|
const struct tnet_ice_candidate_s** candidate_answer_src,
|
||||||
const struct tnet_ice_candidate_s** candidate_answer_dest);
|
const struct tnet_ice_candidate_s** candidate_answer_dest);
|
||||||
TINYNET_API int tnet_ice_ctx_recv_stun_message(struct tnet_ice_ctx_s* self, const void* data, tsk_size_t size, tnet_fd_t local_fd, const struct sockaddr_storage* remote_addr, tsk_bool_t *role_conflict);
|
TINYNET_API int tnet_ice_ctx_recv_stun_message(struct tnet_ice_ctx_s* self, const void* data, tsk_size_t size, tnet_fd_t local_fd, const struct sockaddr_storage* remote_addr, tsk_bool_t *role_conflict);
|
||||||
|
TINYNET_API int tnet_ice_ctx_send_turn_rtp(struct tnet_ice_ctx_s* self, const void* data, tsk_size_t size);
|
||||||
|
TINYNET_API int tnet_ice_ctx_send_turn_rtcp(struct tnet_ice_ctx_s* self, const void* data, tsk_size_t size);
|
||||||
|
|
||||||
TINYNET_API const char* tnet_ice_ctx_get_ufrag(const struct tnet_ice_ctx_s* self);
|
TINYNET_API const char* tnet_ice_ctx_get_ufrag(const struct tnet_ice_ctx_s* self);
|
||||||
TINYNET_API const char* tnet_ice_ctx_get_pwd(const struct tnet_ice_ctx_s* self);
|
TINYNET_API const char* tnet_ice_ctx_get_pwd(const struct tnet_ice_ctx_s* self);
|
||||||
|
|
|
@ -40,10 +40,13 @@ typedef enum tnet_ice_event_type_e
|
||||||
tnet_ice_event_type_gathering_host_candidates_succeed,
|
tnet_ice_event_type_gathering_host_candidates_succeed,
|
||||||
tnet_ice_event_type_gathering_reflexive_candidates_failed,
|
tnet_ice_event_type_gathering_reflexive_candidates_failed,
|
||||||
tnet_ice_event_type_gathering_reflexive_candidates_succeed,
|
tnet_ice_event_type_gathering_reflexive_candidates_succeed,
|
||||||
|
tnet_ice_event_type_gathering_relay_candidates_failed,
|
||||||
|
tnet_ice_event_type_gathering_relay_candidates_succeed,
|
||||||
tnet_ice_event_type_gathering_completed,
|
tnet_ice_event_type_gathering_completed,
|
||||||
tnet_ice_event_type_conncheck_succeed,
|
tnet_ice_event_type_conncheck_succeed,
|
||||||
tnet_ice_event_type_conncheck_failed,
|
tnet_ice_event_type_conncheck_failed,
|
||||||
tnet_ice_event_type_cancelled,
|
tnet_ice_event_type_cancelled,
|
||||||
|
tnet_ice_event_type_turn_connection_broken,
|
||||||
|
|
||||||
// Private events
|
// Private events
|
||||||
tnet_ice_event_type_action
|
tnet_ice_event_type_action
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include "stun/tnet_stun.h"
|
#include "stun/tnet_stun.h"
|
||||||
#include "stun/tnet_stun_message.h"
|
#include "stun/tnet_stun_message.h"
|
||||||
|
#include "stun/tnet_stun_types.h"
|
||||||
|
#include "turn/tnet_turn_session.h"
|
||||||
|
|
||||||
#include "tnet_endianness.h"
|
#include "tnet_endianness.h"
|
||||||
#include "tnet_utils.h"
|
#include "tnet_utils.h"
|
||||||
|
@ -91,6 +93,7 @@ tnet_ice_pair_t* tnet_ice_pair_create(const tnet_ice_candidate_t* candidate_offe
|
||||||
pair->priority = (((uint64_t)TSK_MIN(candidate_offer->priority, candidate_answer->priority)) << 32) +
|
pair->priority = (((uint64_t)TSK_MIN(candidate_offer->priority, candidate_answer->priority)) << 32) +
|
||||||
(TSK_MAX(candidate_offer->priority, candidate_answer->priority) << 1) +
|
(TSK_MAX(candidate_offer->priority, candidate_answer->priority) << 1) +
|
||||||
((candidate_offer->priority > candidate_answer->priority) ? 1 : 0);
|
((candidate_offer->priority > candidate_answer->priority) ? 1 : 0);
|
||||||
|
pair->turn_peer_id = kTurnPeerIdInvalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pair;
|
return pair;
|
||||||
|
@ -105,34 +108,35 @@ tnet_ice_pair_t* tnet_ice_pair_prflx_create(tnet_ice_pairs_L_t* pairs, uint16_t
|
||||||
tnet_ip_t remote_ip;
|
tnet_ip_t remote_ip;
|
||||||
tnet_port_t remote_port;
|
tnet_port_t remote_port;
|
||||||
|
|
||||||
if(!pairs || !remote_addr){
|
if (!pairs || !remote_addr) {
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return tsk_null;
|
return tsk_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((ret = tnet_get_sockip_n_port((const struct sockaddr*)remote_addr, &remote_ip, &remote_port))){
|
tsk_list_foreach(item, pairs) {
|
||||||
TNET_PRINT_LAST_ERROR("tnet_get_sockip_n_port() failed");
|
if (!(pair = item->data) || !pair->candidate_offer || !pair->candidate_answer || !pair->candidate_offer->socket || pair->candidate_offer->socket->fd != local_fd) {
|
||||||
return tsk_null;
|
|
||||||
}
|
|
||||||
|
|
||||||
tsk_list_foreach(item, pairs){
|
|
||||||
if(!(pair = item->data) || !pair->candidate_offer || !pair->candidate_answer || !pair->candidate_offer->socket || pair->candidate_offer->socket->fd != local_fd){
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pair_local = pair;
|
pair_local = pair;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!pair_local){
|
if ((ret = tnet_get_sockip_n_port((const struct sockaddr*)remote_addr, &remote_ip, &remote_port))) {
|
||||||
|
TNET_PRINT_LAST_ERROR("tnet_get_sockip_n_port() failed");
|
||||||
|
return tsk_null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pair_local) {
|
||||||
TSK_DEBUG_ERROR("Cannot create prflx candidate with remote ip = %s and remote port = %u", remote_ip, remote_port);
|
TSK_DEBUG_ERROR("Cannot create prflx candidate with remote ip = %s and remote port = %u", remote_ip, remote_port);
|
||||||
return tsk_null;
|
return tsk_null;
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
tnet_ice_pair_t* pair_peer = tsk_null;
|
tnet_ice_pair_t* pair_peer = tsk_null;
|
||||||
tnet_ice_candidate_t* cand_local = tnet_ice_candidate_create(tnet_ice_cand_type_prflx, pair_local->candidate_offer->socket, pair_local->is_ice_jingle, pair_local->candidate_offer->is_rtp, pair_local->candidate_offer->is_video, pair_local->candidate_offer->ufrag, pair_local->candidate_offer->pwd, pair_local->candidate_offer->foundation);
|
tnet_ice_candidate_t* cand_local;
|
||||||
tnet_ice_candidate_t* cand_remote = tnet_ice_candidate_create(tnet_ice_cand_type_prflx, tsk_null, pair_local->is_ice_jingle, pair_local->candidate_answer->is_rtp, pair_local->candidate_answer->is_video, pair_local->candidate_answer->ufrag, pair_local->candidate_answer->pwd, pair_local->candidate_answer->foundation);
|
tnet_ice_candidate_t* cand_remote;
|
||||||
if(cand_local && cand_remote){
|
cand_local = tnet_ice_candidate_create(tnet_ice_cand_type_prflx, pair_local->candidate_offer->socket, pair_local->is_ice_jingle, pair_local->candidate_offer->is_rtp, pair_local->candidate_offer->is_video, pair_local->candidate_offer->ufrag, pair_local->candidate_offer->pwd, pair_local->candidate_offer->foundation);
|
||||||
|
cand_remote = tnet_ice_candidate_create(tnet_ice_cand_type_prflx, tsk_null, pair_local->is_ice_jingle, pair_local->candidate_answer->is_rtp, pair_local->candidate_answer->is_video, pair_local->candidate_answer->ufrag, pair_local->candidate_answer->pwd, pair_local->candidate_answer->foundation);
|
||||||
|
if (cand_local && cand_remote) {
|
||||||
tsk_strupdate(&cand_remote->transport_str, pair_local->candidate_offer->transport_str);
|
tsk_strupdate(&cand_remote->transport_str, pair_local->candidate_offer->transport_str);
|
||||||
cand_remote->comp_id = pair_local->candidate_offer->comp_id;
|
cand_remote->comp_id = pair_local->candidate_offer->comp_id;
|
||||||
memcpy(cand_remote->connection_addr, remote_ip, sizeof(tnet_ip_t));
|
memcpy(cand_remote->connection_addr, remote_ip, sizeof(tnet_ip_t));
|
||||||
|
@ -160,11 +164,6 @@ tnet_ice_pair_t* tnet_ice_pair_prflx_create(tnet_ice_pairs_L_t* pairs, uint16_t
|
||||||
|
|
||||||
int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
|
int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
|
||||||
{
|
{
|
||||||
char* username = tsk_null;
|
|
||||||
const char* password;
|
|
||||||
uint32_t priority;
|
|
||||||
struct sockaddr_storage remote_addr;
|
|
||||||
tnet_stun_attribute_t *stun_att;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if(!self){
|
if(!self){
|
||||||
|
@ -172,104 +171,158 @@ int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((ret = tnet_sockaddr_init(self->candidate_answer->connection_addr, self->candidate_answer->port, self->candidate_offer->socket->type, &remote_addr))){
|
if (self->candidate_offer->turn.ss) {
|
||||||
|
enum tnet_stun_state_e e_state;
|
||||||
|
if ((ret = tnet_turn_session_get_state_createperm(self->candidate_offer->turn.ss, self->turn_peer_id, &e_state))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if (e_state != tnet_stun_state_ok) {
|
||||||
|
TSK_DEBUG_INFO("TURN CreatePerm not ready yet... to send STUN ConnCheck");
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!self->last_request) {
|
||||||
|
uint32_t priority;
|
||||||
|
|
||||||
|
// Init remote address
|
||||||
|
if ((ret = tnet_sockaddr_init(self->candidate_answer->connection_addr, self->candidate_answer->port, self->candidate_offer->socket->type, &self->remote_addr))) {
|
||||||
TNET_PRINT_LAST_ERROR("tnet_sockaddr_init(%s:%d) failed", self->candidate_answer->connection_addr, self->candidate_answer->port);
|
TNET_PRINT_LAST_ERROR("tnet_sockaddr_init(%s:%d) failed", self->candidate_answer->connection_addr, self->candidate_answer->port);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_binding_request, &self->last_request))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
// 7.1.2.3. Forming Credentials
|
// 7.1.2.3. Forming Credentials
|
||||||
// username= "RFRAG:LFRAG"
|
// username= "RFRAG:LFRAG"
|
||||||
// password= "RPASS"
|
// password= "RPASS"
|
||||||
if(self->is_ice_jingle){
|
{
|
||||||
tsk_sprintf(&username, "%s%s", tnet_ice_candidate_get_ufrag(self->candidate_answer), tnet_ice_candidate_get_ufrag(self->candidate_offer));
|
char* p_uname = tsk_null;
|
||||||
|
const char* pc_pwd;
|
||||||
|
if (self->is_ice_jingle) {
|
||||||
|
tsk_sprintf(&p_uname, "%s%s", tnet_ice_candidate_get_ufrag(self->candidate_answer), tnet_ice_candidate_get_ufrag(self->candidate_offer));
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
tsk_sprintf(&username, "%s:%s", tnet_ice_candidate_get_ufrag(self->candidate_answer), tnet_ice_candidate_get_ufrag(self->candidate_offer));
|
tsk_sprintf(&p_uname, "%s:%s", tnet_ice_candidate_get_ufrag(self->candidate_answer), tnet_ice_candidate_get_ufrag(self->candidate_offer));
|
||||||
|
}
|
||||||
|
pc_pwd = tnet_ice_candidate_get_pwd(self->candidate_answer);
|
||||||
|
ret = tnet_stun_pkt_auth_prepare_shortterm(self->last_request, p_uname, pc_pwd);
|
||||||
|
TSK_FREE(p_uname);
|
||||||
|
if (ret) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
password = tnet_ice_candidate_get_pwd(self->candidate_answer);
|
|
||||||
|
|
||||||
if(!self->last_request && (self->last_request = tnet_stun_message_create(username, password))){
|
|
||||||
self->last_request->type = stun_binding_request;
|
|
||||||
|
|
||||||
// 7.1.2.1. PRIORITY
|
|
||||||
priority = tnet_ice_utils_get_priority(tnet_ice_cand_type_prflx, self->candidate_offer->local_pref, self->candidate_offer->is_rtp);
|
priority = tnet_ice_utils_get_priority(tnet_ice_cand_type_prflx, self->candidate_offer->local_pref, self->candidate_offer->is_rtp);
|
||||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_ice_priority_create(priority))){
|
// add attributes
|
||||||
tnet_stun_message_add_attribute(self->last_request, &stun_att);
|
self->last_request->opt.dontfrag = 0;
|
||||||
}
|
ret = tnet_stun_pkt_attrs_add(self->last_request,
|
||||||
// 7.1.2.1. USE-CANDIDATE
|
TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(kStunSoftware),
|
||||||
if(self->is_controlling){ // aggressive mode
|
// 7.1.2.1. PRIORITY
|
||||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_ice_use_candidate_create())){
|
TNET_STUN_PKT_ATTR_ADD_ICE_PRIORITY(priority),
|
||||||
tnet_stun_message_add_attribute(self->last_request, &stun_att);
|
TNET_STUN_PKT_ATTR_ADD_NULL());
|
||||||
}
|
if (ret) {
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
// 7.1.2.2. ICE-CONTROLLING / ICE-CONTROLLED
|
// 7.1.2.2. ICE-CONTROLLING / ICE-CONTROLLED
|
||||||
if(self->is_controlling){
|
if (self->is_controlling) {
|
||||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_ice_controlling_create(self->tie_breaker))){
|
ret = tnet_stun_pkt_attrs_add(self->last_request,
|
||||||
tnet_stun_message_add_attribute(self->last_request, &stun_att);
|
// 7.1.2.2. ICE-CONTROLLING
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_ICE_CONTROLLING(self->tie_breaker),
|
||||||
|
// 7.1.2.1. USE-CANDIDATE - aggressive mode
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_ICE_USE_CANDIDATE(),
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_NULL());
|
||||||
|
if (ret) {
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_ice_controlled_create(self->tie_breaker))){
|
ret = tnet_stun_pkt_attrs_add(self->last_request,
|
||||||
tnet_stun_message_add_attribute(self->last_request, &stun_att);
|
// 7.1.2.2. ICE-CONTROLLED
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_ICE_CONTROLLED(self->tie_breaker),
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_NULL());
|
||||||
|
if (ret) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tsk_bool_t b_changed = tsk_false;
|
||||||
|
if (self->is_controlling) {
|
||||||
|
tnet_stun_pkt_attr_remove(self->last_request, tnet_stun_attr_type_ice_controlled);
|
||||||
|
if (!tnet_stun_pkt_attr_exists(self->last_request, tnet_stun_attr_type_ice_controlling)) {
|
||||||
|
ret = tnet_stun_pkt_attrs_add(self->last_request,
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_ICE_CONTROLLING(self->tie_breaker),
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_NULL());
|
||||||
|
if (ret) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
b_changed = tsk_true;
|
||||||
|
}
|
||||||
|
if (!tnet_stun_pkt_attr_exists(self->last_request, tnet_stun_attr_type_ice_use_candidate)) {
|
||||||
|
ret = tnet_stun_pkt_attrs_add(self->last_request,
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_ICE_USE_CANDIDATE(),
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_NULL());
|
||||||
|
if (ret) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
b_changed = tsk_true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tnet_stun_pkt_attr_remove(self->last_request, tnet_stun_attr_type_ice_use_candidate);
|
||||||
|
tnet_stun_pkt_attr_remove(self->last_request, tnet_stun_attr_type_ice_controlling);
|
||||||
|
if (!tnet_stun_pkt_attr_exists(self->last_request, tnet_stun_attr_type_ice_controlled)) {
|
||||||
|
ret = tnet_stun_pkt_attrs_add(self->last_request,
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_ICE_CONTROLLED(self->tie_breaker),
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_NULL());
|
||||||
|
if (ret) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
b_changed = tsk_true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// update transac-id if the request structure changed
|
||||||
|
if ((b_changed && (ret = tnet_stun_utils_transac_id_rand(&self->last_request->transac_id)))) {
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SOFTWARE
|
// Send request
|
||||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_software_create(TNET_SOFTWARE, tsk_strlen(TNET_SOFTWARE)))){
|
{
|
||||||
tnet_stun_message_add_attribute(self->last_request, &stun_att);
|
tsk_buffer_t *req_buffer = tsk_null;
|
||||||
|
self->last_request->opt.fingerprint = !self->is_ice_jingle;
|
||||||
|
if ((ret = tnet_stun_pkt_write_with_padding_2(self->last_request, &req_buffer))) {
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
|
if (self->candidate_offer->turn.ss) {
|
||||||
|
// Send using TURN session. Above, we already checked that the TURN session is ready (Alloc=OK, Permission=OK)
|
||||||
|
ret = tnet_turn_session_send_data(self->candidate_offer->turn.ss, self->turn_peer_id, req_buffer->data, (uint16_t)req_buffer->size);
|
||||||
}
|
}
|
||||||
else if(self->last_request){
|
else {
|
||||||
if(self->is_controlling){
|
int sendBytes = tnet_sockfd_sendto(self->candidate_offer->socket->fd, (const struct sockaddr*)&self->remote_addr, req_buffer->data, req_buffer->size);
|
||||||
tnet_stun_message_remove_attribute(self->last_request, stun_ice_controlled);
|
ret = (sendBytes == req_buffer->size) ? 0 : -9;
|
||||||
if(!tnet_stun_message_has_attribute(self->last_request, stun_ice_controlling)){
|
|
||||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_ice_controlling_create(self->tie_breaker))){
|
|
||||||
tnet_stun_message_add_attribute(self->last_request, &stun_att);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(!tnet_stun_message_has_attribute(self->last_request, stun_ice_use_candidate)){
|
|
||||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_ice_use_candidate_create())){
|
|
||||||
tnet_stun_message_add_attribute(self->last_request, &stun_att);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
tnet_stun_message_remove_attribute(self->last_request, stun_ice_use_candidate);
|
|
||||||
tnet_stun_message_remove_attribute(self->last_request, stun_ice_controlling);
|
|
||||||
if(!tnet_stun_message_has_attribute(self->last_request, stun_ice_controlled)){
|
|
||||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_ice_controlled_create(self->tie_breaker))){
|
|
||||||
tnet_stun_message_add_attribute(self->last_request, &stun_att);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(self->last_request){
|
|
||||||
tsk_buffer_t *req_buffer;
|
|
||||||
self->last_request->fingerprint = !self->is_ice_jingle;
|
|
||||||
if((req_buffer = tnet_stun_message_serialize(self->last_request))){
|
|
||||||
/*int sendBytes =*/ tnet_sockfd_sendto(self->candidate_offer->socket->fd, (const struct sockaddr*)&remote_addr, req_buffer->data, req_buffer->size);
|
|
||||||
TSK_OBJECT_SAFE_FREE(req_buffer);
|
TSK_OBJECT_SAFE_FREE(req_buffer);
|
||||||
|
if (ret) {
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
TSK_FREE(username);
|
if (ret == 0 && self->state_offer == tnet_ice_pair_state_frozen) {
|
||||||
|
|
||||||
if(ret == 0 && self->state_offer == tnet_ice_pair_state_frozen){
|
|
||||||
self->state_offer = tnet_ice_pair_state_in_progress;
|
self->state_offer = tnet_ice_pair_state_in_progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tnet_ice_pair_send_response(tnet_ice_pair_t *self, const tnet_stun_request_t* request, const short code, const char* phrase, const struct sockaddr_storage *remote_addr)
|
int tnet_ice_pair_send_response(tnet_ice_pair_t *self, const tnet_stun_pkt_req_t* request, const short code, const char* phrase, const struct sockaddr_storage *remote_addr)
|
||||||
{
|
{
|
||||||
tnet_stun_message_t* message;
|
tnet_stun_pkt_t* message = tsk_null;
|
||||||
const char *password, *username;
|
const char *password, *username;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
tnet_stun_attribute_t *stun_att = tsk_null;
|
tnet_stun_attr_t *stun_att = tsk_null;
|
||||||
struct sockaddr_storage dest_addr;
|
|
||||||
tsk_bool_t is_error = ((code / 100) != 2);
|
tsk_bool_t is_error = ((code / 100) != 2);
|
||||||
|
|
||||||
if(!self || !phrase || !request || !self->candidate_offer || !self->candidate_answer){
|
if(!self || !phrase || !request || !self->candidate_offer || !self->candidate_answer){
|
||||||
|
@ -277,126 +330,108 @@ int tnet_ice_pair_send_response(tnet_ice_pair_t *self, const tnet_stun_request_t
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((ret = tnet_sockaddr_init(self->candidate_answer->connection_addr, self->candidate_answer->port, self->candidate_offer->socket->type, &dest_addr))){
|
// FIXME: "username" and "password" not used
|
||||||
TNET_PRINT_LAST_ERROR("tnet_sockaddr_init(%s:%d) failed", self->candidate_answer->connection_addr, self->candidate_answer->port);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
username = tsk_null;
|
username = tsk_null;
|
||||||
password = tnet_ice_candidate_get_pwd(self->candidate_offer);
|
password = tnet_ice_candidate_get_pwd(self->candidate_offer);
|
||||||
|
|
||||||
if((message = tnet_stun_message_create(username, password))){
|
if ((ret = tnet_stun_pkt_create_empty(is_error ? tnet_stun_pkt_type_binding_error_response : tnet_stun_pkt_type_binding_success_response, &message)) == 0) {
|
||||||
tsk_buffer_t *req_buffer;
|
tsk_buffer_t *req_buffer = tsk_null;
|
||||||
|
memcpy(message->transac_id, request->transac_id, sizeof(request->transac_id));
|
||||||
|
message->opt.fingerprint = !self->is_ice_jingle;
|
||||||
|
message->opt.dontfrag = 0;
|
||||||
|
|
||||||
message->type = is_error ? stun_binding_error_response : stun_binding_success_response;
|
// SOFWARE
|
||||||
memcpy(message->transaction_id, request->transaction_id, sizeof(request->transaction_id));
|
ret = tnet_stun_pkt_attrs_add(message,
|
||||||
message->nointegrity = self->is_ice_jingle;
|
TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(kStunSoftware),
|
||||||
message->fingerprint = !self->is_ice_jingle;
|
TNET_STUN_PKT_ATTR_ADD_NULL());
|
||||||
|
if (ret) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SHORT-TERM authentication even for responses
|
||||||
|
if ((ret = tnet_stun_pkt_auth_prepare_shortterm_2(message, password))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
// ERROR
|
// ERROR
|
||||||
if(is_error){
|
if (is_error) {
|
||||||
tnet_stun_attribute_errorcode_t* stun_att_err;
|
ret = tnet_stun_pkt_attrs_add(message,
|
||||||
if((stun_att_err = tnet_stun_attribute_errorcode_create(tsk_null, 0))){
|
TNET_STUN_PKT_ATTR_ADD_ERROR_CODE(((code / 100) & 0x07), (code - ((code / 100) * 100)), phrase),
|
||||||
stun_att_err->_class = ((code / 100) & 0x07);
|
TNET_STUN_PKT_ATTR_ADD_NULL());
|
||||||
stun_att_err->number = (code - ((code / 100) * 100));
|
if (ret) {
|
||||||
stun_att_err->reason_phrase = tsk_strdup(phrase);
|
goto bail;
|
||||||
TNET_STUN_ATTRIBUTE(stun_att_err)->length = 4 + tsk_strlen(phrase);
|
|
||||||
tnet_stun_message_add_attribute(message, (tnet_stun_attribute_t**)&stun_att_err);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
tnet_stun_attribute_xmapped_addr_t* stun_att_xma;
|
tnet_ip_t remote_ip;
|
||||||
if(self->is_ice_jingle){
|
tnet_port_t remote_port;
|
||||||
const tnet_stun_attribute_username_t * stun_att_usr_name;
|
if (self->is_ice_jingle) {
|
||||||
tnet_stun_attribute_mapped_addr_t* stun_att_ma;
|
const tnet_stun_attr_vdata_t *pc_attr_vdata;
|
||||||
|
|
||||||
// USERNAME
|
// USERNAME
|
||||||
if((stun_att_usr_name = (const tnet_stun_attribute_username_t *)tnet_stun_message_get_attribute(request, stun_username))){
|
if ((ret = tnet_stun_pkt_attr_find_first(request, tnet_stun_attr_type_username, (const tnet_stun_attr_t **)&pc_attr_vdata)) == 0 && pc_attr_vdata) {
|
||||||
stun_att_usr_name = tsk_object_ref((tsk_object_t*)stun_att_usr_name);
|
ret = tnet_stun_pkt_attrs_add(message,
|
||||||
tnet_stun_message_add_attribute(message, (tnet_stun_attribute_t**)&stun_att_usr_name);
|
TNET_STUN_PKT_ATTR_ADD_USERNAME(pc_attr_vdata->p_data_ptr, pc_attr_vdata->u_data_size),
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_NULL());
|
||||||
|
if (ret) {
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MAPPED-ADDRESS
|
|
||||||
if((stun_att_ma = tnet_stun_attribute_mapped_address_create(tsk_null, 0))){
|
|
||||||
uint32_t addr;
|
|
||||||
if(TNET_SOCKET_TYPE_IS_IPV6(self->candidate_offer->socket->type)){
|
|
||||||
tsk_size_t i;
|
|
||||||
const struct sockaddr_in6* sin6 = (const struct sockaddr_in6*)remote_addr;
|
|
||||||
stun_att_ma->family = stun_ipv6;
|
|
||||||
stun_att_ma->port = tnet_ntohs(sin6->sin6_port);
|
|
||||||
for(i = 0; i < 16; i+=4){
|
|
||||||
addr = tnet_ntohl_2(&sin6->sin6_addr.s6_addr[i]);
|
|
||||||
memcpy(&stun_att_ma->address[i], &addr, 4);
|
|
||||||
}
|
}
|
||||||
TNET_STUN_ATTRIBUTE(stun_att_ma)->length = 4 + 16;
|
|
||||||
}
|
}
|
||||||
else{
|
// MAPPED-ADDRESS and XOR-MAPPED-ADDRESS
|
||||||
const struct sockaddr_in* sin = (const struct sockaddr_in*)remote_addr;
|
if ((ret = tnet_get_sockip_n_port((const struct sockaddr*)remote_addr, &remote_ip, &remote_port)) == 0) {
|
||||||
stun_att_ma->family = stun_ipv4;
|
tnet_stun_addr_t _addr;
|
||||||
stun_att_ma->port = tnet_ntohs(sin->sin_port);
|
tnet_stun_address_family_t _familly = (remote_addr->ss_family == AF_INET6) ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4;
|
||||||
addr = tnet_ntohl(sin->sin_addr.s_addr);
|
if ((ret = tnet_stun_utils_inet_pton((_familly == tnet_stun_address_family_ipv6), remote_ip, &_addr)) == 0) {
|
||||||
memcpy(&stun_att_ma->address[0], &addr, 4);
|
ret = tnet_stun_pkt_attrs_add(message,
|
||||||
TNET_STUN_ATTRIBUTE(stun_att_ma)->length = 4 + 4;
|
TNET_STUN_PKT_ATTR_ADD_MAPPED_ADDRESS(_familly, remote_port, &_addr),
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_XOR_MAPPED_ADDRESS(_familly, remote_port, &_addr),
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_NULL());
|
||||||
|
if (ret) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tnet_stun_message_add_attribute(message, (tnet_stun_attribute_t**)&stun_att_ma);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XOR-MAPPED-ADDRESS
|
if (self->candidate_offer->turn.ss) {
|
||||||
if((stun_att_xma = tnet_stun_attribute_xmapped_address_create(tsk_null, 0))){//JINGLE_ICE
|
enum tnet_stun_state_e e_state;
|
||||||
tsk_size_t addr_size;
|
if ((ret = tnet_turn_session_get_state_createperm(self->candidate_offer->turn.ss, self->turn_peer_id, &e_state))) {
|
||||||
tsk_size_t i;
|
goto bail;
|
||||||
uint32_t addr;
|
|
||||||
if(TNET_SOCKET_TYPE_IS_IPV6(self->candidate_offer->socket->type)){
|
|
||||||
addr_size = 16;
|
|
||||||
stun_att_xma->family = stun_ipv6;
|
|
||||||
}
|
}
|
||||||
else{
|
if (e_state != tnet_stun_state_ok) {
|
||||||
addr_size = 4;
|
TSK_DEBUG_INFO("TURN CreatePerm not ready yet... to send STUN response");
|
||||||
stun_att_xma->family = stun_ipv4;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
if ((ret = tnet_stun_pkt_write_with_padding_2(message, &req_buffer))) {
|
||||||
if(stun_att_xma->family == stun_ipv4){
|
goto bail;
|
||||||
const struct sockaddr_in* sin = (const struct sockaddr_in*)remote_addr;
|
|
||||||
stun_att_xma->xport = tnet_ntohs(sin->sin_port) ^ 0x2112;
|
|
||||||
addr = (tnet_ntohl(sin->sin_addr.s_addr) ^ TNET_STUN_MAGIC_COOKIE);
|
|
||||||
memcpy(&stun_att_xma->xaddress[0], &addr, 4);
|
|
||||||
}
|
}
|
||||||
else{
|
if ((ret = tnet_turn_session_send_data(self->candidate_offer->turn.ss, self->turn_peer_id, req_buffer->data, req_buffer->size))) {
|
||||||
const struct sockaddr_in6* sin6 = (const struct sockaddr_in6*)remote_addr;
|
goto bail;
|
||||||
stun_att_xma->xport = tnet_ntohs(sin6->sin6_port) ^ 0x2112;
|
|
||||||
for(i = 0; i < addr_size; i+=4){
|
|
||||||
addr = (tnet_ntohl_2(&sin6->sin6_addr.s6_addr[i]) ^ TNET_STUN_MAGIC_COOKIE);
|
|
||||||
memcpy(&stun_att_xma->xaddress[i], &addr, 4);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
TNET_STUN_ATTRIBUTE(stun_att_xma)->length = 4 + addr_size;
|
struct sockaddr_storage dest_addr;
|
||||||
tnet_stun_message_add_attribute(message, (tnet_stun_attribute_t**)&stun_att_xma);
|
int sendBytes;
|
||||||
|
if ((ret = tnet_sockaddr_init(self->candidate_answer->connection_addr, self->candidate_answer->port, self->candidate_offer->socket->type, &dest_addr))) {
|
||||||
|
TNET_PRINT_LAST_ERROR("tnet_sockaddr_init(%s:%d) failed", self->candidate_answer->connection_addr, self->candidate_answer->port);
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
|
if ((ret = tnet_stun_pkt_write_with_padding_2(message, &req_buffer))) {
|
||||||
// SOFTWARE
|
goto bail;
|
||||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_software_create(TNET_SOFTWARE, tsk_strlen(TNET_SOFTWARE)))){
|
|
||||||
tnet_stun_message_add_attribute(message, &stun_att);
|
|
||||||
}
|
}
|
||||||
}
|
sendBytes = tnet_sockfd_sendto(self->candidate_offer->socket->fd, (const struct sockaddr*)&dest_addr, req_buffer->data, req_buffer->size);
|
||||||
|
|
||||||
if((req_buffer = tnet_stun_message_serialize(message))){
|
|
||||||
int sendBytes = tnet_sockfd_sendto(self->candidate_offer->socket->fd, (const struct sockaddr*)&dest_addr, req_buffer->data, req_buffer->size);
|
|
||||||
TSK_OBJECT_SAFE_FREE(req_buffer);
|
TSK_OBJECT_SAFE_FREE(req_buffer);
|
||||||
ret = (sendBytes > 0) ? 0 : -2;
|
ret = (sendBytes > 0) ? 0 : -2;
|
||||||
if(ret != 0){
|
if (ret != 0) {
|
||||||
TSK_DEBUG_ERROR("ICE pair-answer: failed to send response");
|
TSK_DEBUG_ERROR("ICE pair-answer: failed to send response");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TSK_OBJECT_SAFE_FREE(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ret == 0 && !is_error){
|
if (ret == 0 && !is_error) {
|
||||||
tsk_bool_t change_state =
|
tsk_bool_t change_state =
|
||||||
self->is_ice_jingle || // ICE-JINGLE don't have ICE-CONTROLLING/ICE-CONTROLLED attributes
|
self->is_ice_jingle || // ICE-JINGLE don't have ICE-CONTROLLING/ICE-CONTROLLED attributes
|
||||||
(!self->is_controlling && tnet_stun_message_has_attribute(request, stun_ice_use_candidate)) || // Sender is controlling and uses "ICE-USE-CANDIDATE" attribute
|
(!self->is_controlling && tnet_stun_pkt_attr_exists(request, tnet_stun_attr_type_ice_use_candidate)) || // Sender is controlling and uses "ICE-USE-CANDIDATE" attribute
|
||||||
(self->is_controlling) // We always use agressive nomination and final check-list will have high-priority pairs on the top
|
(self->is_controlling) // We always use agressive nomination and final check-list will have high-priority pairs on the top
|
||||||
;
|
;
|
||||||
TNET_ICE_PAIR_DEBUG_INFO("ICE pair-answer changing state to 'succeed' ? %s, comp-id=%d, found=%s, addr=%s",
|
TNET_ICE_PAIR_DEBUG_INFO("ICE pair-answer changing state to 'succeed' ? %s, comp-id=%d, found=%s, addr=%s",
|
||||||
|
@ -405,22 +440,25 @@ int tnet_ice_pair_send_response(tnet_ice_pair_t *self, const tnet_stun_request_t
|
||||||
self->candidate_answer->foundation,
|
self->candidate_answer->foundation,
|
||||||
self->candidate_answer->connection_addr
|
self->candidate_answer->connection_addr
|
||||||
);
|
);
|
||||||
if(change_state){
|
if (change_state) {
|
||||||
self->state_answer = tnet_ice_pair_state_succeed;
|
self->state_answer = tnet_ice_pair_state_succeed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bail:
|
||||||
|
TSK_OBJECT_SAFE_FREE(message);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tnet_ice_pair_auth_conncheck(const tnet_ice_pair_t *self, const tnet_stun_request_t* request, const void* request_buff, tsk_size_t request_buff_size, short* resp_code, char** resp_phrase)
|
int tnet_ice_pair_auth_conncheck(const tnet_ice_pair_t *self, const tnet_stun_pkt_req_t* request, const void* request_buff, tsk_size_t request_buff_size, short* resp_code, char** resp_phrase)
|
||||||
{
|
{
|
||||||
const uint8_t* _request_buff = (const uint8_t*)request_buff;
|
const uint8_t* _request_buff = (const uint8_t*)request_buff;
|
||||||
|
|
||||||
const tnet_stun_attribute_t* stun_att;
|
const tnet_stun_attr_t* stun_att;
|
||||||
const tnet_stun_attribute_username_t *stun_att_usr_name;
|
const tnet_stun_attr_vdata_t *stun_att_usr_name;
|
||||||
const tnet_stun_attribute_fingerprint_t *stun_att_fingerprint;
|
const tnet_stun_attr_vdata_t *stun_att_fingerprint;
|
||||||
const tnet_stun_attribute_integrity_t *stun_att_integrity;
|
const tnet_stun_attr_vdata_t *stun_att_integrity;
|
||||||
|
|
||||||
const tsk_list_item_t *item;
|
const tsk_list_item_t *item;
|
||||||
tsk_sha1digest_t hmac;
|
tsk_sha1digest_t hmac;
|
||||||
|
@ -433,7 +471,7 @@ int tnet_ice_pair_auth_conncheck(const tnet_ice_pair_t *self, const tnet_stun_re
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!TNET_IS_STUN2_MSG(_request_buff, request_buff_size)){
|
if(!TNET_STUN_BUFF_IS_STUN2(_request_buff, request_buff_size)){
|
||||||
TSK_DEBUG_ERROR("Not STUN buffer");
|
TSK_DEBUG_ERROR("Not STUN buffer");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -443,52 +481,52 @@ int tnet_ice_pair_auth_conncheck(const tnet_ice_pair_t *self, const tnet_stun_re
|
||||||
stun_att_fingerprint = tsk_null;
|
stun_att_fingerprint = tsk_null;
|
||||||
stun_att_integrity = tsk_null;
|
stun_att_integrity = tsk_null;
|
||||||
|
|
||||||
tsk_list_foreach(item, request->attributes){
|
tsk_list_foreach(item, request->p_list_attrs) {
|
||||||
if((!(stun_att = item->data))){
|
if ((!(stun_att = (const tnet_stun_attr_t*)item->data))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(stun_att->type){
|
switch (stun_att->hdr.e_type) {
|
||||||
case stun_username:
|
case tnet_stun_attr_type_username:
|
||||||
{
|
{
|
||||||
stun_att_usr_name = (const tnet_stun_attribute_username_t *)stun_att;
|
stun_att_usr_name = (const tnet_stun_attr_vdata_t *)stun_att;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case stun_fingerprint:
|
case tnet_stun_attr_type_fingerprint:
|
||||||
{
|
{
|
||||||
stun_att_fingerprint = (const tnet_stun_attribute_fingerprint_t *)stun_att;
|
stun_att_fingerprint = (const tnet_stun_attr_vdata_t *)stun_att;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case stun_message_integrity:
|
case tnet_stun_attr_type_message_integrity:
|
||||||
{
|
{
|
||||||
stun_att_integrity = (const tnet_stun_attribute_integrity_t *)stun_att;
|
stun_att_integrity = (const tnet_stun_attr_vdata_t *)stun_att;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!stun_att_integrity){
|
if (!stun_att_integrity) {
|
||||||
if((length = (4 + stun_att->length)) & 0x03){
|
if ((length = (kStunAttrHdrSizeInOctets + stun_att->hdr.u_length)) & 0x03) {
|
||||||
length += (4 - (length & 0x03));
|
length += (4 - (length & 0x03));
|
||||||
}
|
}
|
||||||
msg_integrity_start += length;
|
msg_integrity_start += length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!stun_att_usr_name){
|
if (!stun_att_usr_name) {
|
||||||
TSK_DEBUG_ERROR("USERNAME is missing");
|
TSK_DEBUG_ERROR("USERNAME is missing");
|
||||||
*resp_code = 400;
|
*resp_code = 400;
|
||||||
tsk_strupdate(resp_phrase, "USERNAME is missing");
|
tsk_strupdate(resp_phrase, "USERNAME is missing");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!stun_att_integrity){
|
if (!stun_att_integrity || stun_att_integrity->u_data_size != TSK_SHA1_DIGEST_SIZE) {
|
||||||
if(self->is_ice_jingle){ // Bug introduced in Chrome 20.0.1120.0
|
if (self->is_ice_jingle) { // Bug introduced in Chrome 20.0.1120.0 (Not security issue as ICE-JINGLE is deprecated and will never be ON)
|
||||||
*resp_code = 200;
|
*resp_code = 200;
|
||||||
tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY is missing but accepted");
|
tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY is missing but accepted");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
TSK_DEBUG_ERROR("MESSAGE-INTEGRITY is missing");
|
TSK_DEBUG_ERROR("MESSAGE-INTEGRITY is missing");
|
||||||
*resp_code = 400;
|
*resp_code = 400;
|
||||||
tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY is missing");
|
tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY is missing");
|
||||||
|
@ -496,37 +534,37 @@ int tnet_ice_pair_auth_conncheck(const tnet_ice_pair_t *self, const tnet_stun_re
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((TNET_STUN_HEADER_SIZE + msg_integrity_start) >= request_buff_size){
|
if ((kStunPktHdrSizeInOctets + msg_integrity_start) >= request_buff_size) {
|
||||||
TSK_DEBUG_ERROR("Invalid length");
|
TSK_DEBUG_ERROR("Invalid length");
|
||||||
*resp_code = 400;
|
*resp_code = 400;
|
||||||
tsk_strupdate(resp_phrase, "Invalid length");
|
tsk_strupdate(resp_phrase, "Invalid length");
|
||||||
return -20;
|
return -20;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(request->length != msg_integrity_start){
|
if (request->u_length != msg_integrity_start) {
|
||||||
tsk_size_t size = (TNET_STUN_HEADER_SIZE + msg_integrity_start);
|
tsk_size_t size = (kStunPktHdrSizeInOctets + msg_integrity_start);
|
||||||
uint8_t* new_buffer = (uint8_t*)tsk_calloc(size, 1);
|
uint8_t* new_buffer = (uint8_t*)tsk_calloc(size, 1);
|
||||||
if(!new_buffer){
|
if (!new_buffer) {
|
||||||
TSK_DEBUG_ERROR("Failed to allocate buffer with size = %u", msg_integrity_start);
|
TSK_DEBUG_ERROR("Failed to allocate buffer with size = %u", msg_integrity_start);
|
||||||
return -30;
|
return -30;
|
||||||
}
|
}
|
||||||
memcpy(new_buffer, request_buff, size);
|
memcpy(new_buffer, request_buff, size);
|
||||||
length = msg_integrity_start + (2/* Type */ + 2 /* Length */+ TSK_SHA1_DIGEST_SIZE /* INTEGRITY VALUE*/);
|
length = msg_integrity_start + (kStunAttrHdrSizeInOctets + TSK_SHA1_DIGEST_SIZE /* INTEGRITY VALUE*/);
|
||||||
new_buffer[2] = (length >> 8) & 0xFF;
|
new_buffer[2] = (length >> 8) & 0xFF;
|
||||||
new_buffer[3] = (length & 0xFF);
|
new_buffer[3] = (length & 0xFF);
|
||||||
hmac_sha1digest_compute(new_buffer, size, pwd, tsk_strlen(pwd), hmac);
|
hmac_sha1digest_compute(new_buffer, size, pwd, tsk_strlen(pwd), hmac);
|
||||||
TSK_FREE(new_buffer);
|
TSK_FREE(new_buffer);
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
// must never happen
|
// must never happen
|
||||||
hmac_sha1digest_compute(request_buff, request_buff_size, pwd, tsk_strlen(pwd), hmac);
|
hmac_sha1digest_compute(request_buff, request_buff_size, pwd, tsk_strlen(pwd), hmac);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < TSK_SHA1_DIGEST_SIZE; ++i){
|
for (i = 0; i < TSK_SHA1_DIGEST_SIZE; ++i) {
|
||||||
if(hmac[i] != stun_att_integrity->sha1digest[i]){
|
if (hmac[i] != stun_att_integrity->p_data_ptr[i]) {
|
||||||
TSK_DEBUG_ERROR("MESSAGE-INTEGRITY MISMATCH");
|
TSK_DEBUG_ERROR("MESSAGE-INTEGRITY mismatch");
|
||||||
*resp_code = 401;
|
*resp_code = 401;
|
||||||
tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY MISMATCH");
|
tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY mismatch");
|
||||||
return -40;
|
return -40;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -537,12 +575,12 @@ int tnet_ice_pair_auth_conncheck(const tnet_ice_pair_t *self, const tnet_stun_re
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tnet_ice_pair_recv_response(tnet_ice_pair_t *self, const tnet_stun_response_t* response)
|
int tnet_ice_pair_recv_response(tnet_ice_pair_t *self, const tnet_stun_pkt_resp_t* response)
|
||||||
{
|
{
|
||||||
if(self && response){
|
if(self && response){
|
||||||
if(self->last_request && tnet_stun_message_transac_id_equals(self->last_request->transaction_id, response->transaction_id)){
|
if(self->last_request && tnet_stun_utils_transac_id_equals(self->last_request->transac_id, response->transac_id)){
|
||||||
// ignore errors (e.g. STALE-CREDENTIALS) which could happen in some special cases before success
|
// ignore errors (e.g. STALE-CREDENTIALS) which could happen in some special cases before success
|
||||||
if(TNET_STUN_RESPONSE_IS_SUCCESS(response)){
|
if(TNET_STUN_PKT_RESP_IS_SUCCESS(response)){
|
||||||
self->state_offer = tnet_ice_pair_state_succeed;
|
self->state_offer = tnet_ice_pair_state_succeed;
|
||||||
TNET_ICE_PAIR_DEBUG_INFO("ICE pair-offer changing state to 'succeed', comp-id=%d, found=%s, addr=%s",
|
TNET_ICE_PAIR_DEBUG_INFO("ICE pair-offer changing state to 'succeed', comp-id=%d, found=%s, addr=%s",
|
||||||
self->candidate_offer->comp_id,
|
self->candidate_offer->comp_id,
|
||||||
|
@ -555,26 +593,28 @@ int tnet_ice_pair_recv_response(tnet_ice_pair_t *self, const tnet_stun_response_
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tnet_ice_pair_t* tnet_ice_pairs_find_by_response(tnet_ice_pairs_L_t* pairs, const tnet_stun_message_t* response)
|
const tnet_ice_pair_t* tnet_ice_pairs_find_by_response(tnet_ice_pairs_L_t* pairs, const tnet_stun_pkt_t* response)
|
||||||
{
|
{
|
||||||
if(pairs && response){
|
if(pairs && response){
|
||||||
const tsk_list_item_t *item;
|
const tsk_list_item_t *item;
|
||||||
const tnet_ice_pair_t *pair;
|
const tnet_ice_pair_t *pair;
|
||||||
tnet_port_t mapped_port;
|
tnet_port_t mapped_port;
|
||||||
char* mapped_addr_str = tsk_null;
|
tnet_ip_t mapped_ip;
|
||||||
tsk_list_foreach(item, pairs){
|
tsk_list_foreach(item, pairs){
|
||||||
if(!(pair = item->data) || !pair->candidate_answer || !pair->candidate_offer){
|
if(!(pair = item->data) || !pair->candidate_answer || !pair->candidate_offer){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(pair->last_request && tnet_stun_message_transac_id_equals(pair->last_request->transaction_id, response->transaction_id)){
|
if(pair->last_request && tnet_stun_utils_transac_id_equals(pair->last_request->transac_id, response->transac_id)){
|
||||||
// check that mapped/xmapped address match destination
|
// check that mapped/xmapped address match destination
|
||||||
const tnet_stun_attribute_xmapped_addr_t *xmapped_addr;
|
const tnet_stun_attr_address_t *xmapped_addr = tsk_null;
|
||||||
const tnet_stun_attribute_mapped_addr_t* mapped_addr = tsk_null;
|
const tnet_stun_attr_address_t* mapped_addr = tsk_null;
|
||||||
|
const tnet_stun_attr_address_t* _addr;
|
||||||
|
|
||||||
if(!(xmapped_addr = (const tnet_stun_attribute_xmapped_addr_t *)tnet_stun_message_get_attribute(response, stun_xor_mapped_address))){
|
tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_xor_mapped_address, (const tnet_stun_attr_t **)&xmapped_addr);
|
||||||
mapped_addr = (const tnet_stun_attribute_mapped_addr_t *)tnet_stun_message_get_attribute(response, stun_mapped_address);
|
tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_mapped_address, (const tnet_stun_attr_t **)&mapped_addr);
|
||||||
}
|
_addr = xmapped_addr ? xmapped_addr : mapped_addr;
|
||||||
if(!xmapped_addr && !mapped_addr){
|
|
||||||
|
if (!_addr) {
|
||||||
return pair; // do nothing if the client doesn't return mapped address STUN attribute
|
return pair; // do nothing if the client doesn't return mapped address STUN attribute
|
||||||
}
|
}
|
||||||
/* rfc 5245 7.1.3.2.1. Discovering Peer Reflexive Candidates
|
/* rfc 5245 7.1.3.2.1. Discovering Peer Reflexive Candidates
|
||||||
|
@ -599,16 +639,16 @@ const tnet_ice_pair_t* tnet_ice_pairs_find_by_response(tnet_ice_pairs_L_t* pairs
|
||||||
candidates for the media stream. Its username fragment and password
|
candidates for the media stream. Its username fragment and password
|
||||||
are the same as all other local candidates for that media stream.
|
are the same as all other local candidates for that media stream.
|
||||||
*/
|
*/
|
||||||
tnet_ice_utils_stun_address_tostring(xmapped_addr ? xmapped_addr->xaddress : mapped_addr->address, xmapped_addr ? xmapped_addr->family : mapped_addr->family, &mapped_addr_str);
|
|
||||||
mapped_port = xmapped_addr ? xmapped_addr->xport : mapped_addr->port;
|
tnet_stun_utils_inet_ntop((_addr->e_family == tnet_stun_address_family_ipv6), &_addr->address, &mapped_ip);
|
||||||
if((mapped_port != pair->candidate_offer->port || !tsk_striequals(mapped_addr_str, pair->candidate_offer->connection_addr))){
|
mapped_port = _addr->u_port;
|
||||||
|
if ((mapped_port != pair->candidate_offer->port || !tsk_striequals(mapped_ip, pair->candidate_offer->connection_addr))) {
|
||||||
TSK_DEBUG_INFO("Mapped address different than local connection address...probably symetric NAT: %s#%s or %u#%u",
|
TSK_DEBUG_INFO("Mapped address different than local connection address...probably symetric NAT: %s#%s or %u#%u",
|
||||||
pair->candidate_offer->connection_addr, mapped_addr_str,
|
pair->candidate_offer->connection_addr, mapped_ip,
|
||||||
pair->candidate_offer->port, mapped_port);
|
pair->candidate_offer->port, mapped_port);
|
||||||
// do we really need to add new local candidate?
|
// do we really need to add new local candidate?
|
||||||
// continue;
|
// continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pair;
|
return pair;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -650,6 +690,7 @@ const tnet_ice_pair_t* tnet_ice_pairs_find_by_fd_and_addr(tnet_ice_pairs_L_t* pa
|
||||||
return tsk_null;
|
return tsk_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static tsk_bool_t _tnet_ice_pairs_none_succeed(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id, const char* foundation, tsk_bool_t answer){
|
static tsk_bool_t _tnet_ice_pairs_none_succeed(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id, const char* foundation, tsk_bool_t answer){
|
||||||
if(pairs && foundation){
|
if(pairs && foundation){
|
||||||
const tsk_list_item_t *item;
|
const tsk_list_item_t *item;
|
||||||
|
@ -758,10 +799,10 @@ tsk_bool_t tnet_ice_pairs_have_nominated_symetric(const tnet_ice_pairs_L_t* pair
|
||||||
const tnet_ice_candidate_t *candidate_offer, *candidate_answer_src, *candidate_answer_dest;
|
const tnet_ice_candidate_t *candidate_offer, *candidate_answer_src, *candidate_answer_dest;
|
||||||
tsk_bool_t is_nominated_rtp, is_nominated_rtcp = tsk_true;
|
tsk_bool_t is_nominated_rtp, is_nominated_rtcp = tsk_true;
|
||||||
|
|
||||||
int ret = tnet_ice_pairs_get_nominated_symetric(pairs, TNET_ICE_CANDIDATE_COMPID_RTP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
|
int ret = tnet_ice_pairs_get_nominated_symetric_candidates(pairs, TNET_ICE_CANDIDATE_COMPID_RTP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
|
||||||
is_nominated_rtp = (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest);
|
is_nominated_rtp = (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest);
|
||||||
if(is_nominated_rtp && check_rtcp){
|
if(is_nominated_rtp && check_rtcp){
|
||||||
ret = tnet_ice_pairs_get_nominated_symetric(pairs, TNET_ICE_CANDIDATE_COMPID_RTCP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
|
ret = tnet_ice_pairs_get_nominated_symetric_candidates(pairs, TNET_ICE_CANDIDATE_COMPID_RTCP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
|
||||||
is_nominated_rtcp = (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest);
|
is_nominated_rtcp = (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest);
|
||||||
}
|
}
|
||||||
return (is_nominated_rtp && is_nominated_rtcp);
|
return (is_nominated_rtp && is_nominated_rtcp);
|
||||||
|
@ -769,17 +810,14 @@ tsk_bool_t tnet_ice_pairs_have_nominated_symetric(const tnet_ice_pairs_L_t* pair
|
||||||
|
|
||||||
// gets symetric nominated candidates with the highest priority
|
// gets symetric nominated candidates with the highest priority
|
||||||
// will succeed only if both RTP and RTCP are ok
|
// will succeed only if both RTP and RTCP are ok
|
||||||
int tnet_ice_pairs_get_nominated_symetric(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
|
int tnet_ice_pairs_get_nominated_symetric_candidates(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
|
||||||
const tnet_ice_candidate_t** candidate_offer,
|
const tnet_ice_candidate_t** candidate_offer,
|
||||||
const tnet_ice_candidate_t** candidate_answer_src,
|
const tnet_ice_candidate_t** candidate_answer_src,
|
||||||
const tnet_ice_candidate_t** candidate_answer_dest)
|
const tnet_ice_candidate_t** candidate_answer_dest)
|
||||||
{
|
{
|
||||||
const tnet_ice_pair_t *pair_offer = tsk_null;
|
int ret;
|
||||||
const tnet_ice_pair_t *pair_answer = tsk_null;
|
const tnet_ice_pair_t *pair_offer = tsk_null, *pair_answer_src = tsk_null, *pair_answer_dest = tsk_null;
|
||||||
tsk_size_t i_offer, i_answer;
|
if (!pairs || !candidate_offer || !candidate_answer_src || !candidate_answer_dest) {
|
||||||
static const tsk_bool_t __check_fullness = tsk_false; // pairs will be checked seperatly
|
|
||||||
|
|
||||||
if(!pairs || !candidate_offer || !candidate_answer_src || !candidate_answer_dest){
|
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -788,24 +826,51 @@ int tnet_ice_pairs_get_nominated_symetric(const tnet_ice_pairs_L_t* pairs, uint3
|
||||||
*candidate_answer_src = tsk_null;
|
*candidate_answer_src = tsk_null;
|
||||||
*candidate_answer_dest = tsk_null;
|
*candidate_answer_dest = tsk_null;
|
||||||
|
|
||||||
|
if ((ret = tnet_ice_pairs_get_nominated_symetric_pairs(pairs, comp_id, &pair_offer, &pair_answer_src, &pair_answer_dest)) == 0) {
|
||||||
|
*candidate_offer = pair_offer ? pair_offer->candidate_offer : tsk_null;
|
||||||
|
*candidate_answer_src = pair_answer_src ? pair_answer_src->candidate_answer : tsk_null;
|
||||||
|
*candidate_answer_dest = pair_answer_dest ? pair_answer_dest->candidate_answer : tsk_null;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tnet_ice_pairs_get_nominated_symetric_pairs(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
|
||||||
|
const struct tnet_ice_pair_s** _pair_offer,
|
||||||
|
const struct tnet_ice_pair_s** _pair_answer_src,
|
||||||
|
const struct tnet_ice_pair_s** _pair_answer_dest)
|
||||||
|
{
|
||||||
|
const tnet_ice_pair_t *pair_offer = tsk_null;
|
||||||
|
const tnet_ice_pair_t *pair_answer = tsk_null;
|
||||||
|
tsk_size_t i_offer, i_answer;
|
||||||
|
static const tsk_bool_t __check_fullness = tsk_false; // pairs will be checked seperatly
|
||||||
|
|
||||||
|
if (!pairs || !_pair_offer || !_pair_answer_src || !_pair_answer_dest) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*_pair_offer = tsk_null;
|
||||||
|
*_pair_answer_src = tsk_null;
|
||||||
|
*_pair_answer_dest = tsk_null;
|
||||||
|
|
||||||
i_offer = 0;
|
i_offer = 0;
|
||||||
while(1){
|
while (1) {
|
||||||
_tnet_ice_pairs_get_nominated_offer_at((pairs), i_offer, comp_id, __check_fullness, (pair_offer)); // pair with socket SO as sender
|
_tnet_ice_pairs_get_nominated_offer_at((pairs), i_offer, comp_id, __check_fullness, (pair_offer)); // pair with socket SO as sender
|
||||||
if(!pair_offer) return 0;
|
if(!pair_offer) return 0;
|
||||||
++i_offer;
|
++i_offer;
|
||||||
if(pair_offer->candidate_offer->comp_id != comp_id) continue;
|
if (pair_offer->candidate_offer->comp_id != comp_id) continue;
|
||||||
// find another pair with socket SO as receiver
|
// find another pair with socket SO as receiver
|
||||||
|
|
||||||
i_answer = 0;
|
i_answer = 0;
|
||||||
while(1){
|
while (1) {
|
||||||
_tnet_ice_pairs_get_nominated_answer_at((pairs), i_answer, comp_id, __check_fullness, (pair_answer));
|
_tnet_ice_pairs_get_nominated_answer_at((pairs), i_answer, comp_id, __check_fullness, (pair_answer));
|
||||||
if(!pair_answer) break;
|
if (!pair_answer) break;
|
||||||
++i_answer;
|
++i_answer;
|
||||||
if(pair_answer->candidate_offer->comp_id != comp_id) continue;
|
if (pair_answer->candidate_offer->comp_id != comp_id) continue;
|
||||||
if(pair_answer->candidate_offer == pair_offer->candidate_offer){
|
if (pair_answer->candidate_offer == pair_offer->candidate_offer) {
|
||||||
*candidate_offer = pair_offer->candidate_offer;
|
*_pair_offer = pair_offer;
|
||||||
*candidate_answer_src = pair_answer->candidate_answer;
|
*_pair_answer_src = pair_answer;
|
||||||
*candidate_answer_dest = pair_offer->candidate_answer;
|
*_pair_answer_dest = pair_offer;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "tinynet_config.h"
|
#include "tinynet_config.h"
|
||||||
|
|
||||||
#include "tnet_types.h"
|
#include "tnet_types.h"
|
||||||
|
#include "stun/tnet_stun_types.h"
|
||||||
|
|
||||||
#include "tsk_list.h"
|
#include "tsk_list.h"
|
||||||
|
|
||||||
|
@ -51,27 +52,34 @@ typedef struct tnet_ice_pair_s
|
||||||
tnet_ice_pair_state_t state_answer;
|
tnet_ice_pair_state_t state_answer;
|
||||||
tsk_bool_t is_ice_jingle;
|
tsk_bool_t is_ice_jingle;
|
||||||
tsk_bool_t is_controlling;
|
tsk_bool_t is_controlling;
|
||||||
|
tsk_bool_t is_nominated;
|
||||||
uint64_t tie_breaker;
|
uint64_t tie_breaker;
|
||||||
struct tnet_ice_candidate_s* candidate_offer;
|
struct tnet_ice_candidate_s* candidate_offer;
|
||||||
struct tnet_ice_candidate_s* candidate_answer;
|
struct tnet_ice_candidate_s* candidate_answer;
|
||||||
struct tnet_stun_message_s* last_request;
|
struct tnet_stun_pkt_s* last_request;
|
||||||
|
struct sockaddr_storage remote_addr;
|
||||||
|
tnet_turn_peer_id_t turn_peer_id;
|
||||||
}
|
}
|
||||||
tnet_ice_pair_t;
|
tnet_ice_pair_t;
|
||||||
|
|
||||||
tnet_ice_pair_t* tnet_ice_pair_create(const struct tnet_ice_candidate_s* candidate_offer, const struct tnet_ice_candidate_s* candidate_answer, tsk_bool_t is_controlling, uint64_t tie_breaker, tsk_bool_t is_ice_jingle);
|
tnet_ice_pair_t* tnet_ice_pair_create(const struct tnet_ice_candidate_s* candidate_offer, const struct tnet_ice_candidate_s* candidate_answer, tsk_bool_t is_controlling, uint64_t tie_breaker, tsk_bool_t is_ice_jingle);
|
||||||
tnet_ice_pair_t* tnet_ice_pair_prflx_create(tnet_ice_pairs_L_t* pairs, uint16_t local_fd, const struct sockaddr_storage *remote_addr);
|
tnet_ice_pair_t* tnet_ice_pair_prflx_create(tnet_ice_pairs_L_t* pairs, uint16_t local_fd, const struct sockaddr_storage *remote_addr);
|
||||||
int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self);
|
int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self);
|
||||||
int tnet_ice_pair_send_response(tnet_ice_pair_t *self, const struct tnet_stun_message_s* request, const short code, const char* phrase, const struct sockaddr_storage *remote_addr);
|
int tnet_ice_pair_send_response(tnet_ice_pair_t *self, const struct tnet_stun_pkt_s* request, const short code, const char* phrase, const struct sockaddr_storage *remote_addr);
|
||||||
int tnet_ice_pair_auth_conncheck(const tnet_ice_pair_t *self, const struct tnet_stun_message_s* request, const void* request_buff, tsk_size_t request_buff_size, short* resp_code, char** resp_phrase);
|
int tnet_ice_pair_auth_conncheck(const tnet_ice_pair_t *self, const struct tnet_stun_pkt_s* request, const void* request_buff, tsk_size_t request_buff_size, short* resp_code, char** resp_phrase);
|
||||||
int tnet_ice_pair_recv_response(tnet_ice_pair_t *self, const struct tnet_stun_message_s* response);
|
int tnet_ice_pair_recv_response(tnet_ice_pair_t *self, const struct tnet_stun_pkt_s* response);
|
||||||
const tnet_ice_pair_t* tnet_ice_pairs_find_by_response(tnet_ice_pairs_L_t* pairs, const struct tnet_stun_message_s* response);
|
const tnet_ice_pair_t* tnet_ice_pairs_find_by_response(tnet_ice_pairs_L_t* pairs, const struct tnet_stun_pkt_s* response);
|
||||||
const tnet_ice_pair_t* tnet_ice_pairs_find_by_fd_and_addr(tnet_ice_pairs_L_t* pairs, uint16_t local_fd, const struct sockaddr_storage *remote_addr);
|
const tnet_ice_pair_t* tnet_ice_pairs_find_by_fd_and_addr(tnet_ice_pairs_L_t* pairs, uint16_t local_fd, const struct sockaddr_storage *remote_addr);
|
||||||
tsk_bool_t tnet_ice_pairs_have_nominated_offer(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp);
|
tsk_bool_t tnet_ice_pairs_have_nominated_offer(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp);
|
||||||
tsk_bool_t tnet_ice_pairs_have_nominated_answer(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp);
|
tsk_bool_t tnet_ice_pairs_have_nominated_answer(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp);
|
||||||
tsk_bool_t tnet_ice_pairs_have_nominated_symetric(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp);
|
tsk_bool_t tnet_ice_pairs_have_nominated_symetric(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp);
|
||||||
int tnet_ice_pairs_get_nominated_symetric(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
|
int tnet_ice_pairs_get_nominated_symetric_candidates(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
|
||||||
const struct tnet_ice_candidate_s** candidate_offer,
|
const struct tnet_ice_candidate_s** candidate_offer,
|
||||||
const struct tnet_ice_candidate_s** candidate_answer_src,
|
const struct tnet_ice_candidate_s** candidate_answer_src,
|
||||||
const struct tnet_ice_candidate_s** candidate_answer_dest);
|
const struct tnet_ice_candidate_s** candidate_answer_dest);
|
||||||
|
int tnet_ice_pairs_get_nominated_symetric_pairs(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
|
||||||
|
const struct tnet_ice_pair_s** pair_offer,
|
||||||
|
const struct tnet_ice_pair_s** pair_answer_src,
|
||||||
|
const struct tnet_ice_pair_s** pair_answer_dest);
|
||||||
|
|
||||||
#endif /* TNET_ICE_PAIR_H */
|
#endif /* TNET_ICE_PAIR_H */
|
||||||
|
|
|
@ -125,24 +125,6 @@ int tnet_ice_utils_create_sockets(tnet_socket_type_t socket_type, const char* lo
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: use tnet_stun_utils_inet_ntop()
|
|
||||||
int tnet_ice_utils_stun_address_tostring(const uint8_t in_ip[16], enum tnet_stun_addr_family_e family, char** out_ip)
|
|
||||||
{
|
|
||||||
if(family == stun_ipv6){
|
|
||||||
tsk_sprintf(out_ip, "%x:%x:%x:%x:%x:%x:%x:%x",
|
|
||||||
TSK_TO_UINT16(&in_ip[0]), TSK_TO_UINT16(&in_ip[2]), TSK_TO_UINT16(&in_ip[4]), TSK_TO_UINT16(&in_ip[6]),
|
|
||||||
TSK_TO_UINT16(&in_ip[8]), TSK_TO_UINT16(&in_ip[10]), TSK_TO_UINT16(&in_ip[12]), TSK_TO_UINT16(&in_ip[14]));
|
|
||||||
}
|
|
||||||
else if(family == stun_ipv4){
|
|
||||||
tsk_sprintf(out_ip, "%u.%u.%u.%u", in_ip[0], in_ip[1], in_ip[2], in_ip[3]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
TSK_DEBUG_ERROR("Unsupported address family: %u.", family);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tnet_ice_utils_set_ufrag(char** ufrag)
|
int tnet_ice_utils_set_ufrag(char** ufrag)
|
||||||
{
|
{
|
||||||
if(ufrag){
|
if(ufrag){
|
||||||
|
|
|
@ -35,7 +35,6 @@ struct tnet_socket_s;
|
||||||
uint32_t tnet_ice_utils_get_priority(enum tnet_ice_cand_type_e type, uint16_t local_pref, tsk_bool_t is_rtp);
|
uint32_t tnet_ice_utils_get_priority(enum tnet_ice_cand_type_e type, uint16_t local_pref, tsk_bool_t is_rtp);
|
||||||
int tnet_ice_utils_compute_foundation(char* foundation, tsk_size_t size);
|
int tnet_ice_utils_compute_foundation(char* foundation, tsk_size_t size);
|
||||||
int tnet_ice_utils_create_sockets(enum tnet_socket_type_e socket_type, const char* local_ip, struct tnet_socket_s** socket_rtp, struct tnet_socket_s** socket_rtcp);
|
int tnet_ice_utils_create_sockets(enum tnet_socket_type_e socket_type, const char* local_ip, struct tnet_socket_s** socket_rtp, struct tnet_socket_s** socket_rtcp);
|
||||||
int tnet_ice_utils_stun_address_tostring(const uint8_t in_ip[16], enum tnet_stun_addr_family_e family, char** out_ip);
|
|
||||||
int tnet_ice_utils_set_ufrag(char** ufrag);
|
int tnet_ice_utils_set_ufrag(char** ufrag);
|
||||||
int tnet_ice_utils_set_pwd(char** pwd);
|
int tnet_ice_utils_set_pwd(char** pwd);
|
||||||
|
|
||||||
|
|
|
@ -1,440 +1,440 @@
|
||||||
/*
|
///*
|
||||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
//* Copyright (C) 2010-2011 Mamadou Diop.
|
||||||
*
|
//*
|
||||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
//*
|
||||||
* This file is part of Open Source Doubango Framework.
|
//* This file is part of Open Source Doubango Framework.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
//* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
//* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
//* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
//* (at your option) any later version.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is distributed in the hope that it will be useful,
|
//* DOUBANGO is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
//* GNU General Public License for more details.
|
||||||
*
|
//*
|
||||||
* You should have received a copy of the GNU General Public License
|
//* You should have received a copy of the GNU General Public License
|
||||||
* along with DOUBANGO.
|
//* along with DOUBANGO.
|
||||||
*
|
//*
|
||||||
*/
|
//*/
|
||||||
|
//
|
||||||
/**@file tnet_stun.c
|
///**@file tnet_stun.c
|
||||||
* @brief Session Traversal Utilities for NAT (STUN) implementation as per RFC 5389 and RFC 3489(Obsolete).
|
// * @brief Session Traversal Utilities for NAT (STUN) implementation as per RFC 5389 and RFC 3489(Obsolete).
|
||||||
*
|
// *
|
||||||
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
// * @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
// *
|
||||||
|
//
|
||||||
*/
|
// */
|
||||||
#include "tnet_stun.h"
|
//#include "tnet_stun.h"
|
||||||
|
//
|
||||||
#include "../tnet_nat.h"
|
//#include "../tnet_nat.h"
|
||||||
#include "../tnet_utils.h"
|
//#include "../tnet_utils.h"
|
||||||
|
//
|
||||||
#include "tsk_md5.h"
|
//#include "tsk_md5.h"
|
||||||
#include "tsk_string.h"
|
//#include "tsk_string.h"
|
||||||
#include "tsk_memory.h"
|
//#include "tsk_memory.h"
|
||||||
#include "tsk_buffer.h"
|
//#include "tsk_buffer.h"
|
||||||
#include "tsk_debug.h"
|
//#include "tsk_debug.h"
|
||||||
|
//
|
||||||
#include <string.h>
|
//#include <string.h>
|
||||||
|
//
|
||||||
/**@defgroup tnet_stun_group STUN2 (RFC 5389) implementation.
|
///**@defgroup tnet_stun_group STUN2 (RFC 5389) implementation.
|
||||||
*/
|
//*/
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* Creates new @ref tnet_stun_binding_t object.
|
//* Creates new @ref tnet_stun_binding_t object.
|
||||||
*/
|
//*/
|
||||||
tnet_stun_binding_t* tnet_stun_binding_create(tnet_fd_t fd, tnet_socket_type_t socket_type, const char* server_address, tnet_port_t server_port, const char* username, const char* password)
|
//tnet_stun_binding_t* tnet_stun_binding_create(tnet_fd_t fd, tnet_socket_type_t socket_type, const char* server_address, tnet_port_t server_port, const char* username, const char* password)
|
||||||
{
|
//{
|
||||||
return tsk_object_new(tnet_stun_binding_def_t, fd, socket_type, server_address, server_port, username, password);
|
// return tsk_object_new(tnet_stun_binding_def_t, fd, socket_type, server_address, server_port, username, password);
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
*
|
// *
|
||||||
* Create generic STUN2 request with all mandatory headers and attributes.
|
// * Create generic STUN2 request with all mandatory headers and attributes.
|
||||||
*
|
// *
|
||||||
* @param [in,out] binding The binding object from which to create the request.
|
// * @param [in,out] binding The binding object from which to create the request.
|
||||||
*
|
// *
|
||||||
* @retval STUN2 request if succeed and NULL otherwise.
|
// * @retval STUN2 request if succeed and NULL otherwise.
|
||||||
**/
|
//**/
|
||||||
tnet_stun_message_t *tnet_stun_create_request(const tnet_stun_binding_t* binding)
|
//tnet_stun_pkt_t *tnet_stun_create_request(const tnet_stun_binding_t* binding)
|
||||||
{
|
//{
|
||||||
tnet_stun_message_t *message = tnet_stun_message_create(binding->username, binding->password);
|
// tnet_stun_pkt_t *message = tnet_stun_message_create(binding->username, binding->password);
|
||||||
|
//
|
||||||
if(message) {
|
// if(message) {
|
||||||
message->realm = tsk_strdup(binding->realm);
|
// message->realm = tsk_strdup(binding->realm);
|
||||||
message->nonce = tsk_strdup(binding->nonce);
|
// message->nonce = tsk_strdup(binding->nonce);
|
||||||
|
//
|
||||||
/* Set the request type (RFC 5389 defines only one type) */
|
// /* Set the request type (RFC 5389 defines only one type) */
|
||||||
message->type = stun_binding_request;
|
// message->type = stun_binding_request;
|
||||||
|
//
|
||||||
{ /* Create random transaction id */
|
// { /* Create random transaction id */
|
||||||
tsk_istr_t random;
|
// tsk_istr_t random;
|
||||||
tsk_md5digest_t digest;
|
// tsk_md5digest_t digest;
|
||||||
|
//
|
||||||
tsk_strrandom(&random);
|
// tsk_strrandom(&random);
|
||||||
TSK_MD5_DIGEST_CALC(random, sizeof(random), digest);
|
// TSK_MD5_DIGEST_CALC(random, sizeof(random), digest);
|
||||||
|
//
|
||||||
memcpy(message->transaction_id, digest, TNET_STUN_TRANSACID_SIZE);
|
// memcpy(message->transac_id, digest, TNET_STUN_TRANSACID_SIZE);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/* Add software attribute */
|
// /* Add software attribute */
|
||||||
if(binding->software) {
|
// if(binding->software) {
|
||||||
tnet_stun_attribute_t* attribute = (tnet_stun_attribute_t*)tnet_stun_attribute_software_create(binding->software, tsk_strlen(binding->software));
|
// tnet_stun_attr_t* attribute = (tnet_stun_attr_t*)tnet_stun_attribute_software_create(binding->software, tsk_strlen(binding->software));
|
||||||
tnet_stun_message_add_attribute(message, &attribute);
|
// tnet_stun_message_add_attribute(message, &attribute);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return message;
|
// return message;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
int tnet_stun_send_reliably(const tnet_stun_message_t* message)
|
//int tnet_stun_send_reliably(const tnet_stun_pkt_t* message)
|
||||||
{
|
//{
|
||||||
return -1;
|
// return -1;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
*
|
// *
|
||||||
* Internal function to send a STUN message using unrealiable protocol such as UDP.
|
// * Internal function to send a STUN message using unrealiable protocol such as UDP.
|
||||||
*
|
// *
|
||||||
*
|
// *
|
||||||
* @param localFD The local file descriptor.
|
// * @param localFD The local file descriptor.
|
||||||
* @param RTO The Retransmission TimeOut.
|
// * @param RTO The Retransmission TimeOut.
|
||||||
* @param Rc The Number of retransmissions.
|
// * @param Rc The Number of retransmissions.
|
||||||
* @param [in,out] message The message to send.
|
// * @param [in,out] message The message to send.
|
||||||
* @param [in,out] server The destination STUN server.
|
// * @param [in,out] server The destination STUN server.
|
||||||
*
|
// *
|
||||||
* @return The response from the server or NULL if transport error.
|
// * @return The response from the server or NULL if transport error.
|
||||||
**/
|
//**/
|
||||||
tnet_stun_response_t* tnet_stun_send_unreliably(tnet_fd_t localFD, uint16_t RTO, uint16_t Rc, const tnet_stun_message_t* message, struct sockaddr* server)
|
//tnet_stun_pkt_resp_t* tnet_stun_send_unreliably(tnet_fd_t localFD, uint16_t RTO, uint16_t Rc, const tnet_stun_pkt_t* message, struct sockaddr* server)
|
||||||
{
|
//{
|
||||||
/* RFC 5389 - 7.2.1. Sending over UDP
|
// /* RFC 5389 - 7.2.1. Sending over UDP
|
||||||
STUN indications are not retransmitted; thus, indication transactions over UDP
|
// STUN indications are not retransmitted; thus, indication transactions over UDP
|
||||||
are not reliable.
|
// are not reliable.
|
||||||
*/
|
// */
|
||||||
//int retransmit = (message->type == stun_binding_request);
|
// //int retransmit = (message->type == stun_binding_request);
|
||||||
|
//
|
||||||
int ret = -1;
|
// int ret = -1;
|
||||||
uint16_t i, rto = RTO;
|
// uint16_t i, rto = RTO;
|
||||||
struct timeval tv;
|
// struct timeval tv;
|
||||||
fd_set set;
|
// fd_set set;
|
||||||
|
//
|
||||||
tsk_buffer_t *buffer = tnet_stun_message_serialize(message);
|
// tsk_buffer_t *buffer = tnet_stun_pkt_serialize(message);
|
||||||
tnet_stun_response_t *response = tsk_null;
|
// tnet_stun_pkt_resp_t *response = tsk_null;
|
||||||
|
//
|
||||||
if(!buffer) {
|
// if(!buffer) {
|
||||||
goto bail;
|
// goto bail;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
{
|
// {
|
||||||
//#ifndef SIO_UDP_CONNRESET
|
////#ifndef SIO_UDP_CONNRESET
|
||||||
//# ifndef IOC_VENDOR
|
////# ifndef IOC_VENDOR
|
||||||
//# define IOC_VENDOR 0x18000000
|
////# define IOC_VENDOR 0x18000000
|
||||||
//# endif
|
////# endif
|
||||||
//# ifndef _WSAIOW
|
////# ifndef _WSAIOW
|
||||||
//# define _WSAIOW(x,y) (IOC_IN|(x)|(y))
|
////# define _WSAIOW(x,y) (IOC_IN|(x)|(y))
|
||||||
//# endif
|
////# endif
|
||||||
//# define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
|
////# define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
|
||||||
|
////#endif
|
||||||
|
//// DWORD dwBytesReturned = 0;
|
||||||
|
//// BOOL bNewBehavior = TRUE;
|
||||||
|
//// DWORD status;
|
||||||
|
////
|
||||||
|
//// // disable new behavior using
|
||||||
|
//// // IOCTL: SIO_UDP_CONNRESET
|
||||||
|
//// status = WSAIoctl(localFD, SIO_UDP_CONNRESET, &bNewBehavior, sizeof(bNewBehavior),
|
||||||
|
//// NULL, 0, &dwBytesReturned, NULL, NULL);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// tv.tv_sec = 0;
|
||||||
|
// tv.tv_usec = 0;
|
||||||
|
//
|
||||||
|
// /* RFC 5389 - 7.2.1. Sending over UDP
|
||||||
|
// A client SHOULD retransmit a STUN request message starting with an
|
||||||
|
// interval of RTO ("Retransmission TimeOut"), doubling after each
|
||||||
|
// retransmission.
|
||||||
|
//
|
||||||
|
// e.g. 0 ms, 500 ms, 1500 ms, 3500 ms, 7500ms, 15500 ms, and 31500 ms
|
||||||
|
// */
|
||||||
|
// for(i=0; i<Rc; i++) {
|
||||||
|
// tv.tv_sec += rto/1000;
|
||||||
|
// tv.tv_usec += (rto% 1000) * 1000;
|
||||||
|
//
|
||||||
|
// FD_ZERO(&set);
|
||||||
|
// FD_SET(localFD, &set);
|
||||||
|
//
|
||||||
|
// ret = tnet_sockfd_sendto(localFD, server, buffer->data, buffer->size);
|
||||||
|
//
|
||||||
|
// if((ret = select(localFD+1, &set, NULL, NULL, &tv))<0) {
|
||||||
|
// goto bail;
|
||||||
|
// }
|
||||||
|
// else if(ret == 0) {
|
||||||
|
// /* timeout */
|
||||||
|
// TSK_DEBUG_INFO("STUN request timedout at %d", i);
|
||||||
|
// rto *= 2;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// else if(FD_ISSET(localFD, &set)) {
|
||||||
|
// /* there is data to read */
|
||||||
|
//
|
||||||
|
// tsk_size_t len = 0;
|
||||||
|
// void* data = 0;
|
||||||
|
//
|
||||||
|
// TSK_DEBUG_INFO("STUN request got response");
|
||||||
|
//
|
||||||
|
// /* Check how how many bytes are pending */
|
||||||
|
// if((ret = tnet_ioctlt(localFD, FIONREAD, &len))<0) {
|
||||||
|
// goto bail;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(len==0) {
|
||||||
|
// TSK_DEBUG_INFO("tnet_ioctlt() returent zero bytes");
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /* Receive pending data */
|
||||||
|
// data = tsk_calloc(len, sizeof(uint8_t));
|
||||||
|
// if((ret = tnet_sockfd_recvfrom(localFD, data, len, 0, server))<0) {
|
||||||
|
// TSK_FREE(data);
|
||||||
|
//
|
||||||
|
// TSK_DEBUG_ERROR("Recving STUN dgrams failed with error code:%d", tnet_geterrno());
|
||||||
|
// goto bail;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /* Parse the incoming response. */
|
||||||
|
// response = tnet_stun_message_deserialize(data, (tsk_size_t)ret);
|
||||||
|
// TSK_FREE(data);
|
||||||
|
//
|
||||||
|
// if(response) {
|
||||||
|
// if(tnet_stun_transacid_cmp(message->transac_id, response->transac_id)) {
|
||||||
|
// /* Not same transaction id */
|
||||||
|
// TSK_OBJECT_SAFE_FREE(response);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// goto bail;
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//bail:
|
||||||
|
// TSK_OBJECT_SAFE_FREE(buffer);
|
||||||
|
//
|
||||||
|
// return response;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
///**@ingroup tnet_stun_group
|
||||||
|
// * Internal function to send a STUN2 binding request over the network.
|
||||||
|
// *
|
||||||
|
// * @param [in,out] context The NAT context holding the user preferences.
|
||||||
|
// * @param [in,out] binding The STUN binding object used to create the message to send.
|
||||||
|
// *
|
||||||
|
// * @return Zero if succeed and non-zero error code otherwise.
|
||||||
|
//**/
|
||||||
|
//int tnet_stun_send_bind(const tnet_nat_context_t* context, tnet_stun_binding_t *binding)
|
||||||
|
//{
|
||||||
|
// int ret = -1;
|
||||||
|
// tnet_stun_pkt_resp_t *response = 0;
|
||||||
|
// tnet_stun_pkt_req_t *request = 0;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// goto stun_phase0;
|
||||||
|
//
|
||||||
|
// /* RFC 5389 - 10.2.1.1. First Request
|
||||||
|
// If the client has not completed a successful request/response
|
||||||
|
// transaction with the server (as identified by hostname, if the DNS
|
||||||
|
// procedures of Section 9 are used, else IP address if not), it SHOULD
|
||||||
|
// omit the USERNAME, MESSAGE-INTEGRITY, REALM, and NONCE attributes.
|
||||||
|
// In other words, the very first request is sent as if there were no
|
||||||
|
// authentication or message integrity applied.
|
||||||
|
// */
|
||||||
|
//stun_phase0: {
|
||||||
|
// if(!(request = tnet_stun_create_request(binding))) {
|
||||||
|
// goto bail;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(TNET_SOCKET_TYPE_IS_DGRAM(context->socket_type)) {
|
||||||
|
// response = tnet_stun_send_unreliably(binding->localFD, context->RTO, context->Rc, request, (struct sockaddr*)&binding->server);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(response) {
|
||||||
|
// if(TNET_STUN_PKT_RESP_IS_ERROR(response)) {
|
||||||
|
// short code = tnet_stun_message_get_errorcode(response);
|
||||||
|
// const char* realm = tnet_stun_message_get_realm(response);
|
||||||
|
// const char* nonce = tnet_stun_message_get_nonce(response);
|
||||||
|
//
|
||||||
|
// if(code == 401 && realm && nonce) {
|
||||||
|
// if(!binding->nonce) {
|
||||||
|
// /* First time we get a nonce */
|
||||||
|
// tsk_strupdate(&binding->nonce, nonce);
|
||||||
|
// tsk_strupdate(&binding->realm, realm);
|
||||||
|
//
|
||||||
|
// /* Delete the message and response before retrying*/
|
||||||
|
// TSK_OBJECT_SAFE_FREE(response);
|
||||||
|
// TSK_OBJECT_SAFE_FREE(request);
|
||||||
|
//
|
||||||
|
// // Send again using new transaction identifier
|
||||||
|
// return tnet_stun_send_bind(context, binding);
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// ret = -3;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// ret = -2;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// const tnet_stun_attr_t *attribute;
|
||||||
|
// if((attribute= tnet_stun_message_get_attribute(response, stun_xor_mapped_address))) {
|
||||||
|
// ret = 0;
|
||||||
|
// binding->xmaddr = tsk_object_ref((void*)attribute);
|
||||||
|
// }
|
||||||
|
// else if((attribute= tnet_stun_message_get_attribute(response, stun_mapped_address))) {
|
||||||
|
// ret = 0;
|
||||||
|
// binding->maddr = tsk_object_ref((void*)attribute);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// /* END OF stun_phase0 */
|
||||||
|
//
|
||||||
|
//bail:
|
||||||
|
// TSK_OBJECT_SAFE_FREE(response);
|
||||||
|
// TSK_OBJECT_SAFE_FREE(request);
|
||||||
|
//
|
||||||
|
// return ret;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
///**@ingroup tnet_stun_group
|
||||||
|
// *
|
||||||
|
// * Public function to create a binding context.
|
||||||
|
// *
|
||||||
|
// * @param [in,out] nat_context The NAT context.
|
||||||
|
// * @param localFD The local file descriptor for which to create the binding context.
|
||||||
|
// *
|
||||||
|
// * @return A valid binding id if succeed and @ref kStunBindingInvalidId otherwise. If the returned id is valid then
|
||||||
|
// * the newly created binding will contain the server reflexive address associated to the local file descriptor.
|
||||||
|
//**/
|
||||||
|
//tnet_stun_binding_id_t tnet_stun_bind(const tnet_nat_context_t* nat_context, tnet_fd_t localFD)
|
||||||
|
//{
|
||||||
|
// tnet_stun_binding_id_t id = kStunBindingInvalidId;
|
||||||
|
//
|
||||||
|
// tnet_stun_binding_t *binding = 0;
|
||||||
|
//
|
||||||
|
// if(nat_context && localFD != TNET_INVALID_FD) {
|
||||||
|
// if(!(binding = tnet_stun_binding_create(localFD, nat_context->socket_type, nat_context->server_address, nat_context->server_port, nat_context->username, nat_context->password))) {
|
||||||
|
// goto bail;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(tnet_stun_send_bind(nat_context, binding)) {
|
||||||
|
// TSK_OBJECT_SAFE_FREE(binding);
|
||||||
|
// goto bail;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// id = binding->id;
|
||||||
|
// tsk_list_push_back_data(nat_context->stun_bindings, (void**)&binding);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//bail:
|
||||||
|
// return id;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
///**@ingroup tnet_stun_group
|
||||||
|
// * Compares two transaction ids.
|
||||||
|
// *
|
||||||
|
// * @param id1 The first transaction identifier.
|
||||||
|
// * @param id2 The second transaction identifier.
|
||||||
|
// *
|
||||||
|
// * @return Zero if the two identifiers are equal and non-zero value otherwise.
|
||||||
|
//**/
|
||||||
|
//int tnet_stun_transacid_cmp(const tnet_stun_transac_id_t id1, const tnet_stun_transac_id_t id2)
|
||||||
|
//{
|
||||||
|
// tsk_size_t i;
|
||||||
|
// for(i=0; i<sizeof(tnet_stun_transac_id_t); i++) {
|
||||||
|
// if(id1[i] != id2[i]) {
|
||||||
|
// return (id1[i] - id2[i]);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return 0;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
////=================================================================================================
|
||||||
|
//// STUN2 BINDING object definition
|
||||||
|
////
|
||||||
|
//static tsk_object_t* tnet_stun_binding_ctor(tsk_object_t * self, va_list * app)
|
||||||
|
//{
|
||||||
|
// tnet_stun_binding_t *binding = self;
|
||||||
|
// if(binding) {
|
||||||
|
// static tnet_stun_binding_id_t __binding_unique_id = 0;
|
||||||
|
//
|
||||||
|
// const char* server_address;
|
||||||
|
// tnet_port_t server_port;
|
||||||
|
//
|
||||||
|
// binding->id = ++__binding_unique_id;
|
||||||
|
//
|
||||||
|
// binding->localFD = va_arg(*app, tnet_fd_t);
|
||||||
|
// binding->socket_type = va_arg(*app, tnet_socket_type_t);
|
||||||
|
//
|
||||||
|
// server_address = tsk_strdup(va_arg(*app, const char*));
|
||||||
|
//#if defined(__GNUC__)
|
||||||
|
// server_port = (tnet_port_t)va_arg(*app, unsigned);
|
||||||
|
//#else
|
||||||
|
// server_port = va_arg(*app, tnet_port_t);
|
||||||
//#endif
|
//#endif
|
||||||
// DWORD dwBytesReturned = 0;
|
|
||||||
// BOOL bNewBehavior = TRUE;
|
|
||||||
// DWORD status;
|
|
||||||
//
|
//
|
||||||
// // disable new behavior using
|
// binding->username = tsk_strdup(va_arg(*app, const char*));
|
||||||
// // IOCTL: SIO_UDP_CONNRESET
|
// binding->password = tsk_strdup(va_arg(*app, const char*));
|
||||||
// status = WSAIoctl(localFD, SIO_UDP_CONNRESET, &bNewBehavior, sizeof(bNewBehavior),
|
//
|
||||||
// NULL, 0, &dwBytesReturned, NULL, NULL);
|
// if(server_address) {
|
||||||
}
|
// tnet_sockaddr_init(server_address, server_port, binding->socket_type, &binding->server);
|
||||||
|
// }
|
||||||
tv.tv_sec = 0;
|
//
|
||||||
tv.tv_usec = 0;
|
// binding->software = tsk_strdup(TNET_SOFTWARE);
|
||||||
|
// }
|
||||||
/* RFC 5389 - 7.2.1. Sending over UDP
|
// return self;
|
||||||
A client SHOULD retransmit a STUN request message starting with an
|
//}
|
||||||
interval of RTO ("Retransmission TimeOut"), doubling after each
|
//
|
||||||
retransmission.
|
//static tsk_object_t* tnet_stun_binding_dtor(tsk_object_t * self)
|
||||||
|
//{
|
||||||
e.g. 0 ms, 500 ms, 1500 ms, 3500 ms, 7500ms, 15500 ms, and 31500 ms
|
// tnet_stun_binding_t *binding = self;
|
||||||
*/
|
// if(binding) {
|
||||||
for(i=0; i<Rc; i++) {
|
// TSK_FREE(binding->username);
|
||||||
tv.tv_sec += rto/1000;
|
// TSK_FREE(binding->password);
|
||||||
tv.tv_usec += (rto% 1000) * 1000;
|
// TSK_FREE(binding->realm);
|
||||||
|
// TSK_FREE(binding->nonce);
|
||||||
FD_ZERO(&set);
|
//
|
||||||
FD_SET(localFD, &set);
|
// TSK_FREE(binding->software);
|
||||||
|
//
|
||||||
ret = tnet_sockfd_sendto(localFD, server, buffer->data, buffer->size);
|
// TSK_OBJECT_SAFE_FREE(binding->maddr);
|
||||||
|
// TSK_OBJECT_SAFE_FREE(binding->xmaddr);
|
||||||
if((ret = select(localFD+1, &set, NULL, NULL, &tv))<0) {
|
// }
|
||||||
goto bail;
|
//
|
||||||
}
|
// return self;
|
||||||
else if(ret == 0) {
|
//}
|
||||||
/* timeout */
|
//
|
||||||
TSK_DEBUG_INFO("STUN request timedout at %d", i);
|
//static const tsk_object_def_t tnet_stun_binding_def_s = {
|
||||||
rto *= 2;
|
// sizeof(tnet_stun_binding_t),
|
||||||
continue;
|
// tnet_stun_binding_ctor,
|
||||||
}
|
// tnet_stun_binding_dtor,
|
||||||
else if(FD_ISSET(localFD, &set)) {
|
// tsk_null,
|
||||||
/* there is data to read */
|
//};
|
||||||
|
//const tsk_object_def_t *tnet_stun_binding_def_t = &tnet_stun_binding_def_s;
|
||||||
tsk_size_t len = 0;
|
//
|
||||||
void* data = 0;
|
|
||||||
|
|
||||||
TSK_DEBUG_INFO("STUN request got response");
|
|
||||||
|
|
||||||
/* Check how how many bytes are pending */
|
|
||||||
if((ret = tnet_ioctlt(localFD, FIONREAD, &len))<0) {
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(len==0) {
|
|
||||||
TSK_DEBUG_INFO("tnet_ioctlt() returent zero bytes");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Receive pending data */
|
|
||||||
data = tsk_calloc(len, sizeof(uint8_t));
|
|
||||||
if((ret = tnet_sockfd_recvfrom(localFD, data, len, 0, server))<0) {
|
|
||||||
TSK_FREE(data);
|
|
||||||
|
|
||||||
TSK_DEBUG_ERROR("Recving STUN dgrams failed with error code:%d", tnet_geterrno());
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse the incoming response. */
|
|
||||||
response = tnet_stun_message_deserialize(data, (tsk_size_t)ret);
|
|
||||||
TSK_FREE(data);
|
|
||||||
|
|
||||||
if(response) {
|
|
||||||
if(tnet_stun_transacid_cmp(message->transaction_id, response->transaction_id)) {
|
|
||||||
/* Not same transaction id */
|
|
||||||
TSK_OBJECT_SAFE_FREE(response);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bail:
|
|
||||||
TSK_OBJECT_SAFE_FREE(buffer);
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@ingroup tnet_stun_group
|
|
||||||
* Internal function to send a STUN2 binding request over the network.
|
|
||||||
*
|
|
||||||
* @param [in,out] context The NAT context holding the user preferences.
|
|
||||||
* @param [in,out] binding The STUN binding object used to create the message to send.
|
|
||||||
*
|
|
||||||
* @return Zero if succeed and non-zero error code otherwise.
|
|
||||||
**/
|
|
||||||
int tnet_stun_send_bind(const tnet_nat_context_t* context, tnet_stun_binding_t *binding)
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
tnet_stun_response_t *response = 0;
|
|
||||||
tnet_stun_request_t *request = 0;
|
|
||||||
|
|
||||||
|
|
||||||
goto stun_phase0;
|
|
||||||
|
|
||||||
/* RFC 5389 - 10.2.1.1. First Request
|
|
||||||
If the client has not completed a successful request/response
|
|
||||||
transaction with the server (as identified by hostname, if the DNS
|
|
||||||
procedures of Section 9 are used, else IP address if not), it SHOULD
|
|
||||||
omit the USERNAME, MESSAGE-INTEGRITY, REALM, and NONCE attributes.
|
|
||||||
In other words, the very first request is sent as if there were no
|
|
||||||
authentication or message integrity applied.
|
|
||||||
*/
|
|
||||||
stun_phase0: {
|
|
||||||
if(!(request = tnet_stun_create_request(binding))) {
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(TNET_SOCKET_TYPE_IS_DGRAM(context->socket_type)) {
|
|
||||||
response = tnet_stun_send_unreliably(binding->localFD, context->RTO, context->Rc, request, (struct sockaddr*)&binding->server);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(response) {
|
|
||||||
if(TNET_STUN_RESPONSE_IS_ERROR(response)) {
|
|
||||||
short code = tnet_stun_message_get_errorcode(response);
|
|
||||||
const char* realm = tnet_stun_message_get_realm(response);
|
|
||||||
const char* nonce = tnet_stun_message_get_nonce(response);
|
|
||||||
|
|
||||||
if(code == 401 && realm && nonce) {
|
|
||||||
if(!binding->nonce) {
|
|
||||||
/* First time we get a nonce */
|
|
||||||
tsk_strupdate(&binding->nonce, nonce);
|
|
||||||
tsk_strupdate(&binding->realm, realm);
|
|
||||||
|
|
||||||
/* Delete the message and response before retrying*/
|
|
||||||
TSK_OBJECT_SAFE_FREE(response);
|
|
||||||
TSK_OBJECT_SAFE_FREE(request);
|
|
||||||
|
|
||||||
// Send again using new transaction identifier
|
|
||||||
return tnet_stun_send_bind(context, binding);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ret = -3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ret = -2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const tnet_stun_attribute_t *attribute;
|
|
||||||
if((attribute= tnet_stun_message_get_attribute(response, stun_xor_mapped_address))) {
|
|
||||||
ret = 0;
|
|
||||||
binding->xmaddr = tsk_object_ref((void*)attribute);
|
|
||||||
}
|
|
||||||
else if((attribute= tnet_stun_message_get_attribute(response, stun_mapped_address))) {
|
|
||||||
ret = 0;
|
|
||||||
binding->maddr = tsk_object_ref((void*)attribute);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* END OF stun_phase0 */
|
|
||||||
|
|
||||||
bail:
|
|
||||||
TSK_OBJECT_SAFE_FREE(response);
|
|
||||||
TSK_OBJECT_SAFE_FREE(request);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@ingroup tnet_stun_group
|
|
||||||
*
|
|
||||||
* Public function to create a binding context.
|
|
||||||
*
|
|
||||||
* @param [in,out] nat_context The NAT context.
|
|
||||||
* @param localFD The local file descriptor for which to create the binding context.
|
|
||||||
*
|
|
||||||
* @return A valid binding id if succeed and @ref TNET_STUN_INVALID_BINDING_ID otherwise. If the returned id is valid then
|
|
||||||
* the newly created binding will contain the server reflexive address associated to the local file descriptor.
|
|
||||||
**/
|
|
||||||
tnet_stun_binding_id_t tnet_stun_bind(const tnet_nat_context_t* nat_context, tnet_fd_t localFD)
|
|
||||||
{
|
|
||||||
tnet_stun_binding_id_t id = TNET_STUN_INVALID_BINDING_ID;
|
|
||||||
|
|
||||||
tnet_stun_binding_t *binding = 0;
|
|
||||||
|
|
||||||
if(nat_context && localFD != TNET_INVALID_FD) {
|
|
||||||
if(!(binding = tnet_stun_binding_create(localFD, nat_context->socket_type, nat_context->server_address, nat_context->server_port, nat_context->username, nat_context->password))) {
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tnet_stun_send_bind(nat_context, binding)) {
|
|
||||||
TSK_OBJECT_SAFE_FREE(binding);
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
id = binding->id;
|
|
||||||
tsk_list_push_back_data(nat_context->stun_bindings, (void**)&binding);
|
|
||||||
}
|
|
||||||
|
|
||||||
bail:
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@ingroup tnet_stun_group
|
|
||||||
* Compares two transaction ids.
|
|
||||||
*
|
|
||||||
* @param id1 The first transaction identifier.
|
|
||||||
* @param id2 The second transaction identifier.
|
|
||||||
*
|
|
||||||
* @return Zero if the two identifiers are equal and non-zero value otherwise.
|
|
||||||
**/
|
|
||||||
int tnet_stun_transacid_cmp(const tnet_stun_transacid_t id1, const tnet_stun_transacid_t id2)
|
|
||||||
{
|
|
||||||
tsk_size_t i;
|
|
||||||
for(i=0; i<sizeof(tnet_stun_transacid_t); i++) {
|
|
||||||
if(id1[i] != id2[i]) {
|
|
||||||
return (id1[i] - id2[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=================================================================================================
|
|
||||||
// STUN2 BINDING object definition
|
|
||||||
//
|
//
|
||||||
static tsk_object_t* tnet_stun_binding_ctor(tsk_object_t * self, va_list * app)
|
|
||||||
{
|
|
||||||
tnet_stun_binding_t *binding = self;
|
|
||||||
if(binding) {
|
|
||||||
static tnet_stun_binding_id_t __binding_unique_id = 0;
|
|
||||||
|
|
||||||
const char* server_address;
|
|
||||||
tnet_port_t server_port;
|
|
||||||
|
|
||||||
binding->id = ++__binding_unique_id;
|
|
||||||
|
|
||||||
binding->localFD = va_arg(*app, tnet_fd_t);
|
|
||||||
binding->socket_type = va_arg(*app, tnet_socket_type_t);
|
|
||||||
|
|
||||||
server_address = tsk_strdup(va_arg(*app, const char*));
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
server_port = (tnet_port_t)va_arg(*app, unsigned);
|
|
||||||
#else
|
|
||||||
server_port = va_arg(*app, tnet_port_t);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
binding->username = tsk_strdup(va_arg(*app, const char*));
|
|
||||||
binding->password = tsk_strdup(va_arg(*app, const char*));
|
|
||||||
|
|
||||||
if(server_address) {
|
|
||||||
tnet_sockaddr_init(server_address, server_port, binding->socket_type, &binding->server);
|
|
||||||
}
|
|
||||||
|
|
||||||
binding->software = tsk_strdup(TNET_SOFTWARE);
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
static tsk_object_t* tnet_stun_binding_dtor(tsk_object_t * self)
|
|
||||||
{
|
|
||||||
tnet_stun_binding_t *binding = self;
|
|
||||||
if(binding) {
|
|
||||||
TSK_FREE(binding->username);
|
|
||||||
TSK_FREE(binding->password);
|
|
||||||
TSK_FREE(binding->realm);
|
|
||||||
TSK_FREE(binding->nonce);
|
|
||||||
|
|
||||||
TSK_FREE(binding->software);
|
|
||||||
|
|
||||||
TSK_OBJECT_SAFE_FREE(binding->maddr);
|
|
||||||
TSK_OBJECT_SAFE_FREE(binding->xmaddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const tsk_object_def_t tnet_stun_binding_def_s = {
|
|
||||||
sizeof(tnet_stun_binding_t),
|
|
||||||
tnet_stun_binding_ctor,
|
|
||||||
tnet_stun_binding_dtor,
|
|
||||||
tsk_null,
|
|
||||||
};
|
|
||||||
const tsk_object_def_t *tnet_stun_binding_def_t = &tnet_stun_binding_def_s;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,127 +1,127 @@
|
||||||
/*
|
///*
|
||||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
//* Copyright (C) 2010-2011 Mamadou Diop.
|
||||||
*
|
//*
|
||||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
//*
|
||||||
* This file is part of Open Source Doubango Framework.
|
//* This file is part of Open Source Doubango Framework.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
//* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
//* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
//* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
//* (at your option) any later version.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is distributed in the hope that it will be useful,
|
//* DOUBANGO is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
//* GNU General Public License for more details.
|
||||||
*
|
//*
|
||||||
* You should have received a copy of the GNU General Public License
|
//* You should have received a copy of the GNU General Public License
|
||||||
* along with DOUBANGO.
|
//* along with DOUBANGO.
|
||||||
*
|
//*
|
||||||
*/
|
//*/
|
||||||
|
//
|
||||||
/**@file tnet_stun.h
|
///**@file tnet_stun.h
|
||||||
* @brief Session Traversal Utilities for NAT (STUN) implementation as per RFC 5389 and RFC 3489(Obsolete).
|
// * @brief Session Traversal Utilities for NAT (STUN) implementation as per RFC 5389 and RFC 3489(Obsolete).
|
||||||
*
|
// *
|
||||||
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
// * @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
// *
|
||||||
|
//
|
||||||
*/
|
// */
|
||||||
#ifndef TNET_STUN_H
|
//#ifndef TNET_STUN_H
|
||||||
#define TNET_STUN_H
|
//#define TNET_STUN_H
|
||||||
|
//
|
||||||
#include "tinynet_config.h"
|
//#include "tinynet_config.h"
|
||||||
#include "stun/tnet_stun_message.h"
|
//#include "stun/tnet_stun_message.h"
|
||||||
#include "tnet_types.h"
|
//#include "tnet_types.h"
|
||||||
#include "tnet_socket.h"
|
//#include "tnet_socket.h"
|
||||||
|
//
|
||||||
#include "tsk_object.h"
|
//#include "tsk_object.h"
|
||||||
|
//
|
||||||
TNET_BEGIN_DECLS
|
//TNET_BEGIN_DECLS
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
*/
|
//*/
|
||||||
typedef uint64_t tnet_stun_binding_id_t;
|
////typedef uint64_t tnet_stun_binding_id_t;
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* @def TNET_STUN_INVALID_BINDING_ID
|
// * @def kStunBindingInvalidId
|
||||||
* STUN2 invalid binding id.
|
// * STUN2 invalid binding id.
|
||||||
**/
|
//**/
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* @def TNET_STUN_IS_VALID_BINDING_ID
|
// * @def TNET_STUN_IS_VALID_BINDING_ID
|
||||||
* Checks the validity of the STUN @a id.
|
// * Checks the validity of the STUN @a id.
|
||||||
**/
|
//**/
|
||||||
#define TNET_STUN_INVALID_BINDING_ID 0
|
//#define kStunBindingInvalidId 0
|
||||||
#define TNET_STUN_IS_VALID_BINDING_ID(id) (id != TNET_STUN_INVALID_BINDING_ID)
|
//#define TNET_STUN_IS_VALID_BINDING_ID(id) (id != kStunBindingInvalidId)
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* Default port for both TCP and UDP protos as per RFC 5389 subclause 9.
|
// * Default port for both TCP and UDP protos as per RFC 5389 subclause 9.
|
||||||
**/
|
//**/
|
||||||
#define TNET_STUN_TCP_UDP_DEFAULT_PORT 3478
|
//#define TNET_STUN_TCP_UDP_DEFAULT_PORT 3478
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* Default port for TLS protocol as per RFC 5389 subclause 9.
|
// * Default port for TLS protocol as per RFC 5389 subclause 9.
|
||||||
**/
|
//**/
|
||||||
#define TNET_STUN_TLS_DEFAULT_PORT 5349
|
//#define TNET_STUN_TLS_DEFAULT_PORT 5349
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* STUN2 magic cookie value in network byte order as per RFC 5389 subclause 6.
|
// * STUN2 magic cookie value in network byte order as per RFC 5389 subclause 6.
|
||||||
**/
|
//**/
|
||||||
#define TNET_STUN_MAGIC_COOKIE 0x2112A442
|
//#define kStunMagicCookieLong 0x2112A442
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* STUN2 header size as per RFC 5389 subclause 6.
|
// * STUN2 header size as per RFC 5389 subclause 6.
|
||||||
**/
|
//**/
|
||||||
#define TNET_STUN_HEADER_SIZE 20
|
//#define kStunAttrHdrSizeInOctets 20
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* STUN2 binding context.
|
// * STUN2 binding context.
|
||||||
**/
|
//**/
|
||||||
typedef struct tnet_stun_binding_s {
|
//typedef struct tnet_stun_binding_s {
|
||||||
TSK_DECLARE_OBJECT;
|
// TSK_DECLARE_OBJECT;
|
||||||
|
//
|
||||||
//! A unique id to identify this binding.
|
// //! A unique id to identify this binding.
|
||||||
tnet_stun_binding_id_t id;
|
// tnet_stun_binding_id_t id;
|
||||||
|
//
|
||||||
//! The username to authenticate to the STUN server.
|
// //! The username to authenticate to the STUN server.
|
||||||
char* username;
|
// char* username;
|
||||||
//! The password to authenticate to the STUN server.
|
// //! The password to authenticate to the STUN server.
|
||||||
char* password;
|
// char* password;
|
||||||
//! The realm.
|
// //! The realm.
|
||||||
char* realm;
|
// char* realm;
|
||||||
//! The nonce.
|
// //! The nonce.
|
||||||
char* nonce;
|
// char* nonce;
|
||||||
//! The client name.
|
// //! The client name.
|
||||||
char* software;
|
// char* software;
|
||||||
//! Local file descriptor for which to get server reflexive address.
|
// //! Local file descriptor for which to get server reflexive address.
|
||||||
tnet_fd_t localFD;
|
// tnet_fd_t localFD;
|
||||||
//! The type of the bound socket.
|
// //! The type of the bound socket.
|
||||||
tnet_socket_type_t socket_type;
|
// tnet_socket_type_t socket_type;
|
||||||
//! The address of the STUN server.
|
// //! The address of the STUN server.
|
||||||
struct sockaddr_storage server;
|
// struct sockaddr_storage server;
|
||||||
//! Server reflexive address of the local socket(STUN1 as per RFC 3489).
|
// //! Server reflexive address of the local socket(STUN1 as per RFC 3489).
|
||||||
tnet_stun_attribute_mapped_addr_t *maddr;
|
// tnet_stun_attribute_mapped_addr_t *maddr;
|
||||||
//! XORed server reflexive address (STUN2 as per RFC 5389).
|
// //! XORed server reflexive address (STUN2 as per RFC 5389).
|
||||||
tnet_stun_attribute_xmapped_addr_t *xmaddr;
|
// tnet_stun_attribute_xmapped_addr_t *xmaddr;
|
||||||
} tnet_stun_binding_t;
|
//} tnet_stun_binding_t;
|
||||||
|
//
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_binding_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_binding_def_t;
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* List of @ref tnet_stun_binding_t elements.
|
// * List of @ref tnet_stun_binding_t elements.
|
||||||
**/
|
//**/
|
||||||
typedef tsk_list_t tnet_stun_bindings_L_t;
|
//typedef tsk_list_t tnet_stun_bindings_L_t;
|
||||||
|
//
|
||||||
//#if defined(__SYMBIAN32__) || ANDROID /* Forward declaration */
|
////#if defined(__SYMBIAN32__) || ANDROID /* Forward declaration */
|
||||||
struct tnet_nat_context_s;
|
//struct struct tnet_nat_ctx_s;
|
||||||
//#endif
|
////#endif
|
||||||
|
//
|
||||||
int tnet_stun_send_reliably(const tnet_stun_message_t* message);
|
//int tnet_stun_send_reliably(const tnet_stun_pkt_t* message);
|
||||||
tnet_stun_response_t* tnet_stun_send_unreliably(tnet_fd_t localFD, uint16_t RTO, uint16_t Rc, const tnet_stun_message_t* message, struct sockaddr* server);
|
//tnet_stun_pkt_resp_t* tnet_stun_send_unreliably(tnet_fd_t localFD, uint16_t RTO, uint16_t Rc, const tnet_stun_pkt_t* message, struct sockaddr* server);
|
||||||
TINYNET_API tnet_stun_binding_id_t tnet_stun_bind(const struct tnet_nat_context_s* nat_context, tnet_fd_t localFD);
|
//TINYNET_API tnet_stun_binding_id_t tnet_stun_bind(const struct struct tnet_nat_ctx_s* nat_context, tnet_fd_t localFD);
|
||||||
int tnet_stun_transacid_cmp(const tnet_stun_transacid_t id1, const tnet_stun_transacid_t id2);
|
//int tnet_stun_transacid_cmp(const tnet_stun_transac_id_t id1, const tnet_stun_transac_id_t id2);
|
||||||
|
//
|
||||||
TNET_END_DECLS
|
//TNET_END_DECLS
|
||||||
|
//
|
||||||
|
//
|
||||||
#endif /* TNET_STUN_H */
|
//#endif /* TNET_STUN_H */
|
||||||
|
//
|
||||||
|
|
|
@ -28,6 +28,10 @@
|
||||||
#define kWithoutPadding tsk_false
|
#define kWithoutPadding tsk_false
|
||||||
#define kWithPadding tsk_true
|
#define kWithPadding tsk_true
|
||||||
|
|
||||||
|
#if !defined(PRINT_DESTROYED_MSG)
|
||||||
|
# define PRINT_DESTROYED_MSG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ALIGN_ON_32BITS(size_in_octes) if (((size_in_octes) & 3)) (size_in_octes) += (4 - ((size_in_octes) & 3));
|
#define ALIGN_ON_32BITS(size_in_octes) if (((size_in_octes) & 3)) (size_in_octes) += (4 - ((size_in_octes) & 3));
|
||||||
#define ALIGN_ON_32BITS_AND_SET_PADDING_ZEROS(p_buffer, size_in_octes) \
|
#define ALIGN_ON_32BITS_AND_SET_PADDING_ZEROS(p_buffer, size_in_octes) \
|
||||||
if (((size_in_octes) & 3)) { \
|
if (((size_in_octes) & 3)) { \
|
||||||
|
@ -507,7 +511,9 @@ static tsk_object_t* tnet_stun_attr_vdata_dtor(tsk_object_t * self)
|
||||||
{
|
{
|
||||||
tnet_stun_attr_vdata_t *p_vdata = (tnet_stun_attr_vdata_t *)self;
|
tnet_stun_attr_vdata_t *p_vdata = (tnet_stun_attr_vdata_t *)self;
|
||||||
if (p_vdata) {
|
if (p_vdata) {
|
||||||
|
#if PRINT_DESTROYED_MSG
|
||||||
TSK_DEBUG_INFO("*** STUN Attribute(VDATA) destroyed ***");
|
TSK_DEBUG_INFO("*** STUN Attribute(VDATA) destroyed ***");
|
||||||
|
#endif
|
||||||
TSK_FREE(p_vdata->p_data_ptr);
|
TSK_FREE(p_vdata->p_data_ptr);
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
@ -564,7 +570,9 @@ static tsk_object_t* tnet_stun_attr_address_dtor(tsk_object_t * self)
|
||||||
{
|
{
|
||||||
tnet_stun_attr_address_t *p_addr = (tnet_stun_attr_address_t *)self;
|
tnet_stun_attr_address_t *p_addr = (tnet_stun_attr_address_t *)self;
|
||||||
if (p_addr) {
|
if (p_addr) {
|
||||||
|
#if PRINT_DESTROYED_MSG
|
||||||
TSK_DEBUG_INFO("*** STUN Attribute(ADDRESS) destroyed ***");
|
TSK_DEBUG_INFO("*** STUN Attribute(ADDRESS) destroyed ***");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -624,7 +632,9 @@ static tsk_object_t* tnet_stun_attr_error_code_dtor(tsk_object_t * self)
|
||||||
{
|
{
|
||||||
tnet_stun_attr_error_code_t *p_ec = (tnet_stun_attr_error_code_t *)self;
|
tnet_stun_attr_error_code_t *p_ec = (tnet_stun_attr_error_code_t *)self;
|
||||||
if (p_ec) {
|
if (p_ec) {
|
||||||
|
#if PRINT_DESTROYED_MSG
|
||||||
TSK_DEBUG_INFO("*** STUN Attribute(ERROR-CODE) destroyed ***");
|
TSK_DEBUG_INFO("*** STUN Attribute(ERROR-CODE) destroyed ***");
|
||||||
|
#endif
|
||||||
TSK_FREE(p_ec->p_reason_phrase);
|
TSK_FREE(p_ec->p_reason_phrase);
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,356 +1,356 @@
|
||||||
/*
|
///*
|
||||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
//* Copyright (C) 2010-2011 Mamadou Diop.
|
||||||
*
|
//*
|
||||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
//*
|
||||||
* This file is part of Open Source Doubango Framework.
|
//* This file is part of Open Source Doubango Framework.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
//* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
//* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
//* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
//* (at your option) any later version.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is distributed in the hope that it will be useful,
|
//* DOUBANGO is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
//* GNU General Public License for more details.
|
||||||
*
|
//*
|
||||||
* You should have received a copy of the GNU General Public License
|
//* You should have received a copy of the GNU General Public License
|
||||||
* along with DOUBANGO.
|
//* along with DOUBANGO.
|
||||||
*
|
//*
|
||||||
*/
|
//*/
|
||||||
|
//
|
||||||
/**@file tnet_stun_attribute.h
|
///**@file tnet_stun_attribute.h
|
||||||
* @brief STUN2(RFC 5389) attribute parser.
|
// * @brief STUN2(RFC 5389) attribute parser.
|
||||||
*
|
// *
|
||||||
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
// * @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
// *
|
||||||
|
//
|
||||||
*/
|
// */
|
||||||
#ifndef TNET_STUN_ATTRIBUTE_H
|
//#ifndef TNET_STUN_ATTRIBUTE_H
|
||||||
#define TNET_STUN_ATTRIBUTE_H
|
//#define TNET_STUN_ATTRIBUTE_H
|
||||||
|
//
|
||||||
#include "tinynet_config.h"
|
//#include "tinynet_config.h"
|
||||||
|
//
|
||||||
#include "tnet_types.h"
|
//#include "tnet_types.h"
|
||||||
|
//
|
||||||
#include "tsk_object.h"
|
//#include "tsk_object.h"
|
||||||
#include "tsk_buffer.h"
|
//#include "tsk_buffer.h"
|
||||||
#include "tsk_sha1.h"
|
//#include "tsk_sha1.h"
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* @def TNET_STUN_ATTRIBUTE
|
//* @def TNET_STUN_ATTRIBUTE
|
||||||
* Converts (cast) any STUN attribute to @ref tnet_stun_attribute_t pointer.
|
//* Converts (cast) any STUN attribute to @ref tnet_stun_attr_t pointer.
|
||||||
* @param self The attribute to convert (cast).
|
//* @param self The attribute to convert (cast).
|
||||||
* @retval A pointer to @ref tnet_stun_attribute_t object.
|
//* @retval A pointer to @ref tnet_stun_attr_t object.
|
||||||
*/
|
//*/
|
||||||
TNET_BEGIN_DECLS
|
//TNET_BEGIN_DECLS
|
||||||
|
//
|
||||||
#define TNET_STUN_ATTRIBUTE(self) ((tnet_stun_attribute_t*)(self))
|
//#define TNET_STUN_ATTRIBUTE(self) ((tnet_stun_attr_t*)(self))
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* STUN IP family as per RFC 5389 subclause 15.1.
|
// * STUN IP family as per RFC 5389 subclause 15.1.
|
||||||
**/
|
//**/
|
||||||
typedef enum tnet_stun_addr_family_e {
|
//typedef enum tnet_stun_addr_family_e {
|
||||||
stun_ipv4 = 0x01,
|
// stun_ipv4 = 0x01,
|
||||||
stun_ipv6 = 0x02
|
// stun_ipv6 = 0x02
|
||||||
}
|
//}
|
||||||
tnet_stun_addr_family_t;
|
//tnet_stun_addr_family_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* STUN attribute types as per RFC 5389 subclause 18.2.
|
// * STUN attribute types as per RFC 5389 subclause 18.2.
|
||||||
**/
|
//**/
|
||||||
typedef enum tnet_stun_attribute_type_e {
|
//typedef enum tnet_stun_attr_type_e {
|
||||||
/* === RFC 5389 - Comprehension-required range (0x0000-0x7FFF) */
|
// /* === RFC 5389 - Comprehension-required range (0x0000-0x7FFF) */
|
||||||
stun_reserved = 0x0000, /**< (Reserved) */
|
// stun_reserved = 0x0000, /**< (Reserved) */
|
||||||
stun_mapped_address = 0x0001, /**< http://tools.ietf.org/html/rfc5389#page-32 */
|
// stun_mapped_address = 0x0001, /**< http://tools.ietf.org/html/rfc5389#page-32 */
|
||||||
stun_response_address = 0x0002, /**< (Reserved; was RESPONSE-ADDRESS) */
|
// stun_response_address = 0x0002, /**< (Reserved; was RESPONSE-ADDRESS) */
|
||||||
stun_change_address = 0x0003, /**< (Reserved; was CHANGE-ADDRESS) */
|
// stun_change_address = 0x0003, /**< (Reserved; was CHANGE-ADDRESS) */
|
||||||
stun_source_address = 0x0004, /**< (Reserved; was SOURCE-ADDRESS) */
|
// stun_source_address = 0x0004, /**< (Reserved; was SOURCE-ADDRESS) */
|
||||||
stun_changed_address = 0x0005, /**< (Reserved; was CHANGED-ADDRESS) */
|
// stun_changed_address = 0x0005, /**< (Reserved; was CHANGED-ADDRESS) */
|
||||||
stun_username = 0x0006, /**< http://tools.ietf.org/html/rfc5389#page-34 */
|
// stun_username = 0x0006, /**< http://tools.ietf.org/html/rfc5389#page-34 */
|
||||||
stun_password = 0x0007, /**< (Reserved; was PASSWORD) */
|
// stun_password = 0x0007, /**< (Reserved; was PASSWORD) */
|
||||||
stun_message_integrity = 0x0008, /**< http://tools.ietf.org/html/rfc5389#page-34 */
|
// stun_message_integrity = 0x0008, /**< http://tools.ietf.org/html/rfc5389#page-34 */
|
||||||
stun_error_code = 0x0009, /**< http://tools.ietf.org/html/rfc5389#page-36 */
|
// stun_error_code = 0x0009, /**< http://tools.ietf.org/html/rfc5389#page-36 */
|
||||||
stun_unknown_attributes = 0x000A, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
// stun_unknown_attributes = 0x000A, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
||||||
stun_reflected_from = 0x000B, /**< (Reserved; was REFLECTED-FROM) */
|
// stun_reflected_from = 0x000B, /**< (Reserved; was REFLECTED-FROM) */
|
||||||
stun_realm = 0x0014, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
// stun_realm = 0x0014, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
||||||
stun_nonce = 0x0015, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
// stun_nonce = 0x0015, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
||||||
stun_xor_mapped_address = 0x0020, /**< http://tools.ietf.org/html/rfc5389#page-33 */
|
// stun_xor_mapped_address = 0x0020, /**< http://tools.ietf.org/html/rfc5389#page-33 */
|
||||||
|
//
|
||||||
/* === RFC 5389 - Comprehension-optional range (0x8000-0xFFFF) */
|
// /* === RFC 5389 - Comprehension-optional range (0x8000-0xFFFF) */
|
||||||
stun_software = 0x8022, /**< http://tools.ietf.org/html/rfc5389#page-39 */
|
// stun_software = 0x8022, /**< http://tools.ietf.org/html/rfc5389#page-39 */
|
||||||
stun_alternate_server = 0x8023, /**< http://tools.ietf.org/html/rfc5389#page-39 */
|
// stun_alternate_server = 0x8023, /**< http://tools.ietf.org/html/rfc5389#page-39 */
|
||||||
stun_fingerprint = 0x8028, /**< http://tools.ietf.org/html/rfc5389#page-36 */
|
// stun_fingerprint = 0x8028, /**< http://tools.ietf.org/html/rfc5389#page-36 */
|
||||||
|
//
|
||||||
/* === draft-ietf-behave-turn-16 */
|
// /* === draft-ietf-behave-turn-16 */
|
||||||
stun_channel_number = 0x000C, /**< draft-ietf-behave-turn-16 - CHANNEL-NUMBER */
|
// stun_channel_number = 0x000C, /**< draft-ietf-behave-turn-16 - CHANNEL-NUMBER */
|
||||||
stun_lifetime = 0x000D, /**< draft-ietf-behave-turn-16 - LIFETIME */
|
// stun_lifetime = 0x000D, /**< draft-ietf-behave-turn-16 - LIFETIME */
|
||||||
stun_reserved2 = 0x0010, /**< draft-ietf-behave-turn-16 - Reserved (was BANDWIDTH) */
|
// stun_reserved2 = 0x0010, /**< draft-ietf-behave-turn-16 - Reserved (was BANDWIDTH) */
|
||||||
stun_xor_peer_address = 0x0012, /**< draft-ietf-behave-turn-16 - XOR-PEER-ADDRESS */
|
// stun_xor_peer_address = 0x0012, /**< draft-ietf-behave-turn-16 - XOR-PEER-ADDRESS */
|
||||||
stun_data = 0x0013, /**< draft-ietf-behave-turn-16 - DATA */
|
// stun_data = 0x0013, /**< draft-ietf-behave-turn-16 - DATA */
|
||||||
stun_xor_relayed_address = 0x0016, /**< draft-ietf-behave-turn-16 - XOR-RELAYED-ADDRESS */
|
// stun_xor_relayed_address = 0x0016, /**< draft-ietf-behave-turn-16 - XOR-RELAYED-ADDRESS */
|
||||||
stun_even_port = 0x0018, /**< draft-ietf-behave-turn-16 - EVEN-PORT */
|
// stun_even_port = 0x0018, /**< draft-ietf-behave-turn-16 - EVEN-PORT */
|
||||||
stun_requested_transport = 0x0019, /**< draft-ietf-behave-turn-16 - REQUESTED-TRANSPORT */
|
// stun_requested_transport = 0x0019, /**< draft-ietf-behave-turn-16 - REQUESTED-TRANSPORT */
|
||||||
stun_dont_fragment = 0x001A, /**< draft-ietf-behave-turn-16 - DONT-FRAGMENT */
|
// stun_dont_fragment = 0x001A, /**< draft-ietf-behave-turn-16 - DONT-FRAGMENT */
|
||||||
stun_reserved3 = 0x0021, /**< draft-ietf-behave-turn-16 - Reserved (was TIMER-VAL) */
|
// stun_reserved3 = 0x0021, /**< draft-ietf-behave-turn-16 - Reserved (was TIMER-VAL) */
|
||||||
stun_reservation_token = 0x0022, /**< draft-ietf-behave-turn-16 - RESERVATION-TOKEN */
|
// stun_reservation_token = 0x0022, /**< draft-ietf-behave-turn-16 - RESERVATION-TOKEN */
|
||||||
|
//
|
||||||
/* RFC 5245 */
|
// /* RFC 5245 */
|
||||||
stun_ice_priority = 0x0024, /**< 21.2. STUN Attributes */
|
// stun_ice_priority = 0x0024, /**< 21.2. STUN Attributes */
|
||||||
stun_ice_use_candidate = 0x0025, /**< 21.2. STUN Attributes */
|
// stun_ice_use_candidate = 0x0025, /**< 21.2. STUN Attributes */
|
||||||
stun_ice_controlled = 0x8029, /**< 21.2. STUN Attributes */
|
// stun_ice_controlled = 0x8029, /**< 21.2. STUN Attributes */
|
||||||
stun_ice_controlling = 0x802A, /**< 21.2. STUN Attributes */
|
// stun_ice_controlling = 0x802A, /**< 21.2. STUN Attributes */
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_type_t;
|
//tnet_stun_attr_type_t;
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
RFC 5389 - 15. STUN Attributes
|
// RFC 5389 - 15. STUN Attributes
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_stun_attribute_s {
|
//typedef struct tnet_stun_attribute_s {
|
||||||
TSK_DECLARE_OBJECT;
|
// TSK_DECLARE_OBJECT;
|
||||||
/*
|
// /*
|
||||||
0 1 2 3
|
// 0 1 2 3
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Type | Length |
|
// | Type | Length |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Value (variable) ....
|
// | Value (variable) ....
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*/
|
// */
|
||||||
tnet_stun_attribute_type_t type;
|
// tnet_stun_attr_type_t type;
|
||||||
uint16_t length;
|
// uint16_t length;
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_t;
|
//tnet_stun_attr_t;
|
||||||
|
//
|
||||||
typedef tsk_list_t tnet_stun_attributes_L_t;
|
//typedef tsk_list_t tnet_stun_attributes_L_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_def_t;
|
||||||
|
//
|
||||||
#define TNET_STUN_DECLARE_ATTRIBUTE tnet_stun_attribute_t attribute
|
//#define TNET_STUN_DECLARE_ATTRIBUTE tnet_stun_attr_t attribute
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
*RFC 5389 - 15.1. MAPPED-ADDRESS
|
// *RFC 5389 - 15.1. MAPPED-ADDRESS
|
||||||
*/
|
// */
|
||||||
typedef struct tnet_stun_attribute_mapped_addr_s {
|
//typedef struct tnet_stun_attribute_mapped_addr_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
/*
|
// /*
|
||||||
0 1 2 3
|
// 0 1 2 3
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|0 0 0 0 0 0 0 0| Family | Port |
|
// |0 0 0 0 0 0 0 0| Family | Port |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| |
|
// | |
|
||||||
| Address (32 bits or 128 bits) |
|
// | Address (32 bits or 128 bits) |
|
||||||
| |
|
// | |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*/
|
// */
|
||||||
tnet_stun_addr_family_t family;
|
// tnet_stun_addr_family_t family;
|
||||||
uint16_t port;
|
// uint16_t port;
|
||||||
uint8_t address[16];
|
// uint8_t address[16];
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_mapped_addr_t;
|
//tnet_stun_attribute_mapped_addr_t;
|
||||||
|
//
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_mapped_addr_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_mapped_addr_def_t;
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* RFC 5389 - 15.2. XOR-MAPPED-ADDRESS
|
//* RFC 5389 - 15.2. XOR-MAPPED-ADDRESS
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_stun_attribute_xmapped_addr_s {
|
//typedef struct tnet_stun_attribute_xmapped_addr_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
/*
|
// /*
|
||||||
0 1 2 3
|
// 0 1 2 3
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|x x x x x x x x| Family | X-Port |
|
// |x x x x x x x x| Family | X-Port |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| X-Address (Variable)
|
// | X-Address (Variable)
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*/
|
// */
|
||||||
tnet_stun_addr_family_t family;
|
// tnet_stun_addr_family_t family;
|
||||||
uint16_t xport;
|
// uint16_t xport;
|
||||||
uint8_t xaddress[16];
|
// uint8_t xaddress[16];
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_xmapped_addr_t;
|
//tnet_stun_attribute_xmapped_addr_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_xmapped_addr_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_xmapped_addr_def_t;
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* RFC 5389 - 15.3. USERNAME.
|
//* RFC 5389 - 15.3. USERNAME.
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_stun_attribute_username_s {
|
//typedef struct tnet_stun_attribute_username_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
char* value;
|
// char* value;
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_username_t;
|
//tnet_stun_attribute_username_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_username_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_username_def_t;
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* RFC 5389 - 15.4. MESSAGE-INTEGRITY.
|
//* RFC 5389 - 15.4. MESSAGE-INTEGRITY.
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_stun_attribute_integrity_s {
|
//typedef struct tnet_stun_attribute_integrity_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
tsk_sha1digest_t sha1digest;
|
// tsk_sha1digest_t sha1digest;
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_integrity_t;
|
//tnet_stun_attribute_integrity_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_integrity_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_integrity_def_t;
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* RFC 5389 - 15.5. FINGERPRINT.
|
//* RFC 5389 - 15.5. FINGERPRINT.
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_stun_attribute_fingerprint_s {
|
//typedef struct tnet_stun_attribute_fingerprint_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
uint32_t value;
|
// uint32_t value;
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_fingerprint_t;
|
//tnet_stun_attribute_fingerprint_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_fingerprint_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_fingerprint_def_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
*RFC 5389 - 15.6. ERROR-CODE
|
// *RFC 5389 - 15.6. ERROR-CODE
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_stun_attribute_errorcode_s {
|
//typedef struct tnet_stun_attribute_errorcode_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
/*
|
// /*
|
||||||
0 1 2 3
|
// 0 1 2 3
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Reserved, should be 0 |Class| Number |
|
// | Reserved, should be 0 |Class| Number |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Reason Phrase (variable) ..
|
// | Reason Phrase (variable) ..
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*/
|
// */
|
||||||
uint8_t _class;
|
// uint8_t _class;
|
||||||
uint8_t number;
|
// uint8_t number;
|
||||||
char* reason_phrase;
|
// char* reason_phrase;
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_errorcode_t;
|
//tnet_stun_attribute_errorcode_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_errorcode_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_errorcode_def_t;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* RFC 5389 - 15.7. REALM. */
|
//* RFC 5389 - 15.7. REALM. */
|
||||||
typedef struct tnet_stun_attribute_realm_s {
|
//typedef struct tnet_stun_attribute_realm_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
char* value;
|
// char* value;
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_realm_t;
|
//tnet_stun_attribute_realm_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_realm_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_realm_def_t;
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* RFC 5389 - 15.8. NONCE. */
|
//* RFC 5389 - 15.8. NONCE. */
|
||||||
typedef struct tnet_stun_attribute_nonce_s {
|
//typedef struct tnet_stun_attribute_nonce_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
char* value;
|
// char* value;
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_nonce_t;
|
//tnet_stun_attribute_nonce_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_nonce_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_nonce_def_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* RFC 5389 - 15.9. UNKNOWN-ATTRIBUTES. */
|
//* RFC 5389 - 15.9. UNKNOWN-ATTRIBUTES. */
|
||||||
typedef struct tnet_stun_attribute_unknowns_s {
|
//typedef struct tnet_stun_attribute_unknowns_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
tsk_buffer_t *value;
|
// tsk_buffer_t *value;
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_unknowns_t;
|
//tnet_stun_attribute_unknowns_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_unknowns_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_unknowns_def_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* RFC 5389 - 15.10. SOFTWARE. */
|
//* RFC 5389 - 15.10. SOFTWARE. */
|
||||||
typedef struct tnet_stun_attribute_software_s {
|
//typedef struct tnet_stun_attribute_software_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
char *value;
|
// char *value;
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_software_t;
|
//tnet_stun_attribute_software_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_software_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_software_def_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* RFC 5389 - 15.11. ALTERNATE-SERVER. */
|
//* RFC 5389 - 15.11. ALTERNATE-SERVER. */
|
||||||
typedef struct tnet_stun_attribute_altserver_s {
|
//typedef struct tnet_stun_attribute_altserver_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
tnet_stun_addr_family_t family;
|
// tnet_stun_addr_family_t family;
|
||||||
uint16_t port;
|
// uint16_t port;
|
||||||
uint8_t server[128];
|
// uint8_t server[128];
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_altserver_t;
|
//tnet_stun_attribute_altserver_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_altserver_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_altserver_def_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* RFC 5245 - 19.1. New Attributes */
|
//* RFC 5245 - 19.1. New Attributes */
|
||||||
typedef struct tnet_stun_attribute_ice_priority_s {
|
//typedef struct tnet_stun_attribute_ice_priority_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
uint32_t value;
|
// uint32_t value;
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_ice_priority_t;
|
//tnet_stun_attribute_ice_priority_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_priority_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_priority_def_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* RFC 5245 - 19.1. New Attributes */
|
//* RFC 5245 - 19.1. New Attributes */
|
||||||
typedef struct tnet_stun_attribute_ice_use_candidate_s {
|
//typedef struct tnet_stun_attribute_ice_use_candidate_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_ice_use_candidate_t;
|
//tnet_stun_attribute_ice_use_candidate_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_use_candidate_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_use_candidate_def_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* RFC 5245 - 19.1. New Attributes */
|
//* RFC 5245 - 19.1. New Attributes */
|
||||||
typedef struct tnet_stun_attribute_ice_controlled_s {
|
//typedef struct tnet_stun_attribute_ice_controlled_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
uint64_t value;
|
// uint64_t value;
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_ice_controlled_t;
|
//tnet_stun_attribute_ice_controlled_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_controlled_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_controlled_def_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* RFC 5245 - 19.1. New Attributes */
|
//* RFC 5245 - 19.1. New Attributes */
|
||||||
typedef struct tnet_stun_attribute_ice_controlling_s {
|
//typedef struct tnet_stun_attribute_ice_controlling_s {
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
uint64_t value;
|
// uint64_t value;
|
||||||
}
|
//}
|
||||||
tnet_stun_attribute_ice_controlling_t;
|
//tnet_stun_attribute_ice_controlling_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_controlling_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_controlling_def_t;
|
||||||
|
//
|
||||||
tnet_stun_attribute_t* tnet_stun_attribute_deserialize(const void* data, tsk_size_t size);
|
//tnet_stun_attr_t* tnet_stun_attribute_deserialize(const void* data, tsk_size_t size);
|
||||||
int tnet_stun_attribute_serialize(const tnet_stun_attribute_t* attribute, tsk_buffer_t *output);
|
//int tnet_stun_attribute_serialize(const tnet_stun_attr_t* attribute, tsk_buffer_t *output);
|
||||||
void tnet_stun_attribute_pad(const tnet_stun_attribute_t* attribute, tsk_buffer_t *output);
|
//void tnet_stun_attribute_pad(const tnet_stun_attr_t* attribute, tsk_buffer_t *output);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
tnet_stun_attribute_t* tnet_stun_attribute_create();
|
//tnet_stun_attr_t* tnet_stun_attribute_create();
|
||||||
TINYNET_API tnet_stun_attribute_mapped_addr_t* tnet_stun_attribute_mapped_address_create(const void* payload, tsk_size_t payload_size);
|
//TINYNET_API tnet_stun_attribute_mapped_addr_t* tnet_stun_attribute_mapped_address_create(const void* payload, tsk_size_t payload_size);
|
||||||
TINYNET_API tnet_stun_attribute_xmapped_addr_t* tnet_stun_attribute_xmapped_address_create(const void* payload, tsk_size_t payload_size);
|
//TINYNET_API tnet_stun_attribute_xmapped_addr_t* tnet_stun_attribute_xmapped_address_create(const void* payload, tsk_size_t payload_size);
|
||||||
TINYNET_API tnet_stun_attribute_username_t* tnet_stun_attribute_username_create(const void* payload, tsk_size_t payload_size);
|
//TINYNET_API tnet_stun_attribute_username_t* tnet_stun_attribute_username_create(const void* payload, tsk_size_t payload_size);
|
||||||
TINYNET_API tnet_stun_attribute_integrity_t* tnet_stun_attribute_integrity_create(const void* payload, tsk_size_t payload_size);
|
//TINYNET_API tnet_stun_attribute_integrity_t* tnet_stun_attribute_integrity_create(const void* payload, tsk_size_t payload_size);
|
||||||
TINYNET_API tnet_stun_attribute_fingerprint_t* tnet_stun_attribute_fingerprint_create(uint32_t fingerprint);
|
//TINYNET_API tnet_stun_attribute_fingerprint_t* tnet_stun_attribute_fingerprint_create(uint32_t fingerprint);
|
||||||
TINYNET_API tnet_stun_attribute_errorcode_t* tnet_stun_attribute_errorcode_create(const void* payload, tsk_size_t payload_size);
|
//TINYNET_API tnet_stun_attribute_errorcode_t* tnet_stun_attribute_errorcode_create(const void* payload, tsk_size_t payload_size);
|
||||||
TINYNET_API tnet_stun_attribute_realm_t* tnet_stun_attribute_realm_create(const void* payload, tsk_size_t payload_size);
|
//TINYNET_API tnet_stun_attribute_realm_t* tnet_stun_attribute_realm_create(const void* payload, tsk_size_t payload_size);
|
||||||
TINYNET_API tnet_stun_attribute_nonce_t* tnet_stun_attribute_nonce_create(const void* payload, tsk_size_t payload_size);
|
//TINYNET_API tnet_stun_attribute_nonce_t* tnet_stun_attribute_nonce_create(const void* payload, tsk_size_t payload_size);
|
||||||
TINYNET_API tnet_stun_attribute_unknowns_t* tnet_stun_attribute_unknowns_create(const void* payload, tsk_size_t payload_size);
|
//TINYNET_API tnet_stun_attribute_unknowns_t* tnet_stun_attribute_unknowns_create(const void* payload, tsk_size_t payload_size);
|
||||||
TINYNET_API tnet_stun_attribute_software_t* tnet_stun_attribute_software_create(const void* payload, tsk_size_t payload_size);
|
//TINYNET_API tnet_stun_attribute_software_t* tnet_stun_attribute_software_create(const void* payload, tsk_size_t payload_size);
|
||||||
TINYNET_API tnet_stun_attribute_altserver_t* tnet_stun_attribute_altserver_create(const void* payload, tsk_size_t payload_size);
|
//TINYNET_API tnet_stun_attribute_altserver_t* tnet_stun_attribute_altserver_create(const void* payload, tsk_size_t payload_size);
|
||||||
TINYNET_API tnet_stun_attribute_ice_priority_t* tnet_stun_attribute_ice_priority_create(uint32_t value);
|
//TINYNET_API tnet_stun_attribute_ice_priority_t* tnet_stun_attribute_ice_priority_create(uint32_t value);
|
||||||
TINYNET_API tnet_stun_attribute_ice_use_candidate_t* tnet_stun_attribute_ice_use_candidate_create();
|
//TINYNET_API tnet_stun_attribute_ice_use_candidate_t* tnet_stun_attribute_ice_use_candidate_create();
|
||||||
TINYNET_API tnet_stun_attribute_ice_controlled_t* tnet_stun_attribute_ice_controlled_create(uint64_t value);
|
//TINYNET_API tnet_stun_attribute_ice_controlled_t* tnet_stun_attribute_ice_controlled_create(uint64_t value);
|
||||||
TINYNET_API tnet_stun_attribute_ice_controlling_t* tnet_stun_attribute_ice_controlling_create(uint64_t value);
|
//TINYNET_API tnet_stun_attribute_ice_controlling_t* tnet_stun_attribute_ice_controlling_create(uint64_t value);
|
||||||
|
//
|
||||||
|
//
|
||||||
TNET_END_DECLS
|
//TNET_END_DECLS
|
||||||
|
//
|
||||||
#endif /* TNET_STUN_ATTRIBUTE_H */
|
//#endif /* TNET_STUN_ATTRIBUTE_H */
|
||||||
|
//
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
/* Copyright (C) 2014 Mamadou DIOP.
|
||||||
|
*
|
||||||
|
* This file is part of Open Source Doubango Framework.
|
||||||
|
*
|
||||||
|
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* DOUBANGO is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with DOUBANGO.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "stun/tnet_stun_binding.h"
|
||||||
|
#include "stun/tnet_stun_pkt.h"
|
||||||
|
#include "stun/tnet_stun_attr.h"
|
||||||
|
#include "tnet_utils.h"
|
||||||
|
|
||||||
|
#include "tsk_string.h"
|
||||||
|
#include "tsk_memory.h"
|
||||||
|
#include "tsk_debug.h"
|
||||||
|
|
||||||
|
int tnet_stun_binding_create(tnet_fd_t fd, enum tnet_socket_type_e socket_type, const char* pc_server_address, tnet_port_t server_port, const char* pc_username, const char* pc_password, tnet_stun_binding_t** pp_bind)
|
||||||
|
{
|
||||||
|
extern const tsk_object_def_t *tnet_stun_binding_def_t;
|
||||||
|
static long __unique_id = 0;
|
||||||
|
|
||||||
|
if (!pp_bind) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!(*pp_bind = tsk_object_new(tnet_stun_binding_def_t))) {
|
||||||
|
TSK_DEBUG_ERROR("Failed to create STUN binding object");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
tsk_atomic_inc(&__unique_id);
|
||||||
|
(*pp_bind)->id = __unique_id;
|
||||||
|
(*pp_bind)->localFD = fd;
|
||||||
|
(*pp_bind)->socket_type = socket_type;
|
||||||
|
(*pp_bind)->p_username = tsk_strdup(pc_username);
|
||||||
|
(*pp_bind)->p_password = tsk_strdup(pc_password);
|
||||||
|
|
||||||
|
if (pc_server_address && server_port) {
|
||||||
|
int ret;
|
||||||
|
if ((ret = tnet_sockaddr_init(pc_server_address, server_port, socket_type, &(*pp_bind)->addr_server))) {
|
||||||
|
TSK_OBJECT_SAFE_FREE((*pp_bind));
|
||||||
|
TSK_DEBUG_ERROR("Failed to init STUN server address");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tnet_stun_binding_create_req(const struct tnet_stun_binding_s* pc_self, struct tnet_stun_pkt_s **pp_req)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
if (!pc_self || !pp_req) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_binding_request, pp_req))) {
|
||||||
|
TSK_DEBUG_ERROR("Failed to create STUN Bind request");
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
// add attributes
|
||||||
|
(*pp_req)->opt.dontfrag = 0;
|
||||||
|
ret = tnet_stun_pkt_attrs_add(*pp_req,
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(kStunSoftware),
|
||||||
|
TNET_STUN_PKT_ATTR_ADD_NULL());
|
||||||
|
if (ret) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if (pc_self->p_username && pc_self->p_realm && pc_self->p_nonce) {
|
||||||
|
if ((ret = tnet_stun_pkt_auth_prepare(*pp_req, pc_self->p_username, pc_self->p_password, pc_self->p_realm, pc_self->p_nonce))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bail:
|
||||||
|
if (ret) {
|
||||||
|
TSK_OBJECT_SAFE_FREE(*pp_req);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static tsk_object_t* tnet_stun_binding_ctor(tsk_object_t * self, va_list * app)
|
||||||
|
{
|
||||||
|
tnet_stun_binding_t *p_bind = (tnet_stun_binding_t *)self;
|
||||||
|
if (p_bind) {
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
static tsk_object_t* tnet_stun_binding_dtor(tsk_object_t * self)
|
||||||
|
{
|
||||||
|
tnet_stun_binding_t *p_bind = (tnet_stun_binding_t *)self;
|
||||||
|
if (p_bind) {
|
||||||
|
TSK_DEBUG_INFO("*** STUN BINDING destroyed ***");
|
||||||
|
TSK_FREE(p_bind->p_username);
|
||||||
|
TSK_FREE(p_bind->p_password);
|
||||||
|
TSK_FREE(p_bind->p_realm);
|
||||||
|
TSK_FREE(p_bind->p_nonce);
|
||||||
|
|
||||||
|
TSK_OBJECT_SAFE_FREE(p_bind->p_maddr);
|
||||||
|
TSK_OBJECT_SAFE_FREE(p_bind->p_xmaddr);
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
static int tnet_stun_binding_cmp(const tsk_object_t *_bind1, const tsk_object_t *_bind2)
|
||||||
|
{
|
||||||
|
const tnet_stun_binding_t *pc_bind1 = (const tnet_stun_binding_t *)_bind1;
|
||||||
|
const tnet_stun_binding_t *pc_bind2 = (const tnet_stun_binding_t *)_bind2;
|
||||||
|
|
||||||
|
return (pc_bind1 && pc_bind2) ? (int)(pc_bind1->id - pc_bind2->id) : (int)(pc_bind1 - pc_bind2);
|
||||||
|
}
|
||||||
|
static const tsk_object_def_t tnet_stun_binding_def_s = {
|
||||||
|
sizeof(tnet_stun_binding_t),
|
||||||
|
tnet_stun_binding_ctor,
|
||||||
|
tnet_stun_binding_dtor,
|
||||||
|
tnet_stun_binding_cmp,
|
||||||
|
};
|
||||||
|
const tsk_object_def_t *tnet_stun_binding_def_t = &tnet_stun_binding_def_s;
|
|
@ -0,0 +1,67 @@
|
||||||
|
/* Copyright (C) 2014 Mamadou DIOP.
|
||||||
|
*
|
||||||
|
* This file is part of Open Source Doubango Framework.
|
||||||
|
*
|
||||||
|
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* DOUBANGO is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with DOUBANGO.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef TNET_STUN_BINDING_H
|
||||||
|
#define TNET_STUN_BINDING_H
|
||||||
|
|
||||||
|
#include "tinynet_config.h"
|
||||||
|
#include "tnet_types.h"
|
||||||
|
#include "stun/tnet_stun_types.h"
|
||||||
|
#include "stun/tnet_stun_attr.h"
|
||||||
|
|
||||||
|
#include "tsk_object.h"
|
||||||
|
#include "tsk_list.h"
|
||||||
|
|
||||||
|
TNET_BEGIN_DECLS
|
||||||
|
|
||||||
|
enum tnet_socket_type_e;
|
||||||
|
|
||||||
|
typedef struct tnet_stun_binding_s {
|
||||||
|
TSK_DECLARE_OBJECT;
|
||||||
|
|
||||||
|
//! A unique id to identify this binding.
|
||||||
|
tnet_stun_binding_id_t id;
|
||||||
|
|
||||||
|
//! The username to authenticate to the STUN server.
|
||||||
|
char* p_username;
|
||||||
|
//! The password to authenticate to the STUN server.
|
||||||
|
char* p_password;
|
||||||
|
//! The realm.
|
||||||
|
char* p_realm;
|
||||||
|
//! The nonce.
|
||||||
|
char* p_nonce;
|
||||||
|
//! Local file descriptor for which to get server reflexive address.
|
||||||
|
tnet_fd_t localFD;
|
||||||
|
//! The type of the bound socket.
|
||||||
|
enum tnet_socket_type_e socket_type;
|
||||||
|
//! The address of the STUN server.
|
||||||
|
struct sockaddr_storage addr_server;
|
||||||
|
//! Server reflexive address of the local socket(STUN1 as per RFC 3489).
|
||||||
|
struct tnet_stun_attr_address_s *p_maddr;
|
||||||
|
//! XORed server reflexive address (STUN2 as per RFC 5389).
|
||||||
|
struct tnet_stun_attr_address_s *p_xmaddr;
|
||||||
|
}
|
||||||
|
tnet_stun_binding_t;
|
||||||
|
typedef tsk_list_t tnet_stun_bindings_L_t;
|
||||||
|
|
||||||
|
int tnet_stun_binding_create(tnet_fd_t fd, enum tnet_socket_type_e socket_type, const char* pc_server_address, tnet_port_t server_port, const char* pc_username, const char* pc_password, tnet_stun_binding_t** pp_bind);
|
||||||
|
int tnet_stun_binding_create_req(const struct tnet_stun_binding_s* pc_self, struct tnet_stun_pkt_s **pp_req);
|
||||||
|
|
||||||
|
TNET_END_DECLS
|
||||||
|
|
||||||
|
#endif /* TNET_STUN_BINDING_H */
|
|
@ -1,494 +1,495 @@
|
||||||
/*
|
///*
|
||||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
//* Copyright (C) 2010-2011 Mamadou Diop.
|
||||||
*
|
//*
|
||||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
//*
|
||||||
* This file is part of Open Source Doubango Framework.
|
//* This file is part of Open Source Doubango Framework.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
//* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
//* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
//* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
//* (at your option) any later version.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is distributed in the hope that it will be useful,
|
//* DOUBANGO is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
//* GNU General Public License for more details.
|
||||||
*
|
//*
|
||||||
* You should have received a copy of the GNU General Public License
|
//* You should have received a copy of the GNU General Public License
|
||||||
* along with DOUBANGO.
|
//* along with DOUBANGO.
|
||||||
*
|
//*
|
||||||
*/
|
//*/
|
||||||
|
//
|
||||||
/**@file tnet_stun_message.c
|
///**@file tnet_stun_message.c
|
||||||
* @brief STUN2 (RFC 5389) message parser.
|
// * @brief STUN2 (RFC 5389) message parser.
|
||||||
*
|
// *
|
||||||
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
// * @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
// *
|
||||||
|
//
|
||||||
*/
|
// */
|
||||||
#include "tnet_stun_message.h"
|
//#include "tnet_stun_message.h"
|
||||||
|
//
|
||||||
#include "tnet_stun.h"
|
//#include "tnet_stun.h"
|
||||||
|
//
|
||||||
#include "../tnet_types.h"
|
//#include "../tnet_types.h"
|
||||||
#include "../tnet_endianness.h"
|
//#include "../tnet_endianness.h"
|
||||||
#include "../turn/tnet_turn_attribute.h"
|
//#include "../turn/tnet_turn_attribute.h"
|
||||||
|
//#include "stun/tnet_stun_types.h"
|
||||||
#include "tsk_memory.h"
|
//
|
||||||
#include "tsk_hmac.h"
|
//#include "tsk_memory.h"
|
||||||
#include "tsk_string.h"
|
//#include "tsk_hmac.h"
|
||||||
#include "tsk_ppfcs32.h"
|
//#include "tsk_string.h"
|
||||||
|
//#include "tsk_ppfcs32.h"
|
||||||
#include <string.h>
|
//
|
||||||
|
//#include <string.h>
|
||||||
static int __pred_find_attribute_by_type(const tsk_list_item_t *item, const void *att_type)
|
//
|
||||||
{
|
//static int __pred_find_attribute_by_type(const tsk_list_item_t *item, const void *att_type)
|
||||||
if(item && item->data) {
|
//{
|
||||||
tnet_stun_attribute_t *att = item->data;
|
// if(item && item->data) {
|
||||||
tnet_stun_attribute_type_t type = *((tnet_stun_attribute_type_t*)att_type);
|
// tnet_stun_attr_t *att = item->data;
|
||||||
return (att->type - type);
|
// tnet_stun_attr_type_t type = *((tnet_stun_attr_type_t*)att_type);
|
||||||
}
|
// return (att->type - type);
|
||||||
return -1;
|
// }
|
||||||
}
|
// return -1;
|
||||||
|
//}
|
||||||
/**@ingroup tnet_stun_group
|
//
|
||||||
* Creates new STUN message.
|
///**@ingroup tnet_stun_group
|
||||||
* @retval @ref tnet_stun_message_t object.
|
//* Creates new STUN message.
|
||||||
* @sa tnet_stun_message_create_null.
|
//* @retval @ref tnet_stun_pkt_t object.
|
||||||
*/
|
//* @sa tnet_stun_message_create_null.
|
||||||
|
//*/
|
||||||
tnet_stun_message_t* tnet_stun_message_create(const char* username, const char* password)
|
//
|
||||||
{
|
//tnet_stun_pkt_t* tnet_stun_message_create(const char* username, const char* password)
|
||||||
return tsk_object_new(tnet_stun_message_def_t, username, password);
|
//{
|
||||||
}
|
// return tsk_object_new(tnet_stun_message_def_t, username, password);
|
||||||
|
//}
|
||||||
/**@ingroup tnet_stun_group
|
//
|
||||||
* Creates new STUN message.
|
///**@ingroup tnet_stun_group
|
||||||
* @retval @ref tnet_stun_message_t object.
|
//* Creates new STUN message.
|
||||||
* @sa tnet_stun_message_create.
|
//* @retval @ref tnet_stun_pkt_t object.
|
||||||
*/
|
//* @sa tnet_stun_message_create.
|
||||||
tnet_stun_message_t* tnet_stun_message_create_null()
|
//*/
|
||||||
{
|
//tnet_stun_pkt_t* tnet_stun_message_create_null()
|
||||||
return tnet_stun_message_create(tsk_null, tsk_null);
|
//{
|
||||||
}
|
// return tnet_stun_message_create(tsk_null, tsk_null);
|
||||||
|
//}
|
||||||
#define SERIALIZE_N_ADD_ATTRIBUTE(att_name, payload, payload_size) \
|
//
|
||||||
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_##att_name##_create(payload, payload_size); \
|
//#define SERIALIZE_N_ADD_ATTRIBUTE(att_name, payload, payload_size) \
|
||||||
tnet_stun_attribute_serialize(attribute, output); \
|
// attribute = (tnet_stun_attr_t *)tnet_stun_attribute_##att_name##_create(payload, payload_size); \
|
||||||
tnet_stun_attribute_pad(attribute, output); \
|
// tnet_stun_attribute_serialize(attribute, output); \
|
||||||
TSK_OBJECT_SAFE_FREE(attribute);
|
// tnet_stun_attribute_pad(attribute, output); \
|
||||||
|
// TSK_OBJECT_SAFE_FREE(attribute);
|
||||||
/**@ingroup tnet_stun_group
|
//
|
||||||
* Serializes a STUN message as binary data.
|
///**@ingroup tnet_stun_group
|
||||||
* @param [in,out] self The STUN message to serialize.
|
// * Serializes a STUN message as binary data.
|
||||||
* @retval A buffer holding the binary data (result) if serialization succeed and zero otherwise.
|
// * @param [in,out] self The STUN message to serialize.
|
||||||
**/
|
// * @retval A buffer holding the binary data (result) if serialization succeed and zero otherwise.
|
||||||
tsk_buffer_t* tnet_stun_message_serialize(const tnet_stun_message_t *self)
|
//**/
|
||||||
{
|
//tsk_buffer_t* tnet_stun_pkt_serialize(const tnet_stun_pkt_t *self)
|
||||||
tsk_buffer_t *output = 0;
|
//{
|
||||||
tnet_stun_attribute_t *attribute;
|
// tsk_buffer_t *output = 0;
|
||||||
unsigned compute_integrity = self->integrity;
|
// tnet_stun_attr_t *attribute;
|
||||||
|
// unsigned compute_integrity = self->integrity;
|
||||||
if(!self) {
|
//
|
||||||
goto bail;
|
// if(!self) {
|
||||||
}
|
// goto bail;
|
||||||
|
// }
|
||||||
output = tsk_buffer_create_null();
|
//
|
||||||
|
// output = tsk_buffer_create_null();
|
||||||
/* RFC 5389 - 6. STUN Message Structure
|
//
|
||||||
0 1 2 3
|
// /* RFC 5389 - 6. STUN Message Structure
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
// 0 1 2 3
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|0 0| STUN Message Type | Message Length |
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// |0 0| STUN Message Type | Message Length |
|
||||||
| Magic Cookie |
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// | Magic Cookie |
|
||||||
| |
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Transaction ID (96 bits) |
|
// | |
|
||||||
| |
|
// | Transaction ID (96 bits) |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// | |
|
||||||
*/
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// */
|
||||||
/* STUN Message Type
|
//
|
||||||
*/
|
// /* STUN Message Type
|
||||||
{
|
// */
|
||||||
uint16_t type = tnet_htons(self->type);
|
// {
|
||||||
tsk_buffer_append(output, &(type), 2);
|
// uint16_t type = tnet_htons(self->type);
|
||||||
}
|
// tsk_buffer_append(output, &(type), 2);
|
||||||
|
// }
|
||||||
/* Message Length ==> Will be updated after attributes have been added. */
|
//
|
||||||
{
|
// /* Message Length ==> Will be updated after attributes have been added. */
|
||||||
static const uint16_t length = 0;
|
// {
|
||||||
tsk_buffer_append(output, &(length), 2);
|
// static const uint16_t length = 0;
|
||||||
}
|
// tsk_buffer_append(output, &(length), 2);
|
||||||
|
// }
|
||||||
/* Magic Cookie
|
//
|
||||||
*/
|
// /* Magic Cookie
|
||||||
{
|
// */
|
||||||
uint32_t cookie = tnet_htonl(self->cookie);
|
// {
|
||||||
tsk_buffer_append(output, &(cookie), 4);
|
// uint32_t cookie = tnet_htonl(self->cookie);
|
||||||
}
|
// tsk_buffer_append(output, &(cookie), 4);
|
||||||
|
// }
|
||||||
|
//
|
||||||
/* Transaction ID (96 bits==>16bytes)
|
//
|
||||||
*/
|
// /* Transaction ID (96 bits==>16bytes)
|
||||||
tsk_buffer_append(output, self->transaction_id, TNET_STUN_TRANSACID_SIZE);
|
// */
|
||||||
|
// tsk_buffer_append(output, self->transac_id, TNET_STUN_TRANSACID_SIZE);
|
||||||
/* DONT-FRAGMENT
|
//
|
||||||
*/
|
// /* DONT-FRAGMENT
|
||||||
if(self->dontfrag) {
|
// */
|
||||||
attribute = (tnet_stun_attribute_t *)tnet_turn_attribute_dontfrag_create();
|
// if(self->dontfrag) {
|
||||||
tnet_stun_attribute_serialize(attribute, output);
|
// /*attribute = (tnet_stun_attr_t *)tnet_turn_attribute_dontfrag_create();
|
||||||
TSK_OBJECT_SAFE_FREE(attribute);
|
// tnet_stun_attribute_serialize(attribute, output);
|
||||||
}
|
// TSK_OBJECT_SAFE_FREE(attribute);*/
|
||||||
|
// }
|
||||||
/* AUTHENTICATION */
|
//
|
||||||
if(self->realm && self->nonce) { // long term
|
// /* AUTHENTICATION */
|
||||||
SERIALIZE_N_ADD_ATTRIBUTE(realm, self->realm, tsk_strlen(self->realm));
|
// if(self->realm && self->nonce) { // long term
|
||||||
SERIALIZE_N_ADD_ATTRIBUTE(nonce, self->nonce, tsk_strlen(self->nonce));
|
// SERIALIZE_N_ADD_ATTRIBUTE(realm, self->realm, tsk_strlen(self->realm));
|
||||||
|
// SERIALIZE_N_ADD_ATTRIBUTE(nonce, self->nonce, tsk_strlen(self->nonce));
|
||||||
compute_integrity = !self->nointegrity;
|
//
|
||||||
}
|
// compute_integrity = !self->nointegrity;
|
||||||
else if(self->password) { // short term
|
// }
|
||||||
compute_integrity = !self->nointegrity;
|
// else if(self->password) { // short term
|
||||||
}
|
// compute_integrity = !self->nointegrity;
|
||||||
|
// }
|
||||||
if(compute_integrity && self->username) {
|
//
|
||||||
SERIALIZE_N_ADD_ATTRIBUTE(username, self->username, tsk_strlen(self->username));
|
// if(compute_integrity && self->username) {
|
||||||
}
|
// SERIALIZE_N_ADD_ATTRIBUTE(username, self->username, tsk_strlen(self->username));
|
||||||
|
// }
|
||||||
/*=== Attributes === */
|
//
|
||||||
{
|
// /*=== Attributes === */
|
||||||
tsk_list_item_t *item;
|
// {
|
||||||
tsk_list_foreach(item, self->attributes) {
|
// tsk_list_item_t *item;
|
||||||
attribute = item->data;
|
// tsk_list_foreach(item, self->attributes) {
|
||||||
tnet_stun_attribute_serialize(attribute, output);
|
// attribute = item->data;
|
||||||
tnet_stun_attribute_pad(attribute, output);
|
// tnet_stun_attribute_serialize(attribute, output);
|
||||||
}
|
// tnet_stun_attribute_pad(attribute, output);
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
/* Message Length: The message length MUST contain the size, in bytes, of the message
|
//
|
||||||
not including the 20-byte STUN header.
|
// /* Message Length: The message length MUST contain the size, in bytes, of the message
|
||||||
*/
|
// not including the 20-byte STUN header.
|
||||||
{
|
// */
|
||||||
// compute length for 'MESSAGE-INTEGRITY'
|
// {
|
||||||
// will be computed again to store the correct value
|
// // compute length for 'MESSAGE-INTEGRITY'
|
||||||
uint16_t length = (output->size) - TNET_STUN_HEADER_SIZE;
|
// // will be computed again to store the correct value
|
||||||
#if 0
|
// uint16_t length = (output->size) - kStunAttrHdrSizeInOctets;
|
||||||
if(self->fingerprint) {
|
//#if 0
|
||||||
length += (2/* Type */ + 2 /* Length */+ 4 /* FINGERPRINT VALUE*/);
|
// if(self->fingerprint) {
|
||||||
}
|
// length += (2/* Type */ + 2 /* Length */+ 4 /* FINGERPRINT VALUE*/);
|
||||||
#endif
|
// }
|
||||||
|
//#endif
|
||||||
if(compute_integrity) {
|
//
|
||||||
length += (2/* Type */ + 2 /* Length */+ TSK_SHA1_DIGEST_SIZE /* INTEGRITY VALUE*/);
|
// if(compute_integrity) {
|
||||||
}
|
// length += (2/* Type */ + 2 /* Length */+ TSK_SHA1_DIGEST_SIZE /* INTEGRITY VALUE*/);
|
||||||
|
// }
|
||||||
*(((uint16_t*)output->data)+1) = tnet_htons(length);
|
//
|
||||||
}
|
// *(((uint16_t*)output->data)+1) = tnet_htons(length);
|
||||||
|
// }
|
||||||
/* MESSAGE-INTEGRITY */
|
//
|
||||||
if(compute_integrity) {
|
// /* MESSAGE-INTEGRITY */
|
||||||
/* RFC 5389 - 15.4. MESSAGE-INTEGRITY
|
// if(compute_integrity) {
|
||||||
The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [RFC2104] of the STUN message.
|
// /* RFC 5389 - 15.4. MESSAGE-INTEGRITY
|
||||||
|
// The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [RFC2104] of the STUN message.
|
||||||
For long-term credentials ==> key = MD5(username ":" realm ":" SASLprep(password))
|
//
|
||||||
For short-term credentials ==> key = SASLprep(password)
|
// For long-term credentials ==> key = MD5(username ":" realm ":" SASLprep(password))
|
||||||
*/
|
// For short-term credentials ==> key = SASLprep(password)
|
||||||
|
// */
|
||||||
tsk_sha1digest_t hmac;
|
//
|
||||||
|
// tsk_sha1digest_t hmac;
|
||||||
if(self->username && self->realm && self->password) { // long term
|
//
|
||||||
char* keystr = tsk_null;
|
// if(self->username && self->realm && self->password) { // long term
|
||||||
tsk_md5digest_t md5;
|
// char* keystr = tsk_null;
|
||||||
tsk_sprintf(&keystr, "%s:%s:%s", self->username, self->realm, self->password);
|
// tsk_md5digest_t md5;
|
||||||
TSK_MD5_DIGEST_CALC(keystr, tsk_strlen(keystr), md5);
|
// tsk_sprintf(&keystr, "%s:%s:%s", self->username, self->realm, self->password);
|
||||||
hmac_sha1digest_compute(output->data, output->size, (const char*)md5, TSK_MD5_DIGEST_SIZE, hmac);
|
// TSK_MD5_DIGEST_CALC(keystr, tsk_strlen(keystr), md5);
|
||||||
|
// hmac_sha1digest_compute(output->data, output->size, (const char*)md5, TSK_MD5_DIGEST_SIZE, hmac);
|
||||||
TSK_FREE(keystr);
|
//
|
||||||
}
|
// TSK_FREE(keystr);
|
||||||
else { // short term
|
// }
|
||||||
hmac_sha1digest_compute(output->data, output->size, self->password, tsk_strlen(self->password), hmac);
|
// else { // short term
|
||||||
}
|
// hmac_sha1digest_compute(output->data, output->size, self->password, tsk_strlen(self->password), hmac);
|
||||||
|
// }
|
||||||
SERIALIZE_N_ADD_ATTRIBUTE(integrity, hmac, TSK_SHA1_DIGEST_SIZE);
|
//
|
||||||
}
|
// SERIALIZE_N_ADD_ATTRIBUTE(integrity, hmac, TSK_SHA1_DIGEST_SIZE);
|
||||||
|
// }
|
||||||
// LENGTH
|
//
|
||||||
*(((uint16_t*)output->data) + 1) = tnet_htons((output->size - TNET_STUN_HEADER_SIZE + (self->fingerprint ? 8 : 0)));
|
// // LENGTH
|
||||||
|
// *(((uint16_t*)output->data) + 1) = tnet_htons((output->size - kStunAttrHdrSizeInOctets + (self->fingerprint ? 8 : 0)));
|
||||||
/* FINGERPRINT */
|
//
|
||||||
if(self->fingerprint) { //JINGLE_ICE
|
// /* FINGERPRINT */
|
||||||
/* RFC 5389 - 15.5. FINGERPRINT
|
// if(self->fingerprint) { //JINGLE_ICE
|
||||||
The FINGERPRINT attribute MAY be present in all STUN messages. The
|
// /* RFC 5389 - 15.5. FINGERPRINT
|
||||||
value of the attribute is computed as the CRC-32 of the STUN message
|
// The FINGERPRINT attribute MAY be present in all STUN messages. The
|
||||||
up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with
|
// value of the attribute is computed as the CRC-32 of the STUN message
|
||||||
the 32-bit value 0x5354554e
|
// up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with
|
||||||
*/
|
// the 32-bit value 0x5354554e
|
||||||
uint32_t fingerprint = tsk_pppfcs32(TSK_PPPINITFCS32, output->data, output->size);
|
// */
|
||||||
fingerprint ^= 0x5354554e;
|
// uint32_t fingerprint = tsk_pppfcs32(TSK_PPPINITFCS32, output->data, output->size);
|
||||||
fingerprint = tnet_htonl(fingerprint);
|
// fingerprint ^= 0x5354554e;
|
||||||
|
// fingerprint = tnet_htonl(fingerprint);
|
||||||
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_fingerprint_create(fingerprint);
|
//
|
||||||
tnet_stun_attribute_serialize(attribute, output);
|
// attribute = (tnet_stun_attr_t *)tnet_stun_attribute_fingerprint_create(fingerprint);
|
||||||
TSK_OBJECT_SAFE_FREE(attribute);
|
// tnet_stun_attribute_serialize(attribute, output);
|
||||||
}
|
// TSK_OBJECT_SAFE_FREE(attribute);
|
||||||
|
// }
|
||||||
bail:
|
//
|
||||||
return output;
|
//bail:
|
||||||
}
|
// return output;
|
||||||
|
//}
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
//
|
||||||
*
|
///**@ingroup tnet_stun_group
|
||||||
* Deserializes a STUN message from binary data.
|
// *
|
||||||
*
|
// * Deserializes a STUN message from binary data.
|
||||||
* @param [in,out] data A pointer to the binary data.
|
// *
|
||||||
* @param size The size of the binary data.
|
// * @param [in,out] data A pointer to the binary data.
|
||||||
*
|
// * @param size The size of the binary data.
|
||||||
* @retval A STUN message if deserialization succeed or NULL otherwise.
|
// *
|
||||||
**/
|
// * @retval A STUN message if deserialization succeed or NULL otherwise.
|
||||||
tnet_stun_message_t* tnet_stun_message_deserialize(const uint8_t *data, tsk_size_t size)
|
//**/
|
||||||
{
|
//tnet_stun_pkt_t* tnet_stun_message_deserialize(const uint8_t *data, tsk_size_t size)
|
||||||
tnet_stun_message_t *message = 0;
|
//{
|
||||||
uint8_t* dataPtr, *dataEnd;
|
// tnet_stun_pkt_t *message = 0;
|
||||||
|
// uint8_t* dataPtr, *dataEnd;
|
||||||
|
//
|
||||||
if(!data || (size < TNET_STUN_HEADER_SIZE) || !TNET_IS_STUN2_MSG(data, size)) {
|
//
|
||||||
goto bail;
|
// if(!data || (size < kStunAttrHdrSizeInOctets) || !TNET_STUN_BUFF_IS_STUN2(data, size)) {
|
||||||
}
|
// goto bail;
|
||||||
|
// }
|
||||||
dataPtr = (uint8_t*)data;
|
//
|
||||||
dataEnd = (dataPtr + size);
|
// dataPtr = (uint8_t*)data;
|
||||||
|
// dataEnd = (dataPtr + size);
|
||||||
message = tnet_stun_message_create_null();
|
//
|
||||||
|
// message = tnet_stun_message_create_null();
|
||||||
/* Message Type
|
//
|
||||||
*/
|
// /* Message Type
|
||||||
message->type = (tnet_stun_message_type_t)tnet_ntohs_2(dataPtr);
|
// */
|
||||||
dataPtr += 2;
|
// message->type = (tnet_stun_pkt_type_t)tnet_ntohs_2(dataPtr);
|
||||||
|
// dataPtr += 2;
|
||||||
/* Message Length
|
//
|
||||||
*/
|
// /* Message Length
|
||||||
message->length = tnet_ntohs_2(dataPtr);
|
// */
|
||||||
dataPtr += 2;
|
// message->length = tnet_ntohs_2(dataPtr);
|
||||||
|
// dataPtr += 2;
|
||||||
/* Check message validity
|
//
|
||||||
*/
|
// /* Check message validity
|
||||||
if((message->length + TNET_STUN_HEADER_SIZE) != size) {
|
// */
|
||||||
TSK_OBJECT_SAFE_FREE(message);
|
// if((message->length + kStunAttrHdrSizeInOctets) != size) {
|
||||||
goto bail;
|
// TSK_OBJECT_SAFE_FREE(message);
|
||||||
}
|
// goto bail;
|
||||||
|
// }
|
||||||
/* Magic Cookie
|
//
|
||||||
==> already set by the constructor and checked by @ref TNET_IS_STUN2
|
// /* Magic Cookie
|
||||||
*/
|
// ==> already set by the constructor and checked by @ref TNET_IS_STUN2
|
||||||
dataPtr += 4;
|
// */
|
||||||
|
// dataPtr += 4;
|
||||||
/* Transaction ID
|
//
|
||||||
*/
|
// /* Transaction ID
|
||||||
memcpy(message->transaction_id, dataPtr, TNET_STUN_TRANSACID_SIZE);
|
// */
|
||||||
dataPtr += TNET_STUN_TRANSACID_SIZE;
|
// memcpy(message->transac_id, dataPtr, TNET_STUN_TRANSACID_SIZE);
|
||||||
|
// dataPtr += TNET_STUN_TRANSACID_SIZE;
|
||||||
/* == Parse attributes
|
//
|
||||||
*/
|
// /* == Parse attributes
|
||||||
while(dataPtr < dataEnd) {
|
// */
|
||||||
tnet_stun_attribute_t *attribute = tnet_stun_attribute_deserialize(dataPtr, (dataEnd - dataPtr));
|
// while(dataPtr < dataEnd) {
|
||||||
if(attribute) {
|
// tnet_stun_attr_t *attribute = tnet_stun_attribute_deserialize(dataPtr, (dataEnd - dataPtr));
|
||||||
tsk_size_t att_size = (attribute->length + 2 /* Type*/ + 2/* Length */);
|
// if(attribute) {
|
||||||
att_size += (att_size & 0x03) ? 4-(att_size & 0x03) : 0; // Skip zero bytes used to pad the attribute.
|
// tsk_size_t att_size = (attribute->length + 2 /* Type*/ + 2/* Length */);
|
||||||
|
// att_size += (att_size & 0x03) ? 4-(att_size & 0x03) : 0; // Skip zero bytes used to pad the attribute.
|
||||||
dataPtr += att_size;
|
//
|
||||||
tsk_list_push_back_data(message->attributes, (void**)&attribute);
|
// dataPtr += att_size;
|
||||||
|
// tsk_list_push_back_data(message->attributes, (void**)&attribute);
|
||||||
continue;
|
//
|
||||||
}
|
// continue;
|
||||||
else {
|
// }
|
||||||
continue;
|
// else {
|
||||||
}
|
// continue;
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
bail:
|
//
|
||||||
return message;
|
//bail:
|
||||||
}
|
// return message;
|
||||||
|
//}
|
||||||
/**@ingroup tnet_stun_group
|
//
|
||||||
*/
|
///**@ingroup tnet_stun_group
|
||||||
tsk_bool_t tnet_stun_message_has_attribute(const tnet_stun_message_t *self, tnet_stun_attribute_type_t type)
|
//*/
|
||||||
{
|
//tsk_bool_t tnet_stun_message_has_attribute(const tnet_stun_pkt_t *self, tnet_stun_attr_type_t type)
|
||||||
return (tnet_stun_message_get_attribute(self, type) != tsk_null);
|
//{
|
||||||
}
|
// return (tnet_stun_message_get_attribute(self, type) != tsk_null);
|
||||||
|
//}
|
||||||
/**@ingroup tnet_stun_group
|
//
|
||||||
* Adds an attribute to a STUN message.
|
///**@ingroup tnet_stun_group
|
||||||
* @param self The STUN message into which to add the attribute.
|
//* Adds an attribute to a STUN message.
|
||||||
* @param attribute The attribute to add.
|
//* @param self The STUN message into which to add the attribute.
|
||||||
* @retval Zero if succeed and non-zero error code otherwise.
|
//* @param attribute The attribute to add.
|
||||||
*/
|
//* @retval Zero if succeed and non-zero error code otherwise.
|
||||||
int tnet_stun_message_add_attribute(tnet_stun_message_t *self, tnet_stun_attribute_t** attribute)
|
//*/
|
||||||
{
|
//int tnet_stun_message_add_attribute(tnet_stun_pkt_t *self, tnet_stun_attr_t** attribute)
|
||||||
if(self && attribute && *attribute) {
|
//{
|
||||||
tsk_list_push_back_data(self->attributes, (void**)attribute);
|
// if(self && attribute && *attribute) {
|
||||||
return 0;
|
// tsk_list_push_back_data(self->attributes, (void**)attribute);
|
||||||
}
|
// return 0;
|
||||||
return -1;
|
// }
|
||||||
}
|
// return -1;
|
||||||
|
//}
|
||||||
/**@ingroup tnet_stun_group
|
//
|
||||||
*/
|
///**@ingroup tnet_stun_group
|
||||||
int tnet_stun_message_remove_attribute(tnet_stun_message_t *self, tnet_stun_attribute_type_t type)
|
//*/
|
||||||
{
|
//int tnet_stun_message_remove_attribute(tnet_stun_pkt_t *self, tnet_stun_attr_type_t type)
|
||||||
if(self && self->attributes) {
|
//{
|
||||||
tsk_list_remove_item_by_pred(self->attributes, __pred_find_attribute_by_type, &type);
|
// if(self && self->attributes) {
|
||||||
}
|
// tsk_list_remove_item_by_pred(self->attributes, __pred_find_attribute_by_type, &type);
|
||||||
return 0;
|
// }
|
||||||
}
|
// return 0;
|
||||||
|
//}
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
//
|
||||||
* Gets a STUN attribute from a message.
|
///**@ingroup tnet_stun_group
|
||||||
* @param self The message from which to get the attribute.
|
//* Gets a STUN attribute from a message.
|
||||||
* @param type The type of the attribute to retrieve.
|
//* @param self The message from which to get the attribute.
|
||||||
* @retval @ref tnet_stun_attribute_t object if found and NULL otherwise.
|
//* @param type The type of the attribute to retrieve.
|
||||||
*/
|
//* @retval @ref tnet_stun_attr_t object if found and NULL otherwise.
|
||||||
const tnet_stun_attribute_t* tnet_stun_message_get_attribute(const tnet_stun_message_t *self, tnet_stun_attribute_type_t type)
|
//*/
|
||||||
{
|
//const tnet_stun_attr_t* tnet_stun_message_get_attribute(const tnet_stun_pkt_t *self, tnet_stun_attr_type_t type)
|
||||||
tnet_stun_attribute_t* attribute;
|
//{
|
||||||
|
// tnet_stun_attr_t* attribute;
|
||||||
if(self && !TSK_LIST_IS_EMPTY(self->attributes)) {
|
//
|
||||||
tsk_list_item_t *item;
|
// if(self && !TSK_LIST_IS_EMPTY(self->attributes)) {
|
||||||
tsk_list_foreach(item, self->attributes) {
|
// tsk_list_item_t *item;
|
||||||
if((attribute = item->data) && attribute->type == type) {
|
// tsk_list_foreach(item, self->attributes) {
|
||||||
return attribute;
|
// if((attribute = item->data) && attribute->type == type) {
|
||||||
}
|
// return attribute;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return 0;
|
// }
|
||||||
}
|
// return 0;
|
||||||
|
//}
|
||||||
/**@ingroup tnet_stun_group
|
//
|
||||||
* Gets the STUN error-code attribute value from the message.
|
///**@ingroup tnet_stun_group
|
||||||
* @param self The STUN message from which to get the error code.
|
//* Gets the STUN error-code attribute value from the message.
|
||||||
* @retval The error code if the message contain such attribute or -1 otherwise.
|
//* @param self The STUN message from which to get the error code.
|
||||||
*/
|
//* @retval The error code if the message contain such attribute or -1 otherwise.
|
||||||
short tnet_stun_message_get_errorcode(const tnet_stun_message_t *self)
|
//*/
|
||||||
{
|
//short tnet_stun_message_get_errorcode(const tnet_stun_pkt_t *self)
|
||||||
const tnet_stun_attribute_errorcode_t* error = (const tnet_stun_attribute_errorcode_t*)tnet_stun_message_get_attribute(self, stun_error_code);
|
//{
|
||||||
if(error) {
|
// const tnet_stun_attribute_errorcode_t* error = (const tnet_stun_attribute_errorcode_t*)tnet_stun_message_get_attribute(self, stun_error_code);
|
||||||
return ((error->_class*100) + error->number);
|
// if(error) {
|
||||||
}
|
// return ((error->_class*100) + error->number);
|
||||||
return -1;
|
// }
|
||||||
}
|
// return -1;
|
||||||
|
//}
|
||||||
/**@ingroup tnet_stun_group
|
//
|
||||||
* Gets the STUN @b realm attribute value from the message.
|
///**@ingroup tnet_stun_group
|
||||||
* @param self The STUN message from which to get the @b realm.
|
//* Gets the STUN @b realm attribute value from the message.
|
||||||
* @retval The @b realm as a string pointer code if the message contain such attribute or NULL otherwise.
|
//* @param self The STUN message from which to get the @b realm.
|
||||||
*/
|
//* @retval The @b realm as a string pointer code if the message contain such attribute or NULL otherwise.
|
||||||
const char* tnet_stun_message_get_realm(const tnet_stun_message_t *self)
|
//*/
|
||||||
{
|
//const char* tnet_stun_message_get_realm(const tnet_stun_pkt_t *self)
|
||||||
const tnet_stun_attribute_realm_t* realm = (const tnet_stun_attribute_realm_t*)tnet_stun_message_get_attribute(self, stun_realm);
|
//{
|
||||||
if(realm) {
|
// const tnet_stun_attribute_realm_t* realm = (const tnet_stun_attribute_realm_t*)tnet_stun_message_get_attribute(self, stun_realm);
|
||||||
return realm->value;
|
// if(realm) {
|
||||||
}
|
// return realm->value;
|
||||||
return 0;
|
// }
|
||||||
}
|
// return 0;
|
||||||
|
//}
|
||||||
/**@ingroup tnet_stun_group
|
//
|
||||||
* Gets the STUN @b nonce attribute value from the message.
|
///**@ingroup tnet_stun_group
|
||||||
* @param self The STUN message from which to get the @b nonce.
|
//* Gets the STUN @b nonce attribute value from the message.
|
||||||
* @retval The @b nonce as a string pointer code if the message contain such attribute or NULL otherwise.
|
//* @param self The STUN message from which to get the @b nonce.
|
||||||
*/
|
//* @retval The @b nonce as a string pointer code if the message contain such attribute or NULL otherwise.
|
||||||
const char* tnet_stun_message_get_nonce(const tnet_stun_message_t *self)
|
//*/
|
||||||
{
|
//const char* tnet_stun_message_get_nonce(const tnet_stun_pkt_t *self)
|
||||||
const tnet_stun_attribute_nonce_t* nonce = (const tnet_stun_attribute_nonce_t*)tnet_stun_message_get_attribute(self, stun_nonce);
|
//{
|
||||||
if(nonce) {
|
// const tnet_stun_attribute_nonce_t* nonce = (const tnet_stun_attribute_nonce_t*)tnet_stun_message_get_attribute(self, stun_nonce);
|
||||||
return nonce->value;
|
// if(nonce) {
|
||||||
}
|
// return nonce->value;
|
||||||
return 0;
|
// }
|
||||||
}
|
// return 0;
|
||||||
|
//}
|
||||||
/**@ingroup tnet_stun_group
|
//
|
||||||
* Gets the STUN @b lifetime attribute value from the message.
|
///**@ingroup tnet_stun_group
|
||||||
* @param self The STUN message from which to get the @b lifetime.
|
//* Gets the STUN @b lifetime attribute value from the message.
|
||||||
* @retval The @b lifetime (any positive value) if the message contain such attribute or -1 otherwise.
|
//* @param self The STUN message from which to get the @b lifetime.
|
||||||
*/
|
//* @retval The @b lifetime (any positive value) if the message contain such attribute or -1 otherwise.
|
||||||
int32_t tnet_stun_message_get_lifetime(const tnet_stun_message_t *self)
|
//*/
|
||||||
{
|
//int32_t tnet_stun_message_get_lifetime(const tnet_stun_pkt_t *self)
|
||||||
const tnet_turn_attribute_lifetime_t* lifetime = (const tnet_turn_attribute_lifetime_t*)tnet_stun_message_get_attribute(self, stun_lifetime);
|
//{
|
||||||
if(lifetime) {
|
// /*const tnet_turn_attribute_lifetime_t* lifetime = (const tnet_turn_attribute_lifetime_t*)tnet_stun_message_get_attribute(self, stun_lifetime);
|
||||||
return lifetime->value;
|
// if(lifetime) {
|
||||||
}
|
// return lifetime->value;
|
||||||
return -1;
|
// }*/
|
||||||
}
|
// return -1;
|
||||||
|
//}
|
||||||
/**@ingroup tnet_stun_group
|
//
|
||||||
*/
|
///**@ingroup tnet_stun_group
|
||||||
tsk_bool_t tnet_stun_message_transac_id_equals(const tnet_stun_transacid_t id1, const tnet_stun_transacid_t id2)
|
//*/
|
||||||
{
|
//tsk_bool_t tnet_stun_utils_transac_id_equals(const tnet_stun_transac_id_t id1, const tnet_stun_transac_id_t id2)
|
||||||
tsk_size_t i;
|
//{
|
||||||
static const tsk_size_t size = sizeof(tnet_stun_transacid_t);
|
// tsk_size_t i;
|
||||||
for(i = 0; i < size; i++) {
|
// static const tsk_size_t size = sizeof(tnet_stun_transac_id_t);
|
||||||
if(id1[i] != id2[i]) {
|
// for(i = 0; i < size; i++) {
|
||||||
return tsk_false;
|
// if(id1[i] != id2[i]) {
|
||||||
}
|
// return tsk_false;
|
||||||
}
|
// }
|
||||||
return tsk_true;
|
// }
|
||||||
}
|
// return tsk_true;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
//=================================================================================================
|
//
|
||||||
// STUN2 MESSAGE object definition
|
////=================================================================================================
|
||||||
|
//// STUN2 MESSAGE object definition
|
||||||
|
////
|
||||||
|
//static tsk_object_t* tnet_stun_message_ctor(tsk_object_t * self, va_list * app)
|
||||||
|
//{
|
||||||
|
// tnet_stun_pkt_t *message = self;
|
||||||
|
// if(message) {
|
||||||
|
// message->username = tsk_strdup(va_arg(*app, const char*));
|
||||||
|
// message->password = tsk_strdup(va_arg(*app, const char*));
|
||||||
|
//
|
||||||
|
// message->cookie = kStunMagicCookieLong;
|
||||||
|
// message->attributes = tsk_list_create();
|
||||||
|
//
|
||||||
|
// message->fingerprint = 1;
|
||||||
|
// message->integrity = 0;
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// // Create random transaction id
|
||||||
|
// int i;
|
||||||
|
// for(i = 0; i < sizeof(message->transac_id)/sizeof(message->transac_id[0]); ++i) {
|
||||||
|
// message->transac_id[i] = rand();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return self;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//static tsk_object_t* tnet_stun_message_dtor(tsk_object_t * self)
|
||||||
|
//{
|
||||||
|
// tnet_stun_pkt_t *message = self;
|
||||||
|
// if(message) {
|
||||||
|
// TSK_FREE(message->username);
|
||||||
|
// TSK_FREE(message->password);
|
||||||
|
// TSK_FREE(message->realm);
|
||||||
|
// TSK_FREE(message->nonce);
|
||||||
|
//
|
||||||
|
// TSK_OBJECT_SAFE_FREE(message->attributes);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return self;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//static const tsk_object_def_t tnet_stun_message_def_s = {
|
||||||
|
// sizeof(tnet_stun_pkt_t),
|
||||||
|
// tnet_stun_message_ctor,
|
||||||
|
// tnet_stun_message_dtor,
|
||||||
|
// tsk_null,
|
||||||
|
//};
|
||||||
|
//const tsk_object_def_t *tnet_stun_message_def_t = &tnet_stun_message_def_s;
|
||||||
//
|
//
|
||||||
static tsk_object_t* tnet_stun_message_ctor(tsk_object_t * self, va_list * app)
|
|
||||||
{
|
|
||||||
tnet_stun_message_t *message = self;
|
|
||||||
if(message) {
|
|
||||||
message->username = tsk_strdup(va_arg(*app, const char*));
|
|
||||||
message->password = tsk_strdup(va_arg(*app, const char*));
|
|
||||||
|
|
||||||
message->cookie = TNET_STUN_MAGIC_COOKIE;
|
|
||||||
message->attributes = tsk_list_create();
|
|
||||||
|
|
||||||
message->fingerprint = 1;
|
|
||||||
message->integrity = 0;
|
|
||||||
|
|
||||||
{
|
|
||||||
// Create random transaction id
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < sizeof(message->transaction_id)/sizeof(message->transaction_id[0]); ++i) {
|
|
||||||
message->transaction_id[i] = rand();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
static tsk_object_t* tnet_stun_message_dtor(tsk_object_t * self)
|
|
||||||
{
|
|
||||||
tnet_stun_message_t *message = self;
|
|
||||||
if(message) {
|
|
||||||
TSK_FREE(message->username);
|
|
||||||
TSK_FREE(message->password);
|
|
||||||
TSK_FREE(message->realm);
|
|
||||||
TSK_FREE(message->nonce);
|
|
||||||
|
|
||||||
TSK_OBJECT_SAFE_FREE(message->attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const tsk_object_def_t tnet_stun_message_def_s = {
|
|
||||||
sizeof(tnet_stun_message_t),
|
|
||||||
tnet_stun_message_ctor,
|
|
||||||
tnet_stun_message_dtor,
|
|
||||||
tsk_null,
|
|
||||||
};
|
|
||||||
const tsk_object_def_t *tnet_stun_message_def_t = &tnet_stun_message_def_s;
|
|
||||||
|
|
||||||
|
|
|
@ -1,246 +1,246 @@
|
||||||
/*
|
///*
|
||||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
//* Copyright (C) 2010-2011 Mamadou Diop.
|
||||||
*
|
//*
|
||||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
//*
|
||||||
* This file is part of Open Source Doubango Framework.
|
//* This file is part of Open Source Doubango Framework.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
//* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
//* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
//* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
//* (at your option) any later version.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is distributed in the hope that it will be useful,
|
//* DOUBANGO is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
//* GNU General Public License for more details.
|
||||||
*
|
//*
|
||||||
* You should have received a copy of the GNU General Public License
|
//* You should have received a copy of the GNU General Public License
|
||||||
* along with DOUBANGO.
|
//* along with DOUBANGO.
|
||||||
*
|
//*
|
||||||
*/
|
//*/
|
||||||
|
//
|
||||||
/**@file tnet_stun_message.h
|
///**@file tnet_stun_message.h
|
||||||
* @brief STUN2 (RFC 5389) message parser.
|
// * @brief STUN2 (RFC 5389) message parser.
|
||||||
*
|
// *
|
||||||
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
// * @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
// *
|
||||||
|
//
|
||||||
*/
|
// */
|
||||||
#ifndef TNET_STUN_MESSAGE_H
|
//#ifndef TNET_STUN_MESSAGE_H
|
||||||
#define TNET_STUN_MESSAGE_H
|
//#define TNET_STUN_MESSAGE_H
|
||||||
|
//
|
||||||
#include "tinynet_config.h"
|
//#include "tinynet_config.h"
|
||||||
#include "stun/tnet_stun_attribute.h"
|
//#include "stun/tnet_stun_attribute.h"
|
||||||
|
//
|
||||||
#include "tsk_buffer.h"
|
//#include "tsk_buffer.h"
|
||||||
|
//
|
||||||
TNET_BEGIN_DECLS
|
//TNET_BEGIN_DECLS
|
||||||
|
//
|
||||||
#define TNET_STUN_CLASS_REQUEST_MASK (0x0000)
|
//#define TNET_STUN_CLASS_REQUEST_MASK (0x0000)
|
||||||
#define TNET_STUN_CLASS_INDICATION_MASK (0x0010)
|
//#define TNET_STUN_CLASS_INDICATION_MASK (0x0010)
|
||||||
#define TNET_STUN_CLASS_SUCCESS_MASK (0x0100)
|
//#define TNET_STUN_CLASS_SUCCESS_MASK (0x0100)
|
||||||
#define TNET_STUN_CLASS_ERROR_MASK (0x0110)
|
//#define TNET_STUN_CLASS_ERROR_MASK (0x0110)
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* @def TNET_STUN_MESSAGE_IS_REQUEST
|
//* @def TNET_STUN_MESSAGE_IS_REQUEST
|
||||||
* Checks whether the STUN message is a request or not.
|
//* Checks whether the STUN message is a request or not.
|
||||||
*/
|
//*/
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* @def TNET_STUN_MESSAGE_IS_INDICATION
|
//* @def TNET_STUN_MESSAGE_IS_INDICATION
|
||||||
* Checks whether the STUN message is an indicaton message or not.
|
//* Checks whether the STUN message is an indicaton message or not.
|
||||||
*/
|
//*/
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* @def TNET_STUN_RESPONSE_IS_SUCCESS
|
//* @def TNET_STUN_PKT_RESP_IS_SUCCESS
|
||||||
* Checks whether the STUN message is a success response or not.
|
//* Checks whether the STUN message is a success response or not.
|
||||||
*/
|
//*/
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* @def TNET_STUN_RESPONSE_IS_ERROR
|
//* @def TNET_STUN_PKT_RESP_IS_ERROR
|
||||||
* Checks whether the STUN message is an error response or not.
|
//* Checks whether the STUN message is an error response or not.
|
||||||
*/
|
//*/
|
||||||
#define TNET_STUN_MESSAGE_IS_REQUEST(self) ((self) && (((self)->type & 0x0110) == TNET_STUN_CLASS_REQUEST_MASK))
|
//#define TNET_STUN_MESSAGE_IS_REQUEST(self) ((self) && (((self)->type & 0x0110) == TNET_STUN_CLASS_REQUEST_MASK))
|
||||||
#define TNET_STUN_MESSAGE_IS_RESPONSE(self) (TNET_STUN_RESPONSE_IS_SUCCESS((self)) || TNET_STUN_RESPONSE_IS_ERROR((self)))
|
//#define TNET_STUN_MESSAGE_IS_RESPONSE(self) (TNET_STUN_PKT_RESP_IS_SUCCESS((self)) || TNET_STUN_PKT_RESP_IS_ERROR((self)))
|
||||||
#define TNET_STUN_MESSAGE_IS_INDICATION(self) ((self) && (((self)->type & 0x0110) == TNET_STUN_CLASS_INDICATION_MASK))
|
//#define TNET_STUN_MESSAGE_IS_INDICATION(self) ((self) && (((self)->type & 0x0110) == TNET_STUN_CLASS_INDICATION_MASK))
|
||||||
#define TNET_STUN_RESPONSE_IS_SUCCESS(self) ((self) && (((self)->type & 0x0110) == TNET_STUN_CLASS_SUCCESS_MASK))
|
//#define TNET_STUN_PKT_RESP_IS_SUCCESS(self) ((self) && (((self)->type & 0x0110) == TNET_STUN_CLASS_SUCCESS_MASK))
|
||||||
#define TNET_STUN_RESPONSE_IS_ERROR(self) ((self) && (((self)->type & 0x0110) == TNET_STUN_CLASS_ERROR_MASK))
|
//#define TNET_STUN_PKT_RESP_IS_ERROR(self) ((self) && (((self)->type & 0x0110) == TNET_STUN_CLASS_ERROR_MASK))
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* Checks if the pointer to the buffer hold a STUN header by checking that it starts with 0b00 and contain the magic cookie.
|
// * Checks if the pointer to the buffer hold a STUN header by checking that it starts with 0b00 and contain the magic cookie.
|
||||||
* As per RFC 5389 subclause 19: Explicitly point out that the most significant 2 bits of STUN are
|
// * As per RFC 5389 subclause 19: Explicitly point out that the most significant 2 bits of STUN are
|
||||||
* 0b00, allowing easy differentiation with RTP packets when used with ICE.
|
// * 0b00, allowing easy differentiation with RTP packets when used with ICE.
|
||||||
* As per RFC 5389 subclause 6: The magic cookie field MUST contain the fixed value 0x2112A442 in
|
// * As per RFC 5389 subclause 6: The magic cookie field MUST contain the fixed value 0x2112A442 in
|
||||||
* network byte order.
|
// * network byte order.
|
||||||
*
|
// *
|
||||||
* @param PU8 The pointer to the buffer holding the STUN raw data.
|
// * @param PU8 The pointer to the buffer holding the STUN raw data.
|
||||||
**/
|
//**/
|
||||||
#define TNET_IS_STUN2_MSG(PU8, SIZE) \
|
//#define TNET_STUN_BUFF_IS_STUN2(PU8, SIZE) \
|
||||||
( \
|
// ( \
|
||||||
((PU8)) && \
|
// ((PU8)) && \
|
||||||
((SIZE) >= TNET_STUN_HEADER_SIZE) && \
|
// ((SIZE) >= kStunAttrHdrSizeInOctets) && \
|
||||||
(((PU8)[0] & 0xc0) == 0x00) && \
|
// (((PU8)[0] & 0xc0) == 0x00) && \
|
||||||
( PU8[4] == 0x21 && PU8[5] == 0x12 && PU8[6] == 0xA4 && PU8[7] == 0x42 ) \
|
// ( PU8[4] == 0x21 && PU8[5] == 0x12 && PU8[6] == 0xA4 && PU8[7] == 0x42 ) \
|
||||||
)
|
// )
|
||||||
#define TNET_IS_STUN2 TNET_IS_STUN2_MSG // for backward compatibility
|
//#define TNET_IS_STUN2 TNET_STUN_BUFF_IS_STUN2 // for backward compatibility
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* STUN trasactionn ID size (96bits = 12bytes).
|
// * STUN trasactionn ID size (96bits = 12bytes).
|
||||||
*/
|
//*/
|
||||||
#define TNET_STUN_TRANSACID_SIZE 12
|
//#define TNET_STUN_TRANSACID_SIZE 12
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* Defines an alias representing the STUN transaction id type.
|
// * Defines an alias representing the STUN transaction id type.
|
||||||
**/
|
//**/
|
||||||
typedef uint8_t tnet_stun_transacid_t[TNET_STUN_TRANSACID_SIZE];
|
//typedef uint8_t tnet_stun_transac_id_t[TNET_STUN_TRANSACID_SIZE];
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* List of all supported STUN classes as per RFC 5389 subcaluse 6.
|
// * List of all supported STUN classes as per RFC 5389 subcaluse 6.
|
||||||
**/
|
//**/
|
||||||
typedef enum tnet_stun_class_type_e {
|
//typedef enum tnet_stun_class_type_e {
|
||||||
stun_class_request = 0x00, /**< Request class: 0b00 */
|
// stun_class_request = 0x00, /**< Request class: 0b00 */
|
||||||
stun_class_indication = 0x01, /**< Indication class: 0b01 */
|
// stun_class_indication = 0x01, /**< Indication class: 0b01 */
|
||||||
stun_class_success_response = 0x02, /**< Success response class: 0b10 */
|
// stun_class_success_response = 0x02, /**< Success response class: 0b10 */
|
||||||
stun_class_error_response = 0x03, /**< Error/failure response class: 0b11 */
|
// stun_class_error_response = 0x03, /**< Error/failure response class: 0b11 */
|
||||||
}
|
//}
|
||||||
tnet_stun_class_type_t;
|
//tnet_stun_class_type_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* List of all supported STUN methods.
|
// * List of all supported STUN methods.
|
||||||
* RFC 5389 only define one method(Bining). All other methods have been defined
|
// * RFC 5389 only define one method(Bining). All other methods have been defined
|
||||||
* by TURN (draft-ietf-behave-turn-16 and draft-ietf-behave-turn-tcp-05).
|
// * by TURN (draft-ietf-behave-turn-16 and draft-ietf-behave-turn-tcp-05).
|
||||||
**/
|
//**/
|
||||||
typedef enum tnet_stun_method_type_e {
|
//typedef enum tnet_stun_method_type_e {
|
||||||
stun_method_binding = 0x0001, /**< RFC 5389 - Binding method: 0b000000000001 */
|
// stun_method_binding = 0x0001, /**< RFC 5389 - Binding method: 0b000000000001 */
|
||||||
|
//
|
||||||
stun_method_allocate = 0x0003, /**< draft-ietf-behave-turn-16 - Allocate (only request/response semantics defined) */
|
// stun_method_allocate = 0x0003, /**< draft-ietf-behave-turn-16 - Allocate (only request/response semantics defined) */
|
||||||
stun_method_refresh = 0x0004, /**< draft-ietf-behave-turn-16 - Refresh (only request/response semantics defined) */
|
// stun_method_refresh = 0x0004, /**< draft-ietf-behave-turn-16 - Refresh (only request/response semantics defined) */
|
||||||
stun_method_send = 0x0006, /**< draft-ietf-behave-turn-16 - Send (only indication semantics defined) */
|
// stun_method_send = 0x0006, /**< draft-ietf-behave-turn-16 - Send (only indication semantics defined) */
|
||||||
stun_method_data = 0x0007, /**< draft-ietf-behave-turn-16 - Data (only indication semantics defined) */
|
// stun_method_data = 0x0007, /**< draft-ietf-behave-turn-16 - Data (only indication semantics defined) */
|
||||||
stun_method_createpermission = 0x0008, /**< draft-ietf-behave-turn-16 - CreatePermission (only request/response semantics defined */
|
// stun_method_createpermission = 0x0008, /**< draft-ietf-behave-turn-16 - CreatePermission (only request/response semantics defined */
|
||||||
stun_method_channelbind = 0x0009, /**< draft-ietf-behave-turn-16 - ChannelBind (only request/response semantics defined) */
|
// stun_method_channelbind = 0x0009, /**< draft-ietf-behave-turn-16 - ChannelBind (only request/response semantics defined) */
|
||||||
}
|
//}
|
||||||
tnet_stun_method_type_t;
|
//tnet_stun_method_type_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
* List of all supported STUN types.
|
//* List of all supported STUN types.
|
||||||
*/
|
//*/
|
||||||
typedef enum tnet_stun_message_type_e {
|
//typedef enum tnet_stun_pkt_type_e {
|
||||||
/* RFC 5389 - 6. STUN Message Structure
|
// /* RFC 5389 - 6. STUN Message Structure
|
||||||
|
//
|
||||||
The message type defines the message class (request, success
|
// The message type defines the message class (request, success
|
||||||
response, failure response, or indication) and the message method
|
// response, failure response, or indication) and the message method
|
||||||
(the primary function) of the STUN message. Although there are four
|
// (the primary function) of the STUN message. Although there are four
|
||||||
message classes, there are only two types of transactions in STUN:
|
// message classes, there are only two types of transactions in STUN:
|
||||||
request/response transactions (which consist of a request message and
|
// request/response transactions (which consist of a request message and
|
||||||
a response message) and indication transactions (which consist of a
|
// a response message) and indication transactions (which consist of a
|
||||||
single indication message). Response classes are split into error
|
// single indication message). Response classes are split into error
|
||||||
and success responses to aid in quickly processing the STUN message.
|
// and success responses to aid in quickly processing the STUN message.
|
||||||
|
//
|
||||||
The message type field is decomposed further into the following
|
// The message type field is decomposed further into the following
|
||||||
structure:
|
// structure:
|
||||||
|
//
|
||||||
0 1
|
// 0 1
|
||||||
2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
// 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||||
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +--+--+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|M |M |M|M|M|C|M|M|M|C|M|M|M|M|
|
// |M |M |M|M|M|C|M|M|M|C|M|M|M|M|
|
||||||
|11|10|9|8|7|1|6|5|4|0|3|2|1|0|
|
// |11|10|9|8|7|1|6|5|4|0|3|2|1|0|
|
||||||
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +--+--+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*/
|
// */
|
||||||
stun_binding_request = (stun_method_binding | TNET_STUN_CLASS_REQUEST_MASK),
|
// stun_binding_request = (stun_method_binding | TNET_STUN_CLASS_REQUEST_MASK),
|
||||||
stun_binding_indication = (stun_method_binding | TNET_STUN_CLASS_INDICATION_MASK),
|
// stun_binding_indication = (stun_method_binding | TNET_STUN_CLASS_INDICATION_MASK),
|
||||||
stun_binding_success_response = (stun_method_binding | TNET_STUN_CLASS_SUCCESS_MASK),
|
// stun_binding_success_response = (stun_method_binding | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||||
stun_binding_error_response = (stun_method_binding | TNET_STUN_CLASS_ERROR_MASK),
|
// stun_binding_error_response = (stun_method_binding | TNET_STUN_CLASS_ERROR_MASK),
|
||||||
|
//
|
||||||
stun_allocate_request = (stun_method_allocate | TNET_STUN_CLASS_REQUEST_MASK),
|
// stun_allocate_request = (stun_method_allocate | TNET_STUN_CLASS_REQUEST_MASK),
|
||||||
stun_allocate_indication = (stun_method_allocate | TNET_STUN_CLASS_INDICATION_MASK),
|
// stun_allocate_indication = (stun_method_allocate | TNET_STUN_CLASS_INDICATION_MASK),
|
||||||
stun_allocate_success_response = (stun_method_allocate | TNET_STUN_CLASS_SUCCESS_MASK),
|
// stun_allocate_success_response = (stun_method_allocate | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||||
stun_allocate_error_response = (stun_method_allocate | TNET_STUN_CLASS_ERROR_MASK),
|
// stun_allocate_error_response = (stun_method_allocate | TNET_STUN_CLASS_ERROR_MASK),
|
||||||
|
//
|
||||||
stun_refresh_request = (stun_method_refresh | TNET_STUN_CLASS_REQUEST_MASK),
|
// stun_refresh_request = (stun_method_refresh | TNET_STUN_CLASS_REQUEST_MASK),
|
||||||
stun_refresh_indication = (stun_method_refresh | TNET_STUN_CLASS_INDICATION_MASK),
|
// stun_refresh_indication = (stun_method_refresh | TNET_STUN_CLASS_INDICATION_MASK),
|
||||||
stun_refresh_success_response = (stun_method_refresh | TNET_STUN_CLASS_SUCCESS_MASK),
|
// stun_refresh_success_response = (stun_method_refresh | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||||
stun_refresh_error_response = (stun_method_refresh | TNET_STUN_CLASS_ERROR_MASK),
|
// stun_refresh_error_response = (stun_method_refresh | TNET_STUN_CLASS_ERROR_MASK),
|
||||||
|
//
|
||||||
stun_send_indication = (stun_method_send | TNET_STUN_CLASS_INDICATION_MASK),
|
// stun_send_indication = (stun_method_send | TNET_STUN_CLASS_INDICATION_MASK),
|
||||||
|
//
|
||||||
stun_data_indication = (stun_method_data | TNET_STUN_CLASS_INDICATION_MASK),
|
// stun_data_indication = (stun_method_data | TNET_STUN_CLASS_INDICATION_MASK),
|
||||||
|
//
|
||||||
stun_createpermission_request = (stun_method_createpermission | TNET_STUN_CLASS_REQUEST_MASK),
|
// stun_createpermission_request = (stun_method_createpermission | TNET_STUN_CLASS_REQUEST_MASK),
|
||||||
stun_createpermission_indication = (stun_method_createpermission | TNET_STUN_CLASS_INDICATION_MASK),
|
// stun_createpermission_indication = (stun_method_createpermission | TNET_STUN_CLASS_INDICATION_MASK),
|
||||||
stun_createpermission_success_response = (stun_method_createpermission | TNET_STUN_CLASS_SUCCESS_MASK),
|
// stun_createpermission_success_response = (stun_method_createpermission | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||||
stun_createpermission_error_response = (stun_method_createpermission | TNET_STUN_CLASS_ERROR_MASK),
|
// stun_createpermission_error_response = (stun_method_createpermission | TNET_STUN_CLASS_ERROR_MASK),
|
||||||
|
//
|
||||||
stun_channelbind_request = (stun_method_channelbind | TNET_STUN_CLASS_REQUEST_MASK),
|
// stun_channelbind_request = (stun_method_channelbind | TNET_STUN_CLASS_REQUEST_MASK),
|
||||||
stun_channelbind_indication = (stun_method_channelbind | TNET_STUN_CLASS_INDICATION_MASK),
|
// stun_channelbind_indication = (stun_method_channelbind | TNET_STUN_CLASS_INDICATION_MASK),
|
||||||
stun_channelbind_success_response = (stun_method_channelbind | TNET_STUN_CLASS_SUCCESS_MASK),
|
// stun_channelbind_success_response = (stun_method_channelbind | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||||
stun_channelbind_error_response = (stun_method_channelbind | TNET_STUN_CLASS_ERROR_MASK),
|
// stun_channelbind_error_response = (stun_method_channelbind | TNET_STUN_CLASS_ERROR_MASK),
|
||||||
}
|
//}
|
||||||
tnet_stun_message_type_t;
|
//tnet_stun_pkt_type_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_stun_group
|
///**@ingroup tnet_stun_group
|
||||||
*
|
// *
|
||||||
* STUN Message structure as per RFC 5389 subclause 6.
|
// * STUN Message structure as per RFC 5389 subclause 6.
|
||||||
* http://tools.ietf.org/html/rfc5389#section-6
|
// * http://tools.ietf.org/html/rfc5389#section-6
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_stun_message_s {
|
//typedef struct tnet_stun_pkt_s {
|
||||||
TSK_DECLARE_OBJECT;
|
// TSK_DECLARE_OBJECT;
|
||||||
|
//
|
||||||
/*
|
// /*
|
||||||
0 1 2 3
|
// 0 1 2 3
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|0 0| STUN Message Type | Message Length |
|
// |0 0| STUN Message Type | Message Length |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Magic Cookie |
|
// | Magic Cookie |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| |
|
// | |
|
||||||
| Transaction ID (96 bits) |
|
// | Transaction ID (96 bits) |
|
||||||
| |
|
// | |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*/
|
// */
|
||||||
|
//
|
||||||
tnet_stun_message_type_t type;
|
// tnet_stun_pkt_type_t type;
|
||||||
uint16_t length;
|
// uint16_t length;
|
||||||
uint32_t cookie;
|
// uint32_t cookie;
|
||||||
tnet_stun_transacid_t transaction_id;
|
// tnet_stun_transac_id_t transaction_id;
|
||||||
|
//
|
||||||
unsigned fingerprint:1;
|
// unsigned fingerprint:1;
|
||||||
unsigned integrity:1;
|
// unsigned integrity:1;
|
||||||
unsigned dontfrag:1;
|
// unsigned dontfrag:1;
|
||||||
unsigned nointegrity:1;
|
// unsigned nointegrity:1;
|
||||||
|
//
|
||||||
char* username;
|
// char* username;
|
||||||
char* password;
|
// char* password;
|
||||||
char* realm;
|
// char* realm;
|
||||||
char* nonce;
|
// char* nonce;
|
||||||
|
//
|
||||||
tnet_stun_attributes_L_t *attributes; /**< List of all attributes associated to this message */
|
// tnet_stun_attributes_L_t *attributes; /**< List of all attributes associated to this message */
|
||||||
}
|
//}
|
||||||
tnet_stun_message_t;
|
//tnet_stun_pkt_t;
|
||||||
|
//
|
||||||
typedef tnet_stun_message_t tnet_stun_response_t;
|
//typedef tnet_stun_pkt_t tnet_stun_pkt_resp_t;
|
||||||
typedef tnet_stun_message_t tnet_stun_request_t;
|
//typedef tnet_stun_pkt_t tnet_stun_pkt_req_t;
|
||||||
|
//
|
||||||
TINYNET_API tsk_buffer_t* tnet_stun_message_serialize(const tnet_stun_message_t *message);
|
//TINYNET_API tsk_buffer_t* tnet_stun_pkt_serialize(const tnet_stun_pkt_t *message);
|
||||||
tnet_stun_message_t* tnet_stun_message_deserialize(const uint8_t *data, tsk_size_t size);
|
//tnet_stun_pkt_t* tnet_stun_message_deserialize(const uint8_t *data, tsk_size_t size);
|
||||||
tsk_bool_t tnet_stun_message_has_attribute(const tnet_stun_message_t *self, tnet_stun_attribute_type_t type);
|
//tsk_bool_t tnet_stun_message_has_attribute(const tnet_stun_pkt_t *self, tnet_stun_attr_type_t type);
|
||||||
TINYNET_API int tnet_stun_message_add_attribute(tnet_stun_message_t *self, tnet_stun_attribute_t** attribute);
|
//TINYNET_API int tnet_stun_message_add_attribute(tnet_stun_pkt_t *self, tnet_stun_attr_t** attribute);
|
||||||
int tnet_stun_message_remove_attribute(tnet_stun_message_t *self, tnet_stun_attribute_type_t type);
|
//int tnet_stun_message_remove_attribute(tnet_stun_pkt_t *self, tnet_stun_attr_type_t type);
|
||||||
const tnet_stun_attribute_t* tnet_stun_message_get_attribute(const tnet_stun_message_t *self, tnet_stun_attribute_type_t type);
|
//const tnet_stun_attr_t* tnet_stun_message_get_attribute(const tnet_stun_pkt_t *self, tnet_stun_attr_type_t type);
|
||||||
short tnet_stun_message_get_errorcode(const tnet_stun_message_t *self);
|
//short tnet_stun_message_get_errorcode(const tnet_stun_pkt_t *self);
|
||||||
const char* tnet_stun_message_get_realm(const tnet_stun_message_t *self);
|
//const char* tnet_stun_message_get_realm(const tnet_stun_pkt_t *self);
|
||||||
const char* tnet_stun_message_get_nonce(const tnet_stun_message_t *self);
|
//const char* tnet_stun_message_get_nonce(const tnet_stun_pkt_t *self);
|
||||||
int32_t tnet_stun_message_get_lifetime(const tnet_stun_message_t *self);
|
//int32_t tnet_stun_message_get_lifetime(const tnet_stun_pkt_t *self);
|
||||||
tsk_bool_t tnet_stun_message_transac_id_equals(const tnet_stun_transacid_t id1, const tnet_stun_transacid_t id2);
|
//tsk_bool_t tnet_stun_utils_transac_id_equals(const tnet_stun_transac_id_t id1, const tnet_stun_transac_id_t id2);
|
||||||
|
//
|
||||||
|
//
|
||||||
TINYNET_API tnet_stun_message_t* tnet_stun_message_create(const char* username, const char* password);
|
//TINYNET_API tnet_stun_pkt_t* tnet_stun_message_create(const char* username, const char* password);
|
||||||
TINYNET_API tnet_stun_message_t* tnet_stun_message_create_null();
|
//TINYNET_API tnet_stun_pkt_t* tnet_stun_message_create_null();
|
||||||
|
//
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_message_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_message_def_t;
|
||||||
|
//
|
||||||
|
//
|
||||||
TNET_END_DECLS
|
//TNET_END_DECLS
|
||||||
|
//
|
||||||
|
//
|
||||||
#endif /* TNET_STUN_MESSAGE_H */
|
//#endif /* TNET_STUN_MESSAGE_H */
|
||||||
|
//
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
#include "tsk_memory.h"
|
#include "tsk_memory.h"
|
||||||
#include "tsk_debug.h"
|
#include "tsk_debug.h"
|
||||||
|
|
||||||
|
#if !defined(PRINT_DESTROYED_MSG)
|
||||||
|
# define PRINT_DESTROYED_MSG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
int tnet_stun_pkt_create(tnet_stun_pkt_type_t e_type, uint16_t u_length, const tnet_stun_transac_id_t* pc_transac_id, tnet_stun_pkt_t** pp_attr)
|
int tnet_stun_pkt_create(tnet_stun_pkt_type_t e_type, uint16_t u_length, const tnet_stun_transac_id_t* pc_transac_id, tnet_stun_pkt_t** pp_attr)
|
||||||
{
|
{
|
||||||
extern const tsk_object_def_t *tnet_stun_pkt_def_t;
|
extern const tsk_object_def_t *tnet_stun_pkt_def_t;
|
||||||
|
@ -169,6 +173,27 @@ bail:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tnet_stun_pkt_attr_remove(struct tnet_stun_pkt_s* p_self, enum tnet_stun_attr_type_e e_type)
|
||||||
|
{
|
||||||
|
tsk_list_item_t* pc_item;
|
||||||
|
tnet_stun_attr_t* pc_attr;
|
||||||
|
if (!p_self || !p_self->p_list_attrs) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
again:
|
||||||
|
tsk_list_foreach(pc_item, p_self->p_list_attrs) {
|
||||||
|
if ((pc_attr = (tnet_stun_attr_t*)pc_item->data)) {
|
||||||
|
if (pc_attr->hdr.e_type == e_type) {
|
||||||
|
tsk_list_remove_item(p_self->p_list_attrs, pc_item);
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int tnet_stun_pkt_attr_find(const tnet_stun_pkt_t* pc_self, tnet_stun_attr_type_t e_type, tsk_size_t u_index, const tnet_stun_attr_t** ppc_attr)
|
int tnet_stun_pkt_attr_find(const tnet_stun_pkt_t* pc_self, tnet_stun_attr_type_t e_type, tsk_size_t u_index, const tnet_stun_attr_t** ppc_attr)
|
||||||
{
|
{
|
||||||
const tsk_list_item_t* pc_item;
|
const tsk_list_item_t* pc_item;
|
||||||
|
@ -381,6 +406,32 @@ int tnet_stun_pkt_write_with_padding(const tnet_stun_pkt_t* pc_self, uint8_t* p_
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tnet_stun_pkt_write_with_padding_2(const struct tnet_stun_pkt_s* pc_self, struct tsk_buffer_s** pp_buff)
|
||||||
|
{
|
||||||
|
tsk_size_t u_buff_size;
|
||||||
|
int ret;
|
||||||
|
if (!pc_self || !pp_buff) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*pp_buff = tsk_null;
|
||||||
|
if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_self, &u_buff_size))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
u_buff_size += kStunBuffMinPad;
|
||||||
|
if (!(*pp_buff = tsk_buffer_create(tsk_null, u_buff_size))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if ((ret = tnet_stun_pkt_write_with_padding(pc_self, (*pp_buff)->data, (*pp_buff)->size, &(*pp_buff)->size))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
bail:
|
||||||
|
if (ret) {
|
||||||
|
TSK_OBJECT_SAFE_FREE(*pp_buff);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int tnet_stun_pkt_is_complete(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_bool_t *pb_is_complete)
|
int tnet_stun_pkt_is_complete(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_bool_t *pb_is_complete)
|
||||||
{
|
{
|
||||||
if (!pb_is_complete) {
|
if (!pb_is_complete) {
|
||||||
|
@ -408,7 +459,7 @@ int tnet_stun_pkt_read(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tnet
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!TNET_STUN_PKT_IS_STUN2(pc_buff_ptr, n_buff_size)) {
|
if (!TNET_STUN_BUFF_IS_STUN2(pc_buff_ptr, n_buff_size)) {
|
||||||
TSK_DEBUG_ERROR("Buffer doesn't contain a valid STUN2 pkt");
|
TSK_DEBUG_ERROR("Buffer doesn't contain a valid STUN2 pkt");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
@ -461,11 +512,12 @@ int tnet_stun_pkt_auth_prepare(tnet_stun_pkt_t* p_self, const char* pc_usr_name,
|
||||||
int ret;
|
int ret;
|
||||||
static const tsk_sha1digest_t __pc_sha1digestEmpty = { 0 };
|
static const tsk_sha1digest_t __pc_sha1digestEmpty = { 0 };
|
||||||
static const uint16_t __u_sha1digestEmpty = sizeof(__pc_sha1digestEmpty);
|
static const uint16_t __u_sha1digestEmpty = sizeof(__pc_sha1digestEmpty);
|
||||||
if (!p_self || !pc_usr_name || !pc_realm || !pc_nonce) {
|
if (!p_self /*|| !pc_usr_name*/ || !pc_pwd /*|| !pc_realm || !pc_nonce*/) { // "username", "realm" and "nonce" are null for short-term authentication
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// USERNAME
|
// USERNAME
|
||||||
|
if (pc_usr_name) { // LONG-TERM, optional for SHORT-TERM
|
||||||
if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_username, &pc_attr))) {
|
if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_username, &pc_attr))) {
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -482,7 +534,9 @@ int tnet_stun_pkt_auth_prepare(tnet_stun_pkt_t* p_self, const char* pc_usr_name,
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// REALM
|
// REALM
|
||||||
|
if (pc_realm) { // LONG-TERM
|
||||||
if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_realm, &pc_attr))) {
|
if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_realm, &pc_attr))) {
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -499,7 +553,9 @@ int tnet_stun_pkt_auth_prepare(tnet_stun_pkt_t* p_self, const char* pc_usr_name,
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// NONCE
|
// NONCE
|
||||||
|
if (pc_nonce) { // LONG-TERM
|
||||||
if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_nonce, &pc_attr))) {
|
if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_nonce, &pc_attr))) {
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -516,6 +572,7 @@ int tnet_stun_pkt_auth_prepare(tnet_stun_pkt_t* p_self, const char* pc_usr_name,
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// MESSAGE-INTEGRITY
|
// MESSAGE-INTEGRITY
|
||||||
if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_message_integrity, &pc_attr))) {
|
if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_message_integrity, &pc_attr))) {
|
||||||
goto bail;
|
goto bail;
|
||||||
|
@ -621,6 +678,50 @@ int tnet_stun_pkt_get_errorcode(const struct tnet_stun_pkt_s* pc_self, uint16_t*
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tnet_stun_pkt_process_err420(struct tnet_stun_pkt_s *p_self, const struct tnet_stun_pkt_s *pc_pkt_resp420)
|
||||||
|
{
|
||||||
|
const tnet_stun_attr_vdata_t* pc_attr;
|
||||||
|
uint16_t u16;
|
||||||
|
int ret;
|
||||||
|
tsk_bool_t b_done = tsk_false;
|
||||||
|
if (!p_self || !pc_pkt_resp420) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt_resp420, tnet_stun_attr_type_unknown_attrs, (const tnet_stun_attr_t**)&pc_attr))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if (!pc_attr || !pc_attr->p_data_ptr || (pc_attr->u_data_size & 1)) {
|
||||||
|
TSK_DEBUG_ERROR("UNKNOWN-ATTRIBUTES missing in 420");
|
||||||
|
ret = -3;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
for (u16 = 0; u16 < pc_attr->u_data_size; u16+=2) {
|
||||||
|
switch (*((uint16_t*)&pc_attr->p_data_ptr[u16])) {
|
||||||
|
case tnet_stun_attr_type_dont_fragment: {
|
||||||
|
p_self->opt.dontfrag = 0;
|
||||||
|
b_done = tsk_true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case tnet_stun_attr_type_fingerprint: {
|
||||||
|
p_self->opt.fingerprint = 0;
|
||||||
|
b_done = tsk_true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b_done) {
|
||||||
|
// TRANSACTION-ID
|
||||||
|
if ((ret = tnet_stun_utils_transac_id_rand(&p_self->transac_id))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bail:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static tsk_object_t* tnet_stun_pkt_ctor(tsk_object_t * self, va_list * app)
|
static tsk_object_t* tnet_stun_pkt_ctor(tsk_object_t * self, va_list * app)
|
||||||
{
|
{
|
||||||
tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
|
tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
|
||||||
|
@ -634,7 +735,9 @@ static tsk_object_t* tnet_stun_pkt_dtor(tsk_object_t * self)
|
||||||
{
|
{
|
||||||
tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
|
tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
|
||||||
if (p_pkt) {
|
if (p_pkt) {
|
||||||
|
#if PRINT_DESTROYED_MSG
|
||||||
TSK_DEBUG_INFO("*** STUN pkt destroyed ***");
|
TSK_DEBUG_INFO("*** STUN pkt destroyed ***");
|
||||||
|
#endif
|
||||||
TSK_OBJECT_SAFE_FREE(p_pkt->p_list_attrs);
|
TSK_OBJECT_SAFE_FREE(p_pkt->p_list_attrs);
|
||||||
TSK_FREE(p_pkt->p_pwd);
|
TSK_FREE(p_pkt->p_pwd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "tsk_object.h"
|
#include "tsk_object.h"
|
||||||
#include "tsk_list.h"
|
#include "tsk_list.h"
|
||||||
|
#include "tsk_buffer.h"
|
||||||
|
|
||||||
TNET_BEGIN_DECLS
|
TNET_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ TNET_BEGIN_DECLS
|
||||||
* Checks whether the STUN message is an error response or not.
|
* Checks whether the STUN message is an error response or not.
|
||||||
*/
|
*/
|
||||||
#define TNET_STUN_PKT_IS_REQ(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_request))
|
#define TNET_STUN_PKT_IS_REQ(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_request))
|
||||||
#define TNET_STUN_PKT_IS_RESP(p_self) (TNET_STUN_PKT_RESP_IS_SUCCESS((p_self)) || TNET_STUN_PKT_RESP_IS_ERROR((self)))
|
#define TNET_STUN_PKT_IS_RESP(p_self) (TNET_STUN_PKT_RESP_IS_SUCCESS((p_self)) || TNET_STUN_PKT_RESP_IS_ERROR((p_self)))
|
||||||
#define TNET_STUN_PKT_IS_INDICATION(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_indication))
|
#define TNET_STUN_PKT_IS_INDICATION(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_indication))
|
||||||
#define TNET_STUN_PKT_RESP_IS_SUCCESS(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_success))
|
#define TNET_STUN_PKT_RESP_IS_SUCCESS(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_success))
|
||||||
#define TNET_STUN_PKT_RESP_IS_ERROR(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_error))
|
#define TNET_STUN_PKT_RESP_IS_ERROR(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_error))
|
||||||
|
@ -63,7 +64,7 @@ tnet_stun_pkt_attr_add_t;
|
||||||
|
|
||||||
#define TNET_STUN_PKT_ATTR_ADD_NULL() tnet_stun_pkt_attr_add_null
|
#define TNET_STUN_PKT_ATTR_ADD_NULL() tnet_stun_pkt_attr_add_null
|
||||||
#define TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, P_DATA_PTR, U_DATA_SIZE) tnet_stun_pkt_attr_add_vdata, (enum tnet_stun_attr_type_e)(E_TYPE), (const uint8_t*)(P_DATA_PTR), (uint16_t)(U_DATA_SIZE)
|
#define TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, P_DATA_PTR, U_DATA_SIZE) tnet_stun_pkt_attr_add_vdata, (enum tnet_stun_attr_type_e)(E_TYPE), (const uint8_t*)(P_DATA_PTR), (uint16_t)(U_DATA_SIZE)
|
||||||
#define TNET_STUN_PKT_ATTR_ADD_UINT0(E_TYPE) TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, 0, 0)
|
#define TNET_STUN_PKT_ATTR_ADD_UINT0(E_TYPE) TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, tsk_null, 0)
|
||||||
#define TNET_STUN_PKT_ATTR_ADD_UINT8(E_TYPE, U8) TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, &U8, 1)
|
#define TNET_STUN_PKT_ATTR_ADD_UINT8(E_TYPE, U8) TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, &U8, 1)
|
||||||
#define TNET_STUN_PKT_ATTR_ADD_UINT16(E_TYPE, U16) TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, &U16, 2)
|
#define TNET_STUN_PKT_ATTR_ADD_UINT16(E_TYPE, U16) TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, &U16, 2)
|
||||||
#define TNET_STUN_PKT_ATTR_ADD_UINT32(E_TYPE, U32) TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, &U32, 4)
|
#define TNET_STUN_PKT_ATTR_ADD_UINT32(E_TYPE, U32) TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, &U32, 4)
|
||||||
|
@ -128,7 +129,14 @@ tnet_stun_pkt_attr_add_t;
|
||||||
// rfc5766(TURN) - 14.8. DONT-FRAGMENT
|
// rfc5766(TURN) - 14.8. DONT-FRAGMENT
|
||||||
#define TNET_STUN_PKT_ATTR_ADD_DONT_FRAGMENT() TNET_STUN_PKT_ATTR_ADD_UINT0(tnet_stun_attr_type_dont_fragment)
|
#define TNET_STUN_PKT_ATTR_ADD_DONT_FRAGMENT() TNET_STUN_PKT_ATTR_ADD_UINT0(tnet_stun_attr_type_dont_fragment)
|
||||||
|
|
||||||
|
// rfc5245(ICE) - 19.1. New Attributes (PRIORITY)
|
||||||
|
#define TNET_STUN_PKT_ATTR_ADD_ICE_PRIORITY(U32_PRIORITY) TNET_STUN_PKT_ATTR_ADD_UINT32(tnet_stun_attr_type_ice_priority, U32_PRIORITY)
|
||||||
|
// rfc5245(ICE) - 19.1. New Attributes (USE-CANDIDATE)
|
||||||
|
#define TNET_STUN_PKT_ATTR_ADD_ICE_USE_CANDIDATE() TNET_STUN_PKT_ATTR_ADD_UINT0(tnet_stun_attr_type_ice_use_candidate)
|
||||||
|
// rfc5245(ICE) - 19.1. New Attributes (ICE-CONTROLLED)
|
||||||
|
#define TNET_STUN_PKT_ATTR_ADD_ICE_CONTROLLED(U64_CONTROLLED) TNET_STUN_PKT_ATTR_ADD_UINT64(tnet_stun_attr_type_ice_controlled, U64_CONTROLLED)
|
||||||
|
// rfc5245(ICE) - 19.1. New Attributes (ICE-CONTROLLED)
|
||||||
|
#define TNET_STUN_PKT_ATTR_ADD_ICE_CONTROLLING(U64_CONTROLLING) TNET_STUN_PKT_ATTR_ADD_UINT64(tnet_stun_attr_type_ice_controlling, U64_CONTROLLING)
|
||||||
|
|
||||||
typedef struct tnet_stun_pkt_s {
|
typedef struct tnet_stun_pkt_s {
|
||||||
TSK_DECLARE_OBJECT;
|
TSK_DECLARE_OBJECT;
|
||||||
|
@ -152,18 +160,24 @@ TINYNET_API int tnet_stun_pkt_create(enum tnet_stun_pkt_type_e e_type, uint16_t
|
||||||
#define tnet_stun_pkt_create_empty(e_type, pp_attr) tnet_stun_pkt_create((e_type), 0, tsk_null, (pp_attr))
|
#define tnet_stun_pkt_create_empty(e_type, pp_attr) tnet_stun_pkt_create((e_type), 0, tsk_null, (pp_attr))
|
||||||
TINYNET_API int tnet_stun_pkt_attr_add(struct tnet_stun_pkt_s* p_self, struct tnet_stun_attr_s** pp_attr);
|
TINYNET_API int tnet_stun_pkt_attr_add(struct tnet_stun_pkt_s* p_self, struct tnet_stun_attr_s** pp_attr);
|
||||||
TINYNET_API int tnet_stun_pkt_attrs_add(struct tnet_stun_pkt_s* p_self, ...);
|
TINYNET_API int tnet_stun_pkt_attrs_add(struct tnet_stun_pkt_s* p_self, ...);
|
||||||
|
TINYNET_API int tnet_stun_pkt_attr_remove(struct tnet_stun_pkt_s* p_self, enum tnet_stun_attr_type_e e_type);
|
||||||
TINYNET_API int tnet_stun_pkt_attr_find(const struct tnet_stun_pkt_s* pc_self, enum tnet_stun_attr_type_e e_type, tsk_size_t u_index, const struct tnet_stun_attr_s** ppc_attr);
|
TINYNET_API int tnet_stun_pkt_attr_find(const struct tnet_stun_pkt_s* pc_self, enum tnet_stun_attr_type_e e_type, tsk_size_t u_index, const struct tnet_stun_attr_s** ppc_attr);
|
||||||
#define tnet_stun_pkt_attr_find_first(pc_self, e_type, ppc_attr) tnet_stun_pkt_attr_find((pc_self), (e_type), 0, (ppc_attr))
|
#define tnet_stun_pkt_attr_find_first(pc_self, e_type, ppc_attr) tnet_stun_pkt_attr_find((pc_self), (e_type), 0, (ppc_attr))
|
||||||
TINYNET_API tsk_bool_t tnet_stun_pkt_attr_exists(const struct tnet_stun_pkt_s* pc_self, enum tnet_stun_attr_type_e e_type);
|
TINYNET_API tsk_bool_t tnet_stun_pkt_attr_exists(const struct tnet_stun_pkt_s* pc_self, enum tnet_stun_attr_type_e e_type);
|
||||||
TINYNET_API int tnet_stun_pkt_get_size_in_octetunits_without_padding(const struct tnet_stun_pkt_s* pc_self, tsk_size_t* p_size);
|
TINYNET_API int tnet_stun_pkt_get_size_in_octetunits_without_padding(const struct tnet_stun_pkt_s* pc_self, tsk_size_t* p_size);
|
||||||
TINYNET_API int tnet_stun_pkt_get_size_in_octetunits_with_padding(const struct tnet_stun_pkt_s* pc_self, tsk_size_t* p_size);
|
TINYNET_API int tnet_stun_pkt_get_size_in_octetunits_with_padding(const struct tnet_stun_pkt_s* pc_self, tsk_size_t* p_size);
|
||||||
TINYNET_API int tnet_stun_pkt_write_with_padding(const struct tnet_stun_pkt_s* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written);
|
TINYNET_API int tnet_stun_pkt_write_with_padding(const struct tnet_stun_pkt_s* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written);
|
||||||
|
TINYNET_API int tnet_stun_pkt_write_with_padding_2(const struct tnet_stun_pkt_s* pc_self, struct tsk_buffer_s** pp_buff);
|
||||||
TINYNET_API int tnet_stun_pkt_is_complete(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_bool_t *pb_is_complete);
|
TINYNET_API int tnet_stun_pkt_is_complete(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_bool_t *pb_is_complete);
|
||||||
TINYNET_API int tnet_stun_pkt_read(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, struct tnet_stun_pkt_s** pp_pkt);
|
TINYNET_API int tnet_stun_pkt_read(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, struct tnet_stun_pkt_s** pp_pkt);
|
||||||
TINYNET_API int tnet_stun_pkt_auth_prepare(struct tnet_stun_pkt_s* p_self, const char* pc_usr_name, const char* pc_pwd, const char* pc_realm, const char* pc_nonce);
|
TINYNET_API int tnet_stun_pkt_auth_prepare(struct tnet_stun_pkt_s* p_self, const char* pc_usr_name, const char* pc_pwd, const char* pc_realm, const char* pc_nonce);
|
||||||
|
#define tnet_stun_pkt_auth_prepare_longterm(p_self, pc_usr_name, pc_pwd, pc_realm, pc_nonce) tnet_stun_pkt_auth_prepare((p_self), (pc_usr_name), (pc_pwd), (pc_realm), (pc_nonce))
|
||||||
|
#define tnet_stun_pkt_auth_prepare_shortterm(p_self, pc_usr_name, pc_pwd) tnet_stun_pkt_auth_prepare((p_self), (pc_usr_name), (pc_pwd), tsk_null, tsk_null)
|
||||||
|
#define tnet_stun_pkt_auth_prepare_shortterm_2(p_self, pc_pwd) tnet_stun_pkt_auth_prepare_shortterm((p_self), tsk_null, (pc_pwd))
|
||||||
TINYNET_API int tnet_stun_pkt_auth_prepare_2(struct tnet_stun_pkt_s* p_self, const char* pc_usr_name, const char* pc_pwd, const struct tnet_stun_pkt_s* pc_resp);
|
TINYNET_API int tnet_stun_pkt_auth_prepare_2(struct tnet_stun_pkt_s* p_self, const char* pc_usr_name, const char* pc_pwd, const struct tnet_stun_pkt_s* pc_resp);
|
||||||
TINYNET_API int tnet_stun_pkt_auth_copy(struct tnet_stun_pkt_s* p_self, const char* pc_usr_name, const char* pc_pwd, const struct tnet_stun_pkt_s* pc_pkt);
|
TINYNET_API int tnet_stun_pkt_auth_copy(struct tnet_stun_pkt_s* p_self, const char* pc_usr_name, const char* pc_pwd, const struct tnet_stun_pkt_s* pc_pkt);
|
||||||
TINYNET_API int tnet_stun_pkt_get_errorcode(const struct tnet_stun_pkt_s* pc_self, uint16_t* pu_code);
|
TINYNET_API int tnet_stun_pkt_get_errorcode(const struct tnet_stun_pkt_s* pc_self, uint16_t* pu_code);
|
||||||
|
TINYNET_API int tnet_stun_pkt_process_err420(struct tnet_stun_pkt_s *p_self, const struct tnet_stun_pkt_s *pc_pkt_resp420);
|
||||||
|
|
||||||
TNET_END_DECLS
|
TNET_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
TNET_BEGIN_DECLS
|
TNET_BEGIN_DECLS
|
||||||
|
|
||||||
typedef uint8_t tnet_stun_addr_t[16]; // IPv4(32bits) or IPv6(128bits)
|
typedef uint8_t tnet_stun_addr_t[16]; // IPv4(32bits) or IPv6(128bits)
|
||||||
|
typedef uint64_t tnet_stun_binding_id_t;
|
||||||
|
typedef long tnet_turn_peer_id_t;
|
||||||
|
|
||||||
/**@ingroup tnet_stun_group
|
/**@ingroup tnet_stun_group
|
||||||
* Checks if the pointer to the buffer hold a STUN header by checking that it starts with 0b00 and contain the magic cookie.
|
* Checks if the pointer to the buffer hold a STUN header by checking that it starts with 0b00 and contain the magic cookie.
|
||||||
|
@ -34,7 +36,7 @@ typedef uint8_t tnet_stun_addr_t[16]; // IPv4(32bits) or IPv6(128bits)
|
||||||
*
|
*
|
||||||
* @param PU8 The pointer to the buffer holding the STUN raw data.
|
* @param PU8 The pointer to the buffer holding the STUN raw data.
|
||||||
**/
|
**/
|
||||||
#define TNET_STUN_PKT_IS_STUN2(PU8, SIZE) \
|
#define TNET_STUN_BUFF_IS_STUN2(PU8, SIZE) \
|
||||||
( \
|
( \
|
||||||
((PU8)) && \
|
((PU8)) && \
|
||||||
((SIZE) >= kStunPktHdrSizeInOctets) && \
|
((SIZE) >= kStunPktHdrSizeInOctets) && \
|
||||||
|
@ -43,7 +45,7 @@ typedef uint8_t tnet_stun_addr_t[16]; // IPv4(32bits) or IPv6(128bits)
|
||||||
)
|
)
|
||||||
|
|
||||||
// rfc5766 - 11. Channels
|
// rfc5766 - 11. Channels
|
||||||
#define TNET_STUN_PKT_IS_CHANNEL_DATA(PU8, SIZE) \
|
#define TNET_STUN_BUFF_IS_CHANNEL_DATA(PU8, SIZE) \
|
||||||
( \
|
( \
|
||||||
((PU8)) && \
|
((PU8)) && \
|
||||||
((SIZE) >= kStunChannelDataHdrSizeInOctets) && \
|
((SIZE) >= kStunChannelDataHdrSizeInOctets) && \
|
||||||
|
@ -58,6 +60,15 @@ typedef uint8_t tnet_stun_addr_t[16]; // IPv4(32bits) or IPv6(128bits)
|
||||||
#define kStunErrCodeStaleNonce 438
|
#define kStunErrCodeStaleNonce 438
|
||||||
#define kStunErrCodeIceConflict 487
|
#define kStunErrCodeIceConflict 487
|
||||||
|
|
||||||
|
// Estimate of the round-trip time (RTT) in millisecond.
|
||||||
|
#define kStunRTO 500
|
||||||
|
|
||||||
|
// Number of retransmission for UDP retransmission in millisecond.
|
||||||
|
// 7.2.1. Sending over UDP
|
||||||
|
// Rc SHOULD be configurable and SHOULD have a default of 7.
|
||||||
|
#define kStunRC /*7*/4/* 7 is too hight */
|
||||||
|
|
||||||
|
#define kStunBindingInvalidId 0
|
||||||
|
|
||||||
#if !defined(kStunBuffMinPad)
|
#if !defined(kStunBuffMinPad)
|
||||||
# define kStunBuffMinPad 40 // to make the buffer kasher
|
# define kStunBuffMinPad 40 // to make the buffer kasher
|
||||||
|
@ -324,6 +335,14 @@ tnet_stun_pkt_type_t;
|
||||||
# define kStunChannelDataHdrSizeInOctets 4
|
# define kStunChannelDataHdrSizeInOctets 4
|
||||||
#endif /* kStunChannelDataHdrSizeInOctets */
|
#endif /* kStunChannelDataHdrSizeInOctets */
|
||||||
|
|
||||||
|
// Not part of the standard
|
||||||
|
typedef enum tnet_stun_state_e {
|
||||||
|
tnet_stun_state_none,
|
||||||
|
tnet_stun_state_trying,
|
||||||
|
tnet_stun_state_ok,
|
||||||
|
tnet_stun_state_nok
|
||||||
|
} tnet_stun_state_t;
|
||||||
|
|
||||||
TNET_END_DECLS
|
TNET_END_DECLS
|
||||||
|
|
||||||
#endif /* TNET_STUN_TYPES_H */
|
#endif /* TNET_STUN_TYPES_H */
|
||||||
|
|
|
@ -17,9 +17,12 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "stun/tnet_stun_utils.h"
|
#include "stun/tnet_stun_utils.h"
|
||||||
|
#include "stun/tnet_stun_pkt.h"
|
||||||
|
#include "stun/tnet_stun_attr.h"
|
||||||
|
|
||||||
#include "tnet_utils.h"
|
#include "tnet_utils.h"
|
||||||
|
|
||||||
|
#include "tsk_memory.h"
|
||||||
#include "tsk_debug.h"
|
#include "tsk_debug.h"
|
||||||
|
|
||||||
int tnet_stun_utils_inet_pton(tsk_bool_t b_v6, const char* p_src, tnet_stun_addr_t* p_dst)
|
int tnet_stun_utils_inet_pton(tsk_bool_t b_v6, const char* p_src, tnet_stun_addr_t* p_dst)
|
||||||
|
@ -84,3 +87,115 @@ int tnet_stun_utils_buff_cmp(const uint8_t* pc_buf1_ptr, tsk_size_t n_buff1_size
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tnet_stun_utils_send_unreliably(tnet_fd_t localFD, uint16_t RTO, uint16_t Rc, const struct tnet_stun_pkt_s* pc_stun_req, struct sockaddr* p_addr_server, struct tnet_stun_pkt_s** pp_stun_resp)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
uint16_t i, rto = RTO;
|
||||||
|
struct timeval tv;
|
||||||
|
fd_set set;
|
||||||
|
void* p_buff_ptr = tsk_null;
|
||||||
|
tsk_size_t u_buff_size;
|
||||||
|
|
||||||
|
if (!pc_stun_req || !p_addr_server || !pp_stun_resp) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* RFC 5389 - 7.2.1. Sending over UDP
|
||||||
|
STUN indications are not retransmitted; thus, indication transactions over UDP
|
||||||
|
are not reliable.
|
||||||
|
*/
|
||||||
|
*pp_stun_resp = tsk_null;
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_stun_req, &u_buff_size))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
u_buff_size += kStunBuffMinPad;
|
||||||
|
if (!(p_buff_ptr = tsk_malloc(u_buff_size))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if ((ret = tnet_stun_pkt_write_with_padding(pc_stun_req, p_buff_ptr, u_buff_size, &u_buff_size))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RFC 5389 - 7.2.1. Sending over UDP
|
||||||
|
A client SHOULD retransmit a STUN request message starting with an
|
||||||
|
interval of RTO ("Retransmission TimeOut"), doubling after each
|
||||||
|
retransmission.
|
||||||
|
|
||||||
|
e.g. 0 ms, 500 ms, 1500 ms, 3500 ms, 7500ms, 15500 ms, and 31500 ms
|
||||||
|
*/
|
||||||
|
for (i = 0; i < Rc; i++) {
|
||||||
|
tv.tv_sec += rto/1000;
|
||||||
|
tv.tv_usec += (rto% 1000) * 1000;
|
||||||
|
if (tv.tv_usec >= 1000000) {
|
||||||
|
tv.tv_usec -= 1000000;
|
||||||
|
tv.tv_sec++;
|
||||||
|
}
|
||||||
|
|
||||||
|
FD_ZERO(&set);
|
||||||
|
FD_SET(localFD, &set);
|
||||||
|
|
||||||
|
if ((ret = tnet_sockfd_sendto(localFD, p_addr_server, p_buff_ptr, u_buff_size))) {
|
||||||
|
// do nothing... not an error
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = select(localFD+1, &set, NULL, NULL, &tv)) < 0) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
else if (ret == 0) {
|
||||||
|
/* timeout */
|
||||||
|
TSK_DEBUG_INFO("STUN request timedout at %d", i);
|
||||||
|
rto *= 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (FD_ISSET(localFD, &set)) {
|
||||||
|
/* there is data to read */
|
||||||
|
|
||||||
|
tsk_size_t len = 0;
|
||||||
|
void* data = 0;
|
||||||
|
|
||||||
|
TSK_DEBUG_INFO("STUN request got response");
|
||||||
|
|
||||||
|
/* Check how how many bytes are pending */
|
||||||
|
if ((ret = tnet_ioctlt(localFD, FIONREAD, &len)) < 0) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(len == 0) {
|
||||||
|
TSK_DEBUG_INFO("tnet_ioctlt() returent zero bytes");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Receive pending data */
|
||||||
|
data = tsk_malloc(len);
|
||||||
|
if ((ret = tnet_sockfd_recvfrom(localFD, data, len, 0, p_addr_server)) < 0) {
|
||||||
|
TSK_FREE(data);
|
||||||
|
|
||||||
|
TSK_DEBUG_ERROR("Recv STUN dgrams failed with error code:%d", tnet_geterrno());
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse the incoming response. */
|
||||||
|
ret = tnet_stun_pkt_read(data, (tsk_size_t)ret, pp_stun_resp);
|
||||||
|
TSK_FREE(data);
|
||||||
|
if (*pp_stun_resp) {
|
||||||
|
if (tnet_stun_utils_transac_id_cmp((*pp_stun_resp)->transac_id, pc_stun_req->transac_id) != 0) {
|
||||||
|
/* Not same transaction id */
|
||||||
|
TSK_OBJECT_SAFE_FREE(*pp_stun_resp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bail:
|
||||||
|
TSK_FREE(p_buff_ptr);
|
||||||
|
return (*pp_stun_resp) ? 0 : -4;
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
|
|
||||||
#include "tnet_types.h"
|
#include "tnet_types.h"
|
||||||
|
|
||||||
|
struct tnet_stun_pkt_s;
|
||||||
|
|
||||||
TNET_BEGIN_DECLS
|
TNET_BEGIN_DECLS
|
||||||
|
|
||||||
TINYNET_API int tnet_stun_utils_inet_pton(tsk_bool_t b_v6, const char* p_src, tnet_stun_addr_t* p_dst);
|
TINYNET_API int tnet_stun_utils_inet_pton(tsk_bool_t b_v6, const char* p_src, tnet_stun_addr_t* p_dst);
|
||||||
|
@ -35,7 +37,8 @@ TINYNET_API int tnet_stun_utils_inet_ntop(tsk_bool_t b_v6, const tnet_stun_addr_
|
||||||
TINYNET_API int tnet_stun_utils_transac_id_rand(tnet_stun_transac_id_t* p_transac_id);
|
TINYNET_API int tnet_stun_utils_transac_id_rand(tnet_stun_transac_id_t* p_transac_id);
|
||||||
TINYNET_API int tnet_stun_utils_buff_cmp(const uint8_t* pc_buf1_ptr, tsk_size_t n_buff1_size, const uint8_t* pc_buf2_ptr, tsk_size_t n_buff2_size);
|
TINYNET_API int tnet_stun_utils_buff_cmp(const uint8_t* pc_buf1_ptr, tsk_size_t n_buff1_size, const uint8_t* pc_buf2_ptr, tsk_size_t n_buff2_size);
|
||||||
#define tnet_stun_utils_transac_id_cmp(pc_tid1, pc_tid2) tnet_stun_utils_buff_cmp((pc_tid1), sizeof(tnet_stun_transac_id_t), (pc_tid2), sizeof(tnet_stun_transac_id_t))
|
#define tnet_stun_utils_transac_id_cmp(pc_tid1, pc_tid2) tnet_stun_utils_buff_cmp((pc_tid1), sizeof(tnet_stun_transac_id_t), (pc_tid2), sizeof(tnet_stun_transac_id_t))
|
||||||
|
#define tnet_stun_utils_transac_id_equals(pc_tid1, pc_tid2) (tnet_stun_utils_transac_id_cmp((pc_tid1), (pc_tid2)) == 0)
|
||||||
|
int tnet_stun_utils_send_unreliably(tnet_fd_t localFD, uint16_t RTO, uint16_t Rc, const struct tnet_stun_pkt_s* pc_stun_req, struct sockaddr* p_addr_server, struct tnet_stun_pkt_s** pp_stun_resp);
|
||||||
|
|
||||||
TNET_END_DECLS
|
TNET_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Used in TURN/STUN2 attributes. */
|
/* Used in TURN/STUN2 attributes. */
|
||||||
#define TNET_SOFTWARE "IM-client/OMA1.0 doubango/v0.0.0"
|
#define TNET_SOFTWARE "IM-client/OMA1.0 doubango/v2.0.0"
|
||||||
#define TNET_IANA_PEN 35368 /**< PEN number assigned by the IANA.
|
#define TNET_IANA_PEN 35368 /**< PEN number assigned by the IANA.
|
||||||
The list of assigned numbers could be found here http://www.iana.org/assignments/enterprise-numbers. */
|
The list of assigned numbers could be found here http://www.iana.org/assignments/enterprise-numbers. */
|
||||||
#define TNET_RESOLV_CONF_PATH "/etc/resolv.conf" /**< Path to "/resolv.conf". */
|
#define TNET_RESOLV_CONF_PATH "/etc/resolv.conf" /**< Path to "/resolv.conf". */
|
||||||
|
|
|
@ -41,8 +41,15 @@ typedef struct tnet_dtls_socket_s
|
||||||
tsk_bool_t use_srtp;
|
tsk_bool_t use_srtp;
|
||||||
tsk_bool_t handshake_completed;
|
tsk_bool_t handshake_completed;
|
||||||
tsk_bool_t handshake_started;
|
tsk_bool_t handshake_started;
|
||||||
|
tsk_bool_t handshake_storedata; // whether to store handshaking data or to send it to the remote party
|
||||||
tnet_dtls_setup_t setup;
|
tnet_dtls_setup_t setup;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
void* ptr;
|
||||||
|
tsk_size_t size;
|
||||||
|
tsk_size_t count;
|
||||||
|
} handshake_data;
|
||||||
|
|
||||||
struct{
|
struct{
|
||||||
const void* usrdata;
|
const void* usrdata;
|
||||||
tnet_dtls_socket_cb_f func;
|
tnet_dtls_socket_cb_f func;
|
||||||
|
@ -108,10 +115,13 @@ static int _tnet_dtls_verify_cert(int preverify_ok, X509_STORE_CTX *ctx)
|
||||||
TSK_DEBUG_ERROR("Not expected");
|
TSK_DEBUG_ERROR("Not expected");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(_tnet_dtls_is_fingerprint_matching(ctx->cert, &socket->remote.fp, socket->remote.hash) == tsk_false){
|
tsk_safeobj_lock(socket);
|
||||||
|
if (_tnet_dtls_is_fingerprint_matching(ctx->cert, &socket->remote.fp, socket->remote.hash) == tsk_false) {
|
||||||
TSK_DEBUG_ERROR("Failed to match fingerprint");
|
TSK_DEBUG_ERROR("Failed to match fingerprint");
|
||||||
|
tsk_safeobj_unlock(socket);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
tsk_safeobj_unlock(socket);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,6 +333,10 @@ tnet_dtls_socket_handle_t* tnet_dtls_socket_create(tnet_fd_t fd, struct ssl_ctx_
|
||||||
socket->verify_peer = tsk_true;
|
socket->verify_peer = tsk_true;
|
||||||
SSL_set_verify(socket->ssl, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), _tnet_dtls_verify_cert);
|
SSL_set_verify(socket->ssl, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), _tnet_dtls_verify_cert);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// FIXME:
|
||||||
|
TSK_DEBUG_ERROR("????");
|
||||||
|
}
|
||||||
|
|
||||||
SSL_set_app_data(socket->ssl, socket);
|
SSL_set_app_data(socket->ssl, socket);
|
||||||
}
|
}
|
||||||
|
@ -425,6 +439,27 @@ int tnet_dtls_socket_set_setup(tnet_dtls_socket_handle_t* handle, tnet_dtls_setu
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tnet_dtls_socket_set_store_handshakingdata(tnet_dtls_socket_handle_t* handle, tsk_bool_t handshake_storedata)
|
||||||
|
{
|
||||||
|
if (!handle) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
((tnet_dtls_socket_t*)handle)->handshake_storedata = handshake_storedata;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tnet_dtls_socket_get_handshakingdata(tnet_dtls_socket_handle_t* handle, const void** data, tsk_size_t *size)
|
||||||
|
{
|
||||||
|
if (!handle || !data || !size) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*data = ((tnet_dtls_socket_t*)handle)->handshake_data.ptr;
|
||||||
|
*size = ((tnet_dtls_socket_t*)handle)->handshake_data.count;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
tsk_bool_t tnet_dtls_socket_is_remote_cert_fp_match(tnet_dtls_socket_handle_t* handle)
|
tsk_bool_t tnet_dtls_socket_is_remote_cert_fp_match(tnet_dtls_socket_handle_t* handle)
|
||||||
{
|
{
|
||||||
#if !HAVE_OPENSSL || !HAVE_OPENSSL_DTLS
|
#if !HAVE_OPENSSL || !HAVE_OPENSSL_DTLS
|
||||||
|
@ -443,27 +478,30 @@ int tnet_dtls_socket_do_handshake(tnet_dtls_socket_handle_t* handle, const struc
|
||||||
|
|
||||||
#else
|
#else
|
||||||
tnet_dtls_socket_t *socket = handle;
|
tnet_dtls_socket_t *socket = handle;
|
||||||
int ret, len;
|
int ret = 0, len;
|
||||||
void* out_data;
|
void* out_data;
|
||||||
|
|
||||||
if(!socket){
|
if (!socket) {
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tsk_safeobj_lock(socket);
|
||||||
|
|
||||||
// update remote address even if handshaking is completed
|
// update remote address even if handshaking is completed
|
||||||
if(remote_addr){
|
if (remote_addr) {
|
||||||
socket->remote.addr = *remote_addr;
|
socket->remote.addr = *remote_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(socket->handshake_completed){
|
if (socket->handshake_completed) {
|
||||||
TSK_DEBUG_INFO("Handshake completed");
|
TSK_DEBUG_INFO("Handshake completed");
|
||||||
return 0;
|
ret = 0;
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!socket->handshake_started) {
|
if (!socket->handshake_started) {
|
||||||
if((ret = SSL_do_handshake(socket->ssl)) != 1){
|
if ((ret = SSL_do_handshake(socket->ssl)) != 1) {
|
||||||
switch((ret = SSL_get_error(socket->ssl, ret))){
|
switch ((ret = SSL_get_error(socket->ssl, ret))) {
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
case SSL_ERROR_NONE:
|
case SSL_ERROR_NONE:
|
||||||
|
@ -471,43 +509,41 @@ int tnet_dtls_socket_do_handshake(tnet_dtls_socket_handle_t* handle, const struc
|
||||||
default:
|
default:
|
||||||
TSK_DEBUG_ERROR("DTLS handshake failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
|
TSK_DEBUG_ERROR("DTLS handshake failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
|
||||||
_tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_handshake_failed);
|
_tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_handshake_failed);
|
||||||
return -2;
|
ret = -2;
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
socket->handshake_started = (ret == SSL_ERROR_NONE); // TODO: reset for renegotiation
|
socket->handshake_started = (ret == SSL_ERROR_NONE); // TODO: reset for renegotiation
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
if ((len = BIO_get_mem_data(socket->wbio, &out_data)) > 0 && out_data) {
|
||||||
len = BIO_ctrl_pending(socket->wbio);
|
if (socket->handshake_storedata) {
|
||||||
if (len > 0) {
|
if ((int)socket->handshake_data.size < len) {
|
||||||
tnet_port_t port;
|
if (!(socket->handshake_data.ptr = tsk_realloc(socket->handshake_data.ptr, len))) {
|
||||||
tnet_ip_t ip;
|
socket->handshake_data.size = 0;
|
||||||
out_data = malloc(len);
|
socket->handshake_data.count = 0;
|
||||||
len = BIO_read(socket->wbio, out_data, len);
|
ret = -5;
|
||||||
|
goto bail;
|
||||||
tnet_get_sockip_n_port((const struct sockaddr *)&socket->remote.addr, &ip, &port);
|
|
||||||
TSK_DEBUG_INFO("DTLS data handshake to send with len = %d, ip = %.*s and port = %d", len, sizeof(ip), ip, port);
|
|
||||||
len = tnet_sockfd_sendto(socket->fd, (const struct sockaddr *)&socket->remote.addr, out_data, len);
|
|
||||||
TSK_DEBUG_INFO("DTLS data handshake sent len = %d", len);
|
|
||||||
free(out_data);
|
|
||||||
}
|
}
|
||||||
#else
|
socket->handshake_data.size = len;
|
||||||
|
}
|
||||||
if((len = BIO_get_mem_data(socket->wbio, &out_data)) && out_data){
|
socket->handshake_data.count = len;
|
||||||
|
memcpy(socket->handshake_data.ptr, out_data, len);
|
||||||
|
}
|
||||||
|
else {
|
||||||
tnet_port_t port;
|
tnet_port_t port;
|
||||||
tnet_ip_t ip;
|
tnet_ip_t ip;
|
||||||
tnet_get_sockip_n_port((const struct sockaddr *)&socket->remote.addr, &ip, &port);
|
tnet_get_sockip_n_port((const struct sockaddr *)&socket->remote.addr, &ip, &port);
|
||||||
TSK_DEBUG_INFO("DTLS data handshake to send with len = %d, ip = %.*s and port = %d", len, sizeof(ip), ip, port);
|
TSK_DEBUG_INFO("DTLS data handshake to send with len = %d, ip = %.*s and port = %d", len, sizeof(ip), ip, port);
|
||||||
len = tnet_sockfd_sendto(socket->fd, (const struct sockaddr *)&socket->remote.addr, out_data, len);
|
len = tnet_sockfd_sendto(socket->fd, (const struct sockaddr *)&socket->remote.addr, out_data, len);
|
||||||
TSK_DEBUG_INFO("DTLS data handshake sent len = %d", len);
|
TSK_DEBUG_INFO("DTLS data handshake sent len = %d", len);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
BIO_reset(socket->rbio);
|
BIO_reset(socket->rbio);
|
||||||
BIO_reset(socket->wbio);
|
BIO_reset(socket->wbio);
|
||||||
|
|
||||||
if((socket->handshake_completed = SSL_is_init_finished(socket->ssl))){
|
if ((socket->handshake_completed = SSL_is_init_finished(socket->ssl))) {
|
||||||
TSK_DEBUG_INFO("DTLS handshake completed");
|
TSK_DEBUG_INFO("DTLS handshake completed");
|
||||||
|
|
||||||
#if HAVE_OPENSSL_DTLS_SRTP
|
#if HAVE_OPENSSL_DTLS_SRTP
|
||||||
|
@ -525,9 +561,10 @@ int tnet_dtls_socket_do_handshake(tnet_dtls_socket_handle_t* handle, const struc
|
||||||
static const tsk_size_t keying_material_size = sizeof(keying_material);
|
static const tsk_size_t keying_material_size = sizeof(keying_material);
|
||||||
/*if(socket->use_srtp)*/{
|
/*if(socket->use_srtp)*/{
|
||||||
SRTP_PROTECTION_PROFILE *p = SSL_get_selected_srtp_profile(socket->ssl);
|
SRTP_PROTECTION_PROFILE *p = SSL_get_selected_srtp_profile(socket->ssl);
|
||||||
if(!p){
|
if (!p) {
|
||||||
TSK_DEBUG_ERROR("SSL_get_selected_srtp_profile() returned null [%s]", ERR_error_string(ERR_get_error(), tsk_null));
|
TSK_DEBUG_ERROR("SSL_get_selected_srtp_profile() returned null [%s]", ERR_error_string(ERR_get_error(), tsk_null));
|
||||||
return -2;
|
ret = -2;
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
// alert user
|
// alert user
|
||||||
_tnet_dtls_socket_raise_event(socket, tnet_dtls_socket_event_type_dtls_srtp_profile_selected, p->name, tsk_strlen(p->name));
|
_tnet_dtls_socket_raise_event(socket, tnet_dtls_socket_event_type_dtls_srtp_profile_selected, p->name, tsk_strlen(p->name));
|
||||||
|
@ -536,11 +573,12 @@ int tnet_dtls_socket_do_handshake(tnet_dtls_socket_handle_t* handle, const struc
|
||||||
|
|
||||||
// rfc5764 - 4.2. Key Derivation
|
// rfc5764 - 4.2. Key Derivation
|
||||||
ret = SSL_export_keying_material(socket->ssl, keying_material, sizeof(keying_material), EXTRACTOR_dtls_srtp_text, EXTRACTOR_dtls_srtp_text_len, tsk_null, 0, 0);
|
ret = SSL_export_keying_material(socket->ssl, keying_material, sizeof(keying_material), EXTRACTOR_dtls_srtp_text, EXTRACTOR_dtls_srtp_text_len, tsk_null, 0, 0);
|
||||||
if(ret != 1){
|
if (ret != 1) {
|
||||||
// alert listener
|
// alert listener
|
||||||
_tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_error);
|
_tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_error);
|
||||||
TSK_DEBUG_ERROR("SSL_export_keying_material() failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
|
TSK_DEBUG_ERROR("SSL_export_keying_material() failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
|
||||||
return -2;
|
ret = -2;
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// alert listener
|
// alert listener
|
||||||
|
@ -549,8 +587,10 @@ int tnet_dtls_socket_do_handshake(tnet_dtls_socket_handle_t* handle, const struc
|
||||||
#endif /* HAVE_OPENSSL_DTLS_SRTP */
|
#endif /* HAVE_OPENSSL_DTLS_SRTP */
|
||||||
_tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_handshake_succeed);
|
_tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_handshake_succeed);
|
||||||
}
|
}
|
||||||
|
ret = 0; // clear "ret", error will directly jump to "bail:"
|
||||||
return 0;
|
bail:
|
||||||
|
tsk_safeobj_unlock(socket);
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,24 +613,35 @@ int tnet_dtls_socket_handle_incoming_data(tnet_dtls_socket_handle_t* handle, con
|
||||||
return -200;
|
return -200;
|
||||||
#else
|
#else
|
||||||
tnet_dtls_socket_t *socket = handle;
|
tnet_dtls_socket_t *socket = handle;
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
if(!socket || !data || !size){
|
if (!socket || !data || !size) {
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tsk_safeobj_lock(socket);
|
||||||
|
|
||||||
TSK_DEBUG_INFO("Receive DTLS data: %u", size);
|
TSK_DEBUG_INFO("Receive DTLS data: %u", size);
|
||||||
|
|
||||||
// BIO_reset(socket->rbio);
|
// BIO_reset(socket->rbio);
|
||||||
// BIO_reset(socket->wbio);
|
// BIO_reset(socket->wbio);
|
||||||
|
|
||||||
ret = _tnet_dtls_socket_do_handshake(socket);
|
if (!socket->rbio || !socket->wbio) {
|
||||||
|
TSK_DEBUG_ERROR("BIO not initialized yet");
|
||||||
|
ret = -2;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
if((ret = BIO_write(socket->rbio, data, size)) != size){
|
if ((ret = _tnet_dtls_socket_do_handshake(socket))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = BIO_write(socket->rbio, data, size)) != size) {
|
||||||
ret = SSL_get_error(socket->ssl, ret);
|
ret = SSL_get_error(socket->ssl, ret);
|
||||||
TSK_DEBUG_ERROR("BIO_write(rbio, %u) failed [%s]", size, ERR_error_string(ERR_get_error(), tsk_null));
|
TSK_DEBUG_ERROR("BIO_write(rbio, %u) failed [%s]", size, ERR_error_string(ERR_get_error(), tsk_null));
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if((ret = SSL_read(socket->ssl, (void*)data, size)) <= 0){
|
/*if((ret = SSL_read(socket->ssl, (void*)data, size)) <= 0){
|
||||||
|
@ -626,7 +677,11 @@ int tnet_dtls_socket_handle_incoming_data(tnet_dtls_socket_handle_t* handle, con
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
return _tnet_dtls_socket_do_handshake(socket);
|
ret = _tnet_dtls_socket_do_handshake(socket);
|
||||||
|
|
||||||
|
bail:
|
||||||
|
tsk_safeobj_unlock(socket);
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,19 +703,22 @@ static tsk_object_t* tnet_dtls_socket_dtor(tsk_object_t * self)
|
||||||
tnet_dtls_socket_t *socket = self;
|
tnet_dtls_socket_t *socket = self;
|
||||||
if(socket){
|
if(socket){
|
||||||
#if HAVE_OPENSSL
|
#if HAVE_OPENSSL
|
||||||
if(socket->rbio){
|
if (socket->rbio) {
|
||||||
//BIO_free(socket->rbio);
|
//BIO_free(socket->rbio);
|
||||||
//socket->rbio = tsk_null;
|
socket->rbio = tsk_null;
|
||||||
}
|
}
|
||||||
if(socket->wbio){
|
if (socket->wbio) {
|
||||||
//BIO_free(socket->wbio);
|
//BIO_free(socket->wbio);
|
||||||
//socket->wbio = tsk_null;
|
socket->wbio = tsk_null;
|
||||||
}
|
}
|
||||||
if(socket->ssl){
|
if (socket->ssl) {
|
||||||
SSL_shutdown(socket->ssl);
|
SSL_shutdown(socket->ssl);
|
||||||
|
// https://www.openssl.org/docs/crypto/BIO_s_bio.html
|
||||||
|
// implicitly frees internal_bio
|
||||||
SSL_free(socket->ssl);
|
SSL_free(socket->ssl);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
TSK_FREE(socket->handshake_data.ptr);
|
||||||
tsk_safeobj_deinit(socket);
|
tsk_safeobj_deinit(socket);
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|
|
@ -57,6 +57,8 @@ TINYNET_API tnet_fd_t tnet_dtls_socket_get_fd(const tnet_dtls_socket_handle_t* h
|
||||||
TINYNET_API const struct sockaddr_storage* tnet_dtls_socket_get_remote_addr(const tnet_dtls_socket_handle_t* handle);
|
TINYNET_API const struct sockaddr_storage* tnet_dtls_socket_get_remote_addr(const tnet_dtls_socket_handle_t* handle);
|
||||||
TINYNET_API int tnet_dtls_socket_set_callback(tnet_dtls_socket_handle_t* handle, const void* usrdata, tnet_dtls_socket_cb_f func);
|
TINYNET_API int tnet_dtls_socket_set_callback(tnet_dtls_socket_handle_t* handle, const void* usrdata, tnet_dtls_socket_cb_f func);
|
||||||
TINYNET_API int tnet_dtls_socket_set_remote_fingerprint(tnet_dtls_socket_handle_t* handle, const tnet_fingerprint_t* fingerprint, tnet_dtls_hash_type_t hash);
|
TINYNET_API int tnet_dtls_socket_set_remote_fingerprint(tnet_dtls_socket_handle_t* handle, const tnet_fingerprint_t* fingerprint, tnet_dtls_hash_type_t hash);
|
||||||
|
TINYNET_API int tnet_dtls_socket_set_store_handshakingdata(tnet_dtls_socket_handle_t* handle, tsk_bool_t handshake_storedata);
|
||||||
|
TINYNET_API int tnet_dtls_socket_get_handshakingdata(tnet_dtls_socket_handle_t* handle, const void** data, tsk_size_t *size);
|
||||||
TINYNET_API int tnet_dtls_socket_use_srtp(tnet_dtls_socket_handle_t* handle);
|
TINYNET_API int tnet_dtls_socket_use_srtp(tnet_dtls_socket_handle_t* handle);
|
||||||
TINYNET_API int tnet_dtls_socket_set_setup(tnet_dtls_socket_handle_t* handle, tnet_dtls_setup_t setup);
|
TINYNET_API int tnet_dtls_socket_set_setup(tnet_dtls_socket_handle_t* handle, tnet_dtls_setup_t setup);
|
||||||
TINYNET_API tsk_bool_t tnet_dtls_socket_is_remote_cert_fp_match(tnet_dtls_socket_handle_t* handle);
|
TINYNET_API tsk_bool_t tnet_dtls_socket_is_remote_cert_fp_match(tnet_dtls_socket_handle_t* handle);
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
* Copyright (C) 2010-2011 Mamadou Diop.
|
||||||
*
|
*
|
||||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
|
||||||
*
|
|
||||||
* This file is part of Open Source Doubango Framework.
|
* This file is part of Open Source Doubango Framework.
|
||||||
*
|
*
|
||||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
|
@ -23,13 +21,16 @@
|
||||||
/**@file tnet_nat.c
|
/**@file tnet_nat.c
|
||||||
* @brief NAT Traversal helper functions using STUN, TURN and ICE.
|
* @brief NAT Traversal helper functions using STUN, TURN and ICE.
|
||||||
*
|
*
|
||||||
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#include "tnet_nat.h"
|
#include "tnet_nat.h"
|
||||||
|
#include "stun/tnet_stun_types.h"
|
||||||
|
#include "stun/tnet_stun_utils.h"
|
||||||
|
#include "stun/tnet_stun_pkt.h"
|
||||||
|
#include "stun/tnet_stun_attr.h"
|
||||||
|
#include "stun/tnet_stun_binding.h"
|
||||||
|
|
||||||
#include "tnet_endianness.h"
|
#include "tnet_endianness.h"
|
||||||
|
#include "tnet_socket.h"
|
||||||
|
|
||||||
#include "tsk_string.h"
|
#include "tsk_string.h"
|
||||||
#include "tsk_memory.h"
|
#include "tsk_memory.h"
|
||||||
|
@ -39,35 +40,56 @@
|
||||||
/**@defgroup tnet_nat_group NAT Traversal API (STUN, TURN and ICE).
|
/**@defgroup tnet_nat_group NAT Traversal API (STUN, TURN and ICE).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef struct tnet_nat_ctx_s
|
||||||
|
{
|
||||||
|
TSK_DECLARE_OBJECT;
|
||||||
|
|
||||||
|
tnet_socket_type_t socket_type;
|
||||||
|
|
||||||
|
char* username; /**< The username to use to authenticate against the TURN/STUN server. */
|
||||||
|
char* password; /**< The password to use to authenticate against the TURN/STUN server. */
|
||||||
|
|
||||||
|
char* server_address; /**< TURN/STUN server address (could be FQDN or IP) */
|
||||||
|
tnet_port_t server_port; /**< TURN/STUN server port. */
|
||||||
|
|
||||||
|
uint16_t RTO; /**< Estimate of the round-trip time (RTT) in millisecond. */
|
||||||
|
uint16_t Rc; /**< Number of retransmissions for UDP in millisecond. */
|
||||||
|
|
||||||
|
unsigned use_dnsquery:1; /**< Indicates whether to use DNS SRV query to find the stun/turn ip address. */
|
||||||
|
|
||||||
|
tnet_stun_bindings_L_t *stun_bindings; /**< List of all STUN2 bindings associated to this context. */
|
||||||
|
}
|
||||||
|
tnet_nat_ctx_t;
|
||||||
|
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
/**@ingroup tnet_nat_group
|
||||||
* Creates new NAT context.
|
* Creates new NAT context.
|
||||||
*/
|
*/
|
||||||
tnet_nat_context_handle_t* tnet_nat_context_create(tnet_socket_type_t socket_type, const char* username, const char* password)
|
struct tnet_nat_ctx_s* tnet_nat_context_create(tnet_socket_type_t socket_type, const char* pc_username, const char* pc_password)
|
||||||
{
|
{
|
||||||
return tsk_object_new(tnet_nat_context_def_t, socket_type, username, password);
|
extern const tsk_object_def_t *tnet_nat_context_def_t;
|
||||||
}
|
struct tnet_nat_ctx_s* p_ctx;
|
||||||
|
|
||||||
/**
|
if (!(p_ctx = tsk_object_new(tnet_nat_context_def_t)) || !(p_ctx->stun_bindings = tsk_list_create())) {
|
||||||
* Predicate function to find turn allocation by id.
|
TSK_OBJECT_SAFE_FREE(p_ctx);
|
||||||
*
|
TSK_DEBUG_ERROR("Failed to create NAT context");
|
||||||
* @param [in,out] item The current list item.
|
return tsk_null;
|
||||||
* @param [in,out] id A pointer to the allocation identifier.
|
|
||||||
*
|
|
||||||
* @return Zero if current list item hold an allocation with the same id and -1 otherwise.
|
|
||||||
**/
|
|
||||||
int __pred_find_turn_allocation(const tsk_list_item_t* item, const void* id)
|
|
||||||
{
|
|
||||||
if(item)
|
|
||||||
{
|
|
||||||
tnet_turn_allocation_t *allocation = item->data;
|
|
||||||
if(allocation)
|
|
||||||
{
|
|
||||||
tnet_turn_allocation_id_t alloc_id = *((tnet_turn_allocation_id_t*)id);
|
|
||||||
return (allocation->id == alloc_id) ? 0 : -1;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return -1;
|
p_ctx->socket_type = socket_type;
|
||||||
|
p_ctx->username = tsk_strdup(pc_username);
|
||||||
|
p_ctx->password = tsk_strdup(pc_password);
|
||||||
|
p_ctx->server_port = kStunPortDefaultTcpUdp;
|
||||||
|
/* 7.2.1. Sending over UDP
|
||||||
|
In fixed-line access links, a value of 500 ms is RECOMMENDED.
|
||||||
|
*/
|
||||||
|
p_ctx->RTO = kStunRTO;
|
||||||
|
/* 7.2.1. Sending over UDP
|
||||||
|
Rc SHOULD be configurable and SHOULD have a default of 7.
|
||||||
|
*/
|
||||||
|
p_ctx->Rc = kStunRC;
|
||||||
|
|
||||||
|
return p_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Predicate function to find stun binding by id.
|
/** Predicate function to find stun binding by id.
|
||||||
|
@ -79,122 +101,54 @@ int __pred_find_turn_allocation(const tsk_list_item_t* item, const void* id)
|
||||||
**/
|
**/
|
||||||
int __pred_find_stun_binding(const tsk_list_item_t* item, const void* id)
|
int __pred_find_stun_binding(const tsk_list_item_t* item, const void* id)
|
||||||
{
|
{
|
||||||
if(item)
|
if(item) {
|
||||||
{
|
tnet_stun_binding_t *p_bind = item->data;
|
||||||
tnet_stun_binding_t *binding = item->data;
|
if (p_bind) {
|
||||||
if(binding)
|
|
||||||
{
|
|
||||||
tnet_stun_binding_id_t binding_id = *((tnet_stun_binding_id_t*)id);
|
tnet_stun_binding_id_t binding_id = *((tnet_stun_binding_id_t*)id);
|
||||||
return (binding->id == binding_id) ? 0 : -1;
|
return (p_bind->id == binding_id) ? 0 : -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Predicate function to find TURN channel binding by id.
|
|
||||||
*
|
|
||||||
* @param [in,out] item The current list item.
|
|
||||||
* @param [in,out] id A pointer to the TURN channel binding identifier.
|
|
||||||
*
|
|
||||||
* @return Zero if current list item hold a TURN channel binding with the same id and -1 otherwise.
|
|
||||||
**/
|
|
||||||
int __pred_find_turn_channel_binding(const tsk_list_item_t* item, const void* id)
|
|
||||||
{
|
|
||||||
if(item)
|
|
||||||
{
|
|
||||||
tnet_turn_channel_binding_t *binding = item->data;
|
|
||||||
if(binding)
|
|
||||||
{
|
|
||||||
tnet_turn_channel_binding_id_t binding_id = *((tnet_turn_channel_binding_id_t*)id);
|
|
||||||
return (binding->id == binding_id) ? 0 : -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats binary IP address as string.
|
|
||||||
*
|
|
||||||
* @param in_ip The binary IP address to format (in Host byte order).
|
|
||||||
* @param family The address family.
|
|
||||||
* @param [in,out] out_ip The output string
|
|
||||||
*
|
|
||||||
* @return Zero if current list item hold a binding with the same id and -1 otherwise.
|
|
||||||
**/
|
|
||||||
int tnet_stun_address_tostring(const uint8_t in_ip[16], tnet_stun_addr_family_t family, char** out_ip)
|
|
||||||
{
|
|
||||||
/*if(family == stun_ipv6){
|
|
||||||
tsk_sprintf(out_ip, "%x:%x:%x:%x:%x:%x:%x:%x",
|
|
||||||
tnet_ntohs_2(&in_ip[0]), tnet_ntohs_2(&in_ip[2]), tnet_ntohs_2(&in_ip[4]), tnet_ntohs_2(&in_ip[6]),
|
|
||||||
tnet_ntohs_2(&in_ip[8]), tnet_ntohs_2(&in_ip[10]), tnet_ntohs_2(&in_ip[12]), tnet_ntohs_2(&in_ip[14]));
|
|
||||||
}
|
|
||||||
else if(family == stun_ipv4){
|
|
||||||
tsk_sprintf(out_ip, "%u.%u.%u.%u", (address>>24)&0xFF, (address>>16)&0xFF, (address>>8)&0xFF, (address>>0)&0xFF);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
TSK_DEBUG_ERROR("Unsupported address family: %u.", family);
|
|
||||||
}*/
|
|
||||||
if(family == stun_ipv6){
|
|
||||||
tsk_sprintf(out_ip, "%x:%x:%x:%x:%x:%x:%x:%x",
|
|
||||||
TSK_TO_UINT16(&in_ip[0]), TSK_TO_UINT16(&in_ip[2]), TSK_TO_UINT16(&in_ip[4]), TSK_TO_UINT16(&in_ip[6]),
|
|
||||||
TSK_TO_UINT16(&in_ip[8]), TSK_TO_UINT16(&in_ip[10]), TSK_TO_UINT16(&in_ip[12]), TSK_TO_UINT16(&in_ip[14]));
|
|
||||||
}
|
|
||||||
else if(family == stun_ipv4){
|
|
||||||
tsk_sprintf(out_ip, "%u.%u.%u.%u", in_ip[0], in_ip[1], in_ip[2], in_ip[3]);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
TSK_DEBUG_ERROR("Unsupported address family: %u.", family);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
/**@ingroup tnet_nat_group
|
||||||
*
|
*
|
||||||
* Sets the address of the STUN/TURN server.
|
* Sets the address of the STUN/TURN server.
|
||||||
*
|
*
|
||||||
* @param [in,out] self The NAT context.
|
* @param [in,out] p_self The NAT context.
|
||||||
* @param [in,out] server_address The address of server.
|
* @param [in,out] pc_server_address The address of server.
|
||||||
*
|
*
|
||||||
* @return Zero if succeed and non zero error code otherwise.
|
* @return Zero if succeed and non zero error code otherwise.
|
||||||
**/
|
**/
|
||||||
int tnet_nat_set_server_address(tnet_nat_context_handle_t* self, const char* server_address)
|
int tnet_nat_set_server_address(struct tnet_nat_ctx_s* p_self, const char* pc_server_address)
|
||||||
{
|
{
|
||||||
tnet_nat_context_t* context = self;
|
if (!p_self) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
if(context){
|
|
||||||
tsk_strupdate(&(context->server_address), server_address);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
tsk_strupdate(&(p_self->server_address), pc_server_address);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
/**@ingroup tnet_nat_group
|
||||||
*
|
*
|
||||||
* Sets the address and port of the STUN/TURN server.
|
* Sets the address and port of the STUN/TURN server.
|
||||||
*
|
*
|
||||||
* @param [in,out] self The NAT context.
|
* @param [in,out] p_self The NAT context.
|
||||||
* @param [in,out] server_address The address of server.
|
* @param [in,out] pc_server_address The address of server.
|
||||||
* @param server_port The server port.
|
* @param u_server_port The server port.
|
||||||
*
|
*
|
||||||
* @return Zero if succeed and non zero error code otherwise.
|
* @return Zero if succeed and non zero error code otherwise.
|
||||||
**/
|
**/
|
||||||
int tnet_nat_set_server(tnet_nat_context_handle_t* self, const char* server_address, tnet_port_t server_port)
|
int tnet_nat_set_server(struct tnet_nat_ctx_s* p_self, const char* pc_server_address, tnet_port_t u_server_port)
|
||||||
{
|
{
|
||||||
tnet_nat_context_t* context = self;
|
if (!p_self) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
if(context){
|
|
||||||
tsk_strupdate(&(context->server_address), server_address);
|
|
||||||
context->server_port = server_port;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
tsk_strupdate(&(p_self->server_address), pc_server_address);
|
||||||
|
p_self->server_port = u_server_port;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
/**@ingroup tnet_nat_group
|
||||||
|
@ -202,74 +156,179 @@ int tnet_nat_set_server(tnet_nat_context_handle_t* self, const char* server_addr
|
||||||
* Creates and sends a STUN2 binding request to the STUN/TURN server in order to get the server reflexive
|
* Creates and sends a STUN2 binding request to the STUN/TURN server in order to get the server reflexive
|
||||||
* address associated to this file descriptor (or socket). The caller should call @ref tnet_nat_stun_unbind to destroy the binding.
|
* address associated to this file descriptor (or socket). The caller should call @ref tnet_nat_stun_unbind to destroy the binding.
|
||||||
*
|
*
|
||||||
* @param [in,out] self The NAT context.
|
* @param [in,out] p_self The NAT context.
|
||||||
* @param localFD The local file descriptor (or socket) for which to get the reflexive server address.
|
* @param localFD The local file descriptor (or socket) for which to get the reflexive server address.
|
||||||
*
|
*
|
||||||
* @return A valid binding id if succeed and @ref TNET_STUN_INVALID_BINDING_ID otherwise. If the returned id is valid then
|
* @return A valid binding id if succeed and @ref kStunBindingInvalidId otherwise. If the returned id is valid then
|
||||||
* the newly created binding will contain the server-reflexive address associated to the local file descriptor.
|
* the newly created binding will contain the server-reflexive address associated to the local file descriptor.
|
||||||
*
|
*
|
||||||
* @sa @ref tnet_nat_stun_unbind.
|
* @sa @ref tnet_nat_stun_unbind.
|
||||||
**/
|
**/
|
||||||
tnet_stun_binding_id_t tnet_nat_stun_bind(const tnet_nat_context_handle_t* self, const tnet_fd_t localFD)
|
tnet_stun_binding_id_t tnet_nat_stun_bind(const struct tnet_nat_ctx_s* p_self, const tnet_fd_t localFD)
|
||||||
{
|
{
|
||||||
const tnet_nat_context_t* context = self;
|
tnet_stun_binding_id_t id = kStunBindingInvalidId;
|
||||||
if(context){
|
tnet_stun_binding_t *p_binding = tsk_null;
|
||||||
return tnet_stun_bind(context, localFD);
|
int ret;
|
||||||
|
if (!p_self || localFD == TNET_INVALID_FD) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
return TNET_STUN_INVALID_BINDING_ID;
|
if ((ret = tnet_stun_binding_create(localFD, p_self->socket_type, p_self->server_address, p_self->server_port, p_self->username, p_self->password, &p_binding))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if ((ret = tnet_nat_stun_send_bind(p_self, p_binding))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
id = p_binding->id;
|
||||||
|
tsk_list_push_back_data(p_self->stun_bindings, (void**)&p_binding);
|
||||||
|
|
||||||
|
bail:
|
||||||
|
TSK_OBJECT_SAFE_FREE(p_binding);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**@ingroup tnet_nat_group
|
||||||
|
* Internal function to send a STUN2 binding request over the network.
|
||||||
|
*
|
||||||
|
* @param [in,out] p_self The NAT context holding the user preferences.
|
||||||
|
* @param [in,out] p_binding The STUN binding object used to create the message to send.
|
||||||
|
*
|
||||||
|
* @return Zero if succeed and non-zero error code otherwise.
|
||||||
|
**/
|
||||||
|
int tnet_nat_stun_send_bind(const struct tnet_nat_ctx_s* pc_self, struct tnet_stun_binding_s *p_binding)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
tnet_stun_pkt_resp_t *p_pkt_resp = tsk_null;
|
||||||
|
tnet_stun_pkt_req_t *p_pkt_req = tsk_null;
|
||||||
|
|
||||||
|
if (!pc_self || !p_binding) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TNET_SOCKET_TYPE_IS_DGRAM(p_binding->socket_type)) {
|
||||||
|
TSK_DEBUG_ERROR("Only DGRAM could be used for STUN transport");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = tnet_stun_binding_create_req(p_binding, &p_pkt_req))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RFC 5389 - 10.2.1.1. First Request
|
||||||
|
If the client has not completed a successful request/response
|
||||||
|
transaction with the server (as identified by hostname, if the DNS
|
||||||
|
procedures of Section 9 are used, else IP address if not), it SHOULD
|
||||||
|
omit the USERNAME, MESSAGE-INTEGRITY, REALM, and NONCE attributes.
|
||||||
|
In other words, the very first request is sent as if there were no
|
||||||
|
authentication or message integrity applied.
|
||||||
|
*/
|
||||||
|
stun_phase0: {
|
||||||
|
if ((ret = tnet_stun_utils_send_unreliably(p_binding->localFD, pc_self->RTO, pc_self->Rc, p_pkt_req, (struct sockaddr*)&p_binding->addr_server, &p_pkt_resp))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_pkt_resp) {
|
||||||
|
if (TNET_STUN_PKT_RESP_IS_ERROR(p_pkt_resp)) {
|
||||||
|
uint16_t u_code;
|
||||||
|
if ((ret = tnet_stun_pkt_get_errorcode(p_pkt_resp, &u_code))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if (u_code == kStunErrCodeUnauthorized || u_code == kStunErrCodeStaleNonce) {
|
||||||
|
if (u_code == kStunErrCodeUnauthorized) {
|
||||||
|
// Make sure this is not an authentication failure (#2 401)
|
||||||
|
// Do not send another req to avoid endless messages
|
||||||
|
if ((tnet_stun_pkt_attr_exists(p_pkt_req, tnet_stun_attr_type_message_integrity))) { // already has a MESSAGE-INTEGRITY?
|
||||||
|
TSK_DEBUG_ERROR("STUN authentication failed");
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((ret = tnet_stun_pkt_auth_prepare_2(p_pkt_req, p_binding->p_username, p_binding->p_password, p_pkt_resp))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
// Try to send again now that authinfo is up2date
|
||||||
|
goto stun_phase0;
|
||||||
|
}
|
||||||
|
else if (u_code == kStunErrCodeUnknownAttributes) {
|
||||||
|
if((ret = tnet_stun_pkt_process_err420(p_pkt_req, p_pkt_resp))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
// Try to send again now that authinfo is up2date
|
||||||
|
goto stun_phase0;
|
||||||
|
}
|
||||||
|
ret = -3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const tnet_stun_attr_address_t* pc_addr;
|
||||||
|
if ((ret = tnet_stun_pkt_attr_find_first(p_pkt_resp, tnet_stun_attr_type_xor_mapped_address, (const tnet_stun_attr_t**)&pc_addr)) == 0 && pc_addr) {
|
||||||
|
TSK_OBJECT_SAFE_FREE(p_binding->p_xmaddr);
|
||||||
|
p_binding->p_xmaddr = tsk_object_ref(TSK_OBJECT(pc_addr));
|
||||||
|
}
|
||||||
|
if ((ret = tnet_stun_pkt_attr_find_first(p_pkt_resp, tnet_stun_attr_type_mapped_address, (const tnet_stun_attr_t**)&pc_addr)) == 0 && pc_addr) {
|
||||||
|
TSK_OBJECT_SAFE_FREE(p_binding->p_maddr);
|
||||||
|
p_binding->p_maddr = tsk_object_ref(TSK_OBJECT(pc_addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* END OF stun_phase0 */
|
||||||
|
|
||||||
|
bail:
|
||||||
|
TSK_OBJECT_SAFE_FREE(p_pkt_resp);
|
||||||
|
TSK_OBJECT_SAFE_FREE(p_pkt_req);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
/**@ingroup tnet_nat_group
|
||||||
* Gets the server reflexive address associated to this STUN2 binding.
|
* Gets the server reflexive address associated to this STUN2 binding.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param [in,out] self The NAT context.
|
* @param [in,out] p_self The NAT context.
|
||||||
* @param id The id of the STUN2 binding conetxt (obtained using @ref tnet_nat_stun_bind) holding the server-reflexive address.
|
* @param id The id of the STUN2 binding conetxt (obtained using @ref tnet_nat_stun_bind) holding the server-reflexive address.
|
||||||
* @param [in,out] ipaddress The reflexive IP address. It is up the the caller to free the returned string
|
* @param [in,out] pp_ip The reflexive IP address. It is up the the caller to free the returned string
|
||||||
* @param [in,out] port The reflexive port.
|
* @param [in,out] pu_port The reflexive port.
|
||||||
*
|
*
|
||||||
* @return Zero if succeed and non zero error code otherwise.
|
* @return Zero if succeed and non zero error code otherwise.
|
||||||
**/
|
**/
|
||||||
int tnet_nat_stun_get_reflexive_address(const tnet_nat_context_handle_t* self, tnet_stun_binding_id_t id, char** ipaddress, tnet_port_t *port)
|
int tnet_nat_stun_get_reflexive_address(const struct tnet_nat_ctx_s* p_self, tnet_stun_binding_id_t id, char** pp_ip, tnet_port_t *pu_port)
|
||||||
{
|
{
|
||||||
const tnet_nat_context_t* context = self;
|
const tsk_list_item_t* item;
|
||||||
if(context){
|
if (!p_self) {
|
||||||
const tsk_list_item_t* item = tsk_list_find_item_by_pred(context->stun_bindings, __pred_find_stun_binding, &id);
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
if(item && item->data){
|
return -1;
|
||||||
tnet_stun_binding_t *binding = item->data;
|
|
||||||
/*STUN2: XOR-MAPPED-ADDRESS */
|
|
||||||
if(binding->xmaddr){
|
|
||||||
int ret = 0;
|
|
||||||
if(ipaddress){
|
|
||||||
ret = tnet_stun_address_tostring(binding->xmaddr->xaddress, binding->xmaddr->family, ipaddress);
|
|
||||||
}
|
}
|
||||||
if(port){
|
if (!pp_ip && !pu_port) {
|
||||||
*port = /*tnet_ntohs*/(binding->xmaddr->xport);
|
return 0;
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*STUN1: MAPPED-ADDRESS*/
|
if ((item = tsk_list_find_item_by_pred(p_self->stun_bindings, __pred_find_stun_binding, &id)) && item->data) {
|
||||||
if(binding->maddr){
|
const tnet_stun_binding_t *pc_bind = (const tnet_stun_binding_t *)item->data;
|
||||||
int ret = 0;
|
const struct tnet_stun_attr_address_s *pc_addr = pc_bind->p_xmaddr ? pc_bind->p_xmaddr : pc_bind->p_maddr;
|
||||||
if(ipaddress){
|
if (pc_addr) {
|
||||||
ret = tnet_stun_address_tostring(binding->maddr->address, binding->maddr->family, ipaddress);
|
tnet_ip_t ip;
|
||||||
}
|
int ret;
|
||||||
if(port){
|
if ((ret = tnet_stun_utils_inet_ntop((pc_addr->e_family == tnet_stun_address_family_ipv6), &pc_addr->address, &ip))) {
|
||||||
*port = /*tnet_ntohs*/(binding->maddr->port);
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if (pp_ip) {
|
||||||
|
tsk_strupdate(pp_ip, ip);
|
||||||
|
}
|
||||||
|
if (pu_port) {
|
||||||
|
*pu_port = pc_addr->u_port;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
/**@ingroup tnet_nat_group
|
||||||
*
|
*
|
||||||
* Removes a STUN2 binding from the NAT context.
|
* Removes a STUN2 binding from the NAT context.
|
||||||
*
|
*
|
||||||
* @param [in,out] self The NAT context from which to remove the STUN2 binding.
|
* @param [in,out] p_self The NAT context from which to remove the STUN2 binding.
|
||||||
* @param id The id of the STUN2 binding to remove.
|
* @param id The id of the STUN2 binding to remove.
|
||||||
*
|
*
|
||||||
* @return Zero if succeed and non zero error code otherwise.
|
* @return Zero if succeed and non zero error code otherwise.
|
||||||
|
@ -277,234 +336,14 @@ int tnet_nat_stun_get_reflexive_address(const tnet_nat_context_handle_t* self, t
|
||||||
*
|
*
|
||||||
* @sa @ref tnet_nat_stun_bind.
|
* @sa @ref tnet_nat_stun_bind.
|
||||||
**/
|
**/
|
||||||
int tnet_nat_stun_unbind(const tnet_nat_context_handle_t* self, tnet_stun_binding_id_t id)
|
int tnet_nat_stun_unbind(const struct tnet_nat_ctx_s* p_self, tnet_stun_binding_id_t id)
|
||||||
{
|
{
|
||||||
const tnet_nat_context_t* context = self;
|
if (!p_self) {
|
||||||
if(context)
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
{
|
return -1;
|
||||||
tsk_list_remove_item_by_pred(context->stun_bindings, __pred_find_stun_binding, &id);
|
}
|
||||||
|
tsk_list_remove_item_by_pred(p_self->stun_bindings, __pred_find_stun_binding, &id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
|
||||||
*
|
|
||||||
* Creates TURN allocation as per draft-ietf-behave-turn-16 subclause 6. This function will also
|
|
||||||
* send an allocation request to the server (subclause 6.1).
|
|
||||||
*
|
|
||||||
* @param [in,out] self The NAT context.
|
|
||||||
* @param localFD The local file descriptor.
|
|
||||||
*
|
|
||||||
* @return A valid TURN allocation id if succeed and @ref TNET_TURN_INVALID_ALLOCATION_ID otherwise.
|
|
||||||
*
|
|
||||||
* @sa @ref tnet_nat_turn_unallocate.
|
|
||||||
**/
|
|
||||||
tnet_turn_allocation_id_t tnet_nat_turn_allocate(const tnet_nat_context_handle_t* self, const tnet_fd_t localFD)
|
|
||||||
{
|
|
||||||
const tnet_nat_context_t* context = self;
|
|
||||||
|
|
||||||
if(self)
|
|
||||||
{
|
|
||||||
return tnet_turn_allocate(self, localFD, context->socket_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TNET_TURN_INVALID_ALLOCATION_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
|
||||||
* Gets the STUN server-refelexive IP address and port associated to this TURN allocation.
|
|
||||||
*
|
|
||||||
* @param [in,out] self The NAT context.
|
|
||||||
* @param id The id of the TURN allocation for which to to get server-reflexive IP address and port.
|
|
||||||
* @param [in,out] ipaddress The server-reflexive IP address.
|
|
||||||
* @param [in,out] port The server-reflexive port.
|
|
||||||
*
|
|
||||||
* @return Zero if succeed and non zero error code otherwise.
|
|
||||||
**/
|
|
||||||
int tnet_nat_turn_get_reflexive_address(const tnet_nat_context_handle_t* self, tnet_turn_allocation_id_t id, char** ipaddress, tnet_port_t *port)
|
|
||||||
{
|
|
||||||
const tnet_nat_context_t* context = self;
|
|
||||||
if(context)
|
|
||||||
{
|
|
||||||
const tsk_list_item_t* item = tsk_list_find_item_by_pred(context->allocations, __pred_find_turn_allocation, &id);
|
|
||||||
if(item && item->data)
|
|
||||||
{
|
|
||||||
tnet_turn_allocation_t *allocation = item->data;
|
|
||||||
/*STUN2: XOR-MAPPED-ADDRESS */
|
|
||||||
if(allocation->xmaddr)
|
|
||||||
{
|
|
||||||
int ret = tnet_stun_address_tostring(allocation->xmaddr->xaddress, allocation->xmaddr->family, ipaddress);
|
|
||||||
*port = /*tnet_ntohs*/(allocation->xmaddr->xport);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*STUN1: MAPPED-ADDRESS*/
|
|
||||||
if(allocation->maddr)
|
|
||||||
{
|
|
||||||
int ret = tnet_stun_address_tostring(allocation->maddr->address, allocation->maddr->family, ipaddress);
|
|
||||||
*port = /*tnet_ntohs*/(allocation->maddr->port);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
|
||||||
*
|
|
||||||
* Refresh a TURN allocation previously created using @ref tnet_nat_turn_allocate.
|
|
||||||
*
|
|
||||||
* @param [in,out] self The NAT context.
|
|
||||||
* @param id The id of the TURN allocation to refresh.
|
|
||||||
*
|
|
||||||
* @return Zero if succeed and non zero error code otherwise.
|
|
||||||
**/
|
|
||||||
int tnet_nat_turn_allocation_refresh(const tnet_nat_context_handle_t* self, tnet_turn_allocation_id_t id)
|
|
||||||
{
|
|
||||||
const tnet_nat_context_t* context = self;
|
|
||||||
|
|
||||||
if(context)
|
|
||||||
{
|
|
||||||
const tsk_list_item_t* item = tsk_list_find_item_by_pred(context->allocations, __pred_find_turn_allocation, &id);
|
|
||||||
if(item && item->data)
|
|
||||||
{
|
|
||||||
tnet_turn_allocation_t *allocation = item->data;
|
|
||||||
return tnet_turn_allocation_refresh(self, allocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
|
||||||
*
|
|
||||||
* Unallocate/remove a TURN allocation from the server.
|
|
||||||
*
|
|
||||||
* @param [in,out] self The NAT context from which to remove the allocation.
|
|
||||||
* @param id The id of the TURN allocation to remove.
|
|
||||||
*
|
|
||||||
* @return Zero if succeed and non zero error code otherwise.
|
|
||||||
*
|
|
||||||
* @sa @ref tnet_nat_turn_allocate.
|
|
||||||
**/
|
|
||||||
int tnet_nat_turn_unallocate(const tnet_nat_context_handle_t* self, tnet_turn_allocation_id_t id)
|
|
||||||
{
|
|
||||||
const tnet_nat_context_t* context = self;
|
|
||||||
|
|
||||||
if(context)
|
|
||||||
{
|
|
||||||
const tsk_list_item_t* item = tsk_list_find_item_by_pred(context->allocations, __pred_find_turn_allocation, &id);
|
|
||||||
if(item && item->data)
|
|
||||||
{
|
|
||||||
tnet_turn_allocation_t *allocation = item->data;
|
|
||||||
return tnet_turn_unallocate(self, allocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
|
||||||
* Creates TURN channel binding as per draft-ietf-behave-turn-16 sublause 11 and send it to the
|
|
||||||
* server as per subclause 11.1.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param [in,out] self The NAT context.
|
|
||||||
* @param id The id of the TURN allocation associated to this binding.
|
|
||||||
* @param [in,out] peer The XOR remote peer for the channel binding.
|
|
||||||
*
|
|
||||||
* @return A valid TURN channel binding id if succeed and @ref TNET_TURN_INVALID_CHANNEL_BINDING_ID otherwise.
|
|
||||||
**/
|
|
||||||
tnet_turn_channel_binding_id_t tnet_nat_turn_channel_bind(const tnet_nat_context_handle_t* self, tnet_turn_allocation_id_t id, struct sockaddr_storage *peer)
|
|
||||||
{
|
|
||||||
const tnet_nat_context_t* context = self;
|
|
||||||
|
|
||||||
if(context)
|
|
||||||
{
|
|
||||||
const tsk_list_item_t* item = tsk_list_find_item_by_pred(context->allocations, __pred_find_turn_allocation, &id);
|
|
||||||
if(item && item->data)
|
|
||||||
{
|
|
||||||
tnet_turn_allocation_t *allocation = item->data;
|
|
||||||
return tnet_turn_channel_bind(self, allocation, peer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TNET_TURN_INVALID_CHANNEL_BINDING_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
|
||||||
*/
|
|
||||||
int tnet_nat_turn_channel_refresh(const tnet_nat_context_handle_t* self, tnet_turn_channel_binding_id_t id)
|
|
||||||
{
|
|
||||||
const tnet_nat_context_t* context = self;
|
|
||||||
|
|
||||||
if(context)
|
|
||||||
{
|
|
||||||
tsk_list_item_t* curr;
|
|
||||||
tsk_list_foreach(curr, context->allocations)
|
|
||||||
{
|
|
||||||
const tsk_list_item_t* item = tsk_list_find_item_by_pred(((tnet_turn_allocation_t *)curr->data)->channel_bindings, __pred_find_turn_channel_binding, &id);
|
|
||||||
if(item && item->data)
|
|
||||||
{
|
|
||||||
return tnet_turn_channel_refresh(context, (tnet_turn_channel_binding_t *)item->data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
|
||||||
*/
|
|
||||||
int tnet_nat_turn_channel_send(const tnet_nat_context_handle_t* self, tnet_turn_channel_binding_id_t id, const void* data, tsk_size_t size, int indication)
|
|
||||||
{
|
|
||||||
const tnet_nat_context_t* context = self;
|
|
||||||
|
|
||||||
if(context && data && size)
|
|
||||||
{
|
|
||||||
tsk_list_item_t* curr;
|
|
||||||
tsk_list_foreach(curr, context->allocations)
|
|
||||||
{
|
|
||||||
const tsk_list_item_t* item = tsk_list_find_item_by_pred(((tnet_turn_allocation_t *)curr->data)->channel_bindings, __pred_find_turn_channel_binding, &id);
|
|
||||||
if(item && item->data)
|
|
||||||
{
|
|
||||||
return tnet_turn_channel_senddata(context, (tnet_turn_channel_binding_t *)item->data, data, size, indication);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
|
||||||
*/
|
|
||||||
int tnet_nat_turn_add_permission(const tnet_nat_context_handle_t* self, tnet_turn_allocation_id_t id, const char* ipaddress, uint32_t timeout)
|
|
||||||
{
|
|
||||||
const tnet_nat_context_t* context = self;
|
|
||||||
|
|
||||||
if(self)
|
|
||||||
{
|
|
||||||
const tsk_list_item_t* item = tsk_list_find_item_by_pred(context->allocations, __pred_find_turn_allocation, &id);
|
|
||||||
if(item && item->data)
|
|
||||||
{
|
|
||||||
tnet_turn_allocation_t *allocation = item->data;
|
|
||||||
return tnet_turn_add_permission(self, allocation, ipaddress, timeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -513,56 +352,28 @@ int tnet_nat_turn_add_permission(const tnet_nat_context_handle_t* self, tnet_tur
|
||||||
//
|
//
|
||||||
static tsk_object_t* tnet_nat_context_ctor(tsk_object_t * self, va_list * app)
|
static tsk_object_t* tnet_nat_context_ctor(tsk_object_t * self, va_list * app)
|
||||||
{
|
{
|
||||||
tnet_nat_context_t *context = self;
|
tnet_nat_ctx_t *p_ctx = (tnet_nat_ctx_t*)self;
|
||||||
if(context){
|
if (p_ctx) {
|
||||||
context->socket_type = va_arg(*app, tnet_socket_type_t);
|
|
||||||
|
|
||||||
context->username = tsk_strdup(va_arg(*app, const char*));
|
|
||||||
context->password = tsk_strdup(va_arg(*app, const char*));
|
|
||||||
|
|
||||||
context->server_port = TNET_NAT_TCP_UDP_DEFAULT_PORT;
|
|
||||||
|
|
||||||
/* 7.2.1. Sending over UDP
|
|
||||||
In fixed-line access links, a value of 500 ms is RECOMMENDED.
|
|
||||||
*/
|
|
||||||
context->RTO = TNET_NAT_DEFAULT_RTO;
|
|
||||||
|
|
||||||
/* 7.2.1. Sending over UDP
|
|
||||||
Rc SHOULD be configurable and SHOULD have a default of 7.
|
|
||||||
*/
|
|
||||||
context->Rc = TNET_NAT_DEFAULT_RC;
|
|
||||||
|
|
||||||
context->software = tsk_strdup(TNET_SOFTWARE);
|
|
||||||
//context->enable_evenport = 1;
|
|
||||||
//context->enable_fingerprint = 1;
|
|
||||||
context->enable_integrity = 0;
|
|
||||||
context->enable_dontfrag = 0;//TNET_SOCKET_TYPE_IS_DGRAM(context->socket_type) ? 1 : 0;
|
|
||||||
|
|
||||||
context->allocations = tsk_list_create();
|
|
||||||
context->stun_bindings = tsk_list_create();
|
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
static tsk_object_t* tnet_nat_context_dtor(tsk_object_t * self)
|
static tsk_object_t* tnet_nat_context_dtor(tsk_object_t * self)
|
||||||
{
|
{
|
||||||
tnet_nat_context_t *context = self;
|
tnet_nat_ctx_t *p_ctx = (tnet_nat_ctx_t*)self;
|
||||||
if(context){
|
if (p_ctx) {
|
||||||
TSK_FREE(context->username);
|
TSK_FREE(p_ctx->username);
|
||||||
TSK_FREE(context->password);
|
TSK_FREE(p_ctx->password);
|
||||||
TSK_FREE(context->software);
|
TSK_FREE(p_ctx->server_address);
|
||||||
TSK_FREE(context->server_address);
|
|
||||||
|
|
||||||
TSK_OBJECT_SAFE_FREE(context->allocations);
|
TSK_OBJECT_SAFE_FREE(p_ctx->stun_bindings);
|
||||||
TSK_OBJECT_SAFE_FREE(context->stun_bindings);
|
TSK_DEBUG_INFO("*** NAT context destroyed ***");
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const tsk_object_def_t tnet_nat_context_def_s =
|
static const tsk_object_def_t tnet_nat_context_def_s =
|
||||||
{
|
{
|
||||||
sizeof(tnet_nat_context_t),
|
sizeof(tnet_nat_ctx_t),
|
||||||
tnet_nat_context_ctor,
|
tnet_nat_context_ctor,
|
||||||
tnet_nat_context_dtor,
|
tnet_nat_context_dtor,
|
||||||
tsk_null,
|
tsk_null,
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
/*
|
/* Copyright (C) 2010-2014 Mamadou DIOP.
|
||||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
|
||||||
*
|
|
||||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
|
||||||
*
|
*
|
||||||
* This file is part of Open Source Doubango Framework.
|
* This file is part of Open Source Doubango Framework.
|
||||||
*
|
*
|
||||||
|
@ -19,101 +16,27 @@
|
||||||
* along with DOUBANGO.
|
* along with DOUBANGO.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**@file tnet_nat.h
|
|
||||||
* @brief NAT Traversal helper functions using STUN, TURN and ICE.
|
|
||||||
*
|
|
||||||
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
|
||||||
#ifndef TNET_NAT_H
|
#ifndef TNET_NAT_H
|
||||||
#define TNET_NAT_H
|
#define TNET_NAT_H
|
||||||
|
|
||||||
#include "tinynet_config.h"
|
#include "tinynet_config.h"
|
||||||
|
#include "tnet_socket.h"
|
||||||
|
|
||||||
#include "stun/tnet_stun.h"
|
#include "stun/tnet_stun_types.h"
|
||||||
#include "turn/tnet_turn.h"
|
|
||||||
|
|
||||||
#include "tnet_proto.h"
|
|
||||||
#include "tnet_types.h"
|
|
||||||
|
|
||||||
#include "tsk_object.h"
|
|
||||||
|
|
||||||
|
|
||||||
TNET_BEGIN_DECLS
|
TNET_BEGIN_DECLS
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
struct tnet_nat_ctx_s;
|
||||||
* Estimate of the round-trip time (RTT) in millisecond.
|
struct tnet_stun_binding_s;
|
||||||
*/
|
enum tnet_socket_type_e;
|
||||||
#define TNET_NAT_DEFAULT_RTO 500
|
|
||||||
/**@ingroup tnet_nat_group
|
|
||||||
* Number of retransmission for UDP retransmission in millisecond.
|
|
||||||
* 7.2.1. Sending over UDP
|
|
||||||
Rc SHOULD be configurable and SHOULD have a default of 7.
|
|
||||||
*/
|
|
||||||
#define TNET_NAT_DEFAULT_RC /*7*/3/* 7 is too hight */
|
|
||||||
/**@ingroup tnet_nat_group
|
|
||||||
*/
|
|
||||||
#define TNET_NAT_TCP_UDP_DEFAULT_PORT 3478
|
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
TINYNET_API int tnet_nat_set_server_address(struct tnet_nat_ctx_s* p_self, const char* pc_srv_addr);
|
||||||
* NAT context.
|
TINYNET_API int tnet_nat_set_server(struct tnet_nat_ctx_s* p_self, const char* pc_srv_addr, tnet_port_t u_srv_port);
|
||||||
**/
|
TINYNET_API tnet_stun_binding_id_t tnet_nat_stun_bind(const struct tnet_nat_ctx_s* p_self, const tnet_fd_t localFD);
|
||||||
typedef struct tnet_nat_context_s
|
TINYNET_API int tnet_nat_stun_send_bind(const struct tnet_nat_ctx_s* pc_self, struct tnet_stun_binding_s *p_binding);
|
||||||
{
|
TINYNET_API int tnet_nat_stun_get_reflexive_address(const struct tnet_nat_ctx_s* p_self, tnet_stun_binding_id_t id, char** pp_ip, tnet_port_t *pu_port);
|
||||||
TSK_DECLARE_OBJECT;
|
TINYNET_API int tnet_nat_stun_unbind(const struct tnet_nat_ctx_s* p_self, tnet_stun_binding_id_t id);
|
||||||
|
TINYNET_API struct tnet_nat_ctx_s* tnet_nat_context_create(enum tnet_socket_type_e socket_type, const char* pc_username, const char* pc_password);
|
||||||
//tnet_fd_t localFD; /**< Local file descriptor. */
|
|
||||||
tnet_socket_type_t socket_type;
|
|
||||||
|
|
||||||
char* username; /**< The username to use to authenticate against the TURN/STUN server. */
|
|
||||||
char* password; /**< The password to use to authenticate against the TURN/STUN server. */
|
|
||||||
char* software; /**< The turn/stun client name. */
|
|
||||||
|
|
||||||
char* server_address; /**< TURN/STUN server address (could be FQDN or IP) */
|
|
||||||
tnet_port_t server_port; /**< TURN/STUN server port. */
|
|
||||||
|
|
||||||
uint16_t RTO; /**< Estimate of the round-trip time (RTT) in millisecond. */
|
|
||||||
uint16_t Rc; /**< Number of retransmissions for UDP in millisecond. */
|
|
||||||
|
|
||||||
unsigned enable_dontfrag:1;
|
|
||||||
unsigned enable_integrity:1;
|
|
||||||
unsigned enable_evenport:1;
|
|
||||||
unsigned enable_fingerprint:1; /**< Indicates whether to add the 'fingerprint' attribute in all outgoing stun/turn requests. */
|
|
||||||
unsigned use_dnsquery:1; /**< Indicates whether to use DNS SRV query to find the stun/turn ip address. */
|
|
||||||
|
|
||||||
tnet_turn_allocations_L_t *allocations; /**< List of all allocations associated to this context. */
|
|
||||||
tnet_stun_bindings_L_t *stun_bindings; /**< List of all STUN2 bindings associated to this context. */
|
|
||||||
}
|
|
||||||
tnet_nat_context_t;
|
|
||||||
|
|
||||||
/**@ingroup tnet_nat_group
|
|
||||||
* Handle to the NAT context(@ref tnet_nat_context_t).
|
|
||||||
**/
|
|
||||||
typedef void tnet_nat_context_handle_t;
|
|
||||||
|
|
||||||
TINYNET_API int tnet_nat_set_server_address(tnet_nat_context_handle_t* self, const char* server_address);
|
|
||||||
TINYNET_API int tnet_nat_set_server(tnet_nat_context_handle_t* self, const char* server_address, tnet_port_t server_port);
|
|
||||||
|
|
||||||
TINYNET_API tnet_stun_binding_id_t tnet_nat_stun_bind(const tnet_nat_context_handle_t* self, const tnet_fd_t localFD);
|
|
||||||
TINYNET_API int tnet_nat_stun_get_reflexive_address(const tnet_nat_context_handle_t* self, tnet_stun_binding_id_t id, char** ipaddress, tnet_port_t *port);
|
|
||||||
TINYNET_API int tnet_nat_stun_unbind(const tnet_nat_context_handle_t* self, tnet_stun_binding_id_t id);
|
|
||||||
|
|
||||||
TINYNET_API tnet_turn_allocation_id_t tnet_nat_turn_allocate(const tnet_nat_context_handle_t* self, const tnet_fd_t localFD);
|
|
||||||
TINYNET_API int tnet_nat_turn_get_reflexive_address(const tnet_nat_context_handle_t* self, tnet_turn_allocation_id_t id, char** ipaddress, tnet_port_t *port);
|
|
||||||
TINYNET_API int tnet_nat_turn_allocation_refresh(const tnet_nat_context_handle_t* self, tnet_turn_allocation_id_t id);
|
|
||||||
TINYNET_API int tnet_nat_turn_unallocate(const tnet_nat_context_handle_t* self, tnet_turn_allocation_id_t id);
|
|
||||||
TINYNET_API tnet_turn_channel_binding_id_t tnet_nat_turn_channel_bind(const tnet_nat_context_handle_t* self, tnet_turn_allocation_id_t id, struct sockaddr_storage *peer);
|
|
||||||
TINYNET_API int tnet_nat_turn_channel_refresh(const tnet_nat_context_handle_t* self, tnet_turn_channel_binding_id_t id);
|
|
||||||
TINYNET_API int tnet_nat_turn_channel_send(const tnet_nat_context_handle_t* self, tnet_turn_channel_binding_id_t id, const void* data, tsk_size_t size, int indication);
|
|
||||||
#define tnet_nat_turn_channel_sendindication(context, channel_id, data, size) tnet_nat_turn_channel_send(context, channel_id, data, size, 1)
|
|
||||||
#define tnet_nat_turn_channel_senddata(context, channel_id, data, size) tnet_nat_turn_channel_send(context, channel_id, data, size, 0)
|
|
||||||
TINYNET_API int tnet_nat_turn_add_permission(const tnet_nat_context_handle_t* self, tnet_turn_allocation_id_t id, const char* ipaddress, uint32_t timeout);
|
|
||||||
|
|
||||||
TINYNET_API tnet_nat_context_handle_t* tnet_nat_context_create(tnet_socket_type_t socket_type, const char* username, const char* password);
|
|
||||||
|
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_nat_context_def_t;
|
|
||||||
|
|
||||||
TNET_END_DECLS
|
TNET_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -155,19 +155,9 @@ tnet_socket_t* tnet_socket_create_2(const char* host, tnet_port_t port_, tnet_so
|
||||||
*/
|
*/
|
||||||
//
|
//
|
||||||
if (TNET_SOCKET_TYPE_IS_STREAM(sock->type)) {
|
if (TNET_SOCKET_TYPE_IS_STREAM(sock->type)) {
|
||||||
#if defined(SOLARIS)
|
if ((status = tnet_sockfd_reuseaddr(sock->fd, 1))) {
|
||||||
static const char yes = '1';
|
// do not break...continue
|
||||||
#else
|
|
||||||
static const int yes = 1;
|
|
||||||
#endif
|
|
||||||
if(setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(int)) == -1){
|
|
||||||
TNET_PRINT_LAST_ERROR("setsockopt(SO_REUSEADDR) have failed");
|
|
||||||
}
|
}
|
||||||
#if defined(SO_REUSEPORT)
|
|
||||||
if(setsockopt(sock->fd, SOL_SOCKET, SO_REUSEPORT, (char*)&yes, sizeof(int)) == -1){
|
|
||||||
TNET_PRINT_LAST_ERROR("setsockopt(SO_REUSEPORT) have failed");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bindsocket){
|
if(bindsocket){
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#include "tls/tnet_tls.h"
|
#include "tls/tnet_tls.h"
|
||||||
#include "tls/tnet_dtls.h"
|
#include "tls/tnet_dtls.h"
|
||||||
|
|
||||||
|
#include "stun/tnet_stun_types.h"
|
||||||
|
|
||||||
#include "tsk_memory.h"
|
#include "tsk_memory.h"
|
||||||
#include "tsk_string.h"
|
#include "tsk_string.h"
|
||||||
#include "tsk_debug.h"
|
#include "tsk_debug.h"
|
||||||
|
@ -107,6 +109,7 @@ static int _tnet_transport_ssl_init(tnet_transport_t* transport)
|
||||||
TSK_DEBUG_ERROR("SSL_CTX_set_cipher_list failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
|
TSK_DEBUG_ERROR("SSL_CTX_set_cipher_list failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
|
||||||
return -6;
|
return -6;
|
||||||
}
|
}
|
||||||
|
transport->dtls.activated = tsk_true;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_OPENSSL_DTLS */
|
#endif /* HAVE_OPENSSL_DTLS */
|
||||||
}
|
}
|
||||||
|
@ -364,7 +367,7 @@ int tnet_transport_get_ip_n_port_2(const tnet_transport_handle_t *handle, tnet_i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int tnet_transport_set_natt_ctx(tnet_transport_handle_t *handle, tnet_nat_context_handle_t* natt_ctx)
|
int tnet_transport_set_natt_ctx(tnet_transport_handle_t *handle, struct tnet_nat_ctx_s* natt_ctx)
|
||||||
{
|
{
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
@ -378,15 +381,15 @@ int tnet_transport_set_natt_ctx(tnet_transport_handle_t *handle, tnet_nat_contex
|
||||||
int tnet_transport_get_public_ip_n_port(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_ip_t *ip, tnet_port_t *port)
|
int tnet_transport_get_public_ip_n_port(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_ip_t *ip, tnet_port_t *port)
|
||||||
{
|
{
|
||||||
tsk_bool_t stun_ok = tsk_false;
|
tsk_bool_t stun_ok = tsk_false;
|
||||||
tnet_nat_context_handle_t* natt_ctx;
|
struct tnet_nat_ctx_s* natt_ctx;
|
||||||
const tnet_transport_t *transport = handle;
|
const tnet_transport_t *transport = handle;
|
||||||
if(!transport){
|
if(!transport){
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(TNET_SOCKET_TYPE_IS_DGRAM(transport->type) && (natt_ctx = tsk_object_ref(transport->natt_ctx))){
|
if (TNET_SOCKET_TYPE_IS_DGRAM(transport->type) && (natt_ctx = tsk_object_ref(transport->natt_ctx))) {
|
||||||
tnet_stun_binding_id_t bind_id = TNET_STUN_INVALID_BINDING_ID;
|
tnet_stun_binding_id_t bind_id = kStunBindingInvalidId;
|
||||||
// if the socket is already monitored by the transport we should pause because both the transport and
|
// if the socket is already monitored by the transport we should pause because both the transport and
|
||||||
// NAT binder will try to read from it
|
// NAT binder will try to read from it
|
||||||
|
|
||||||
|
@ -397,7 +400,7 @@ int tnet_transport_get_public_ip_n_port(const tnet_transport_handle_t *handle, t
|
||||||
// Resume the socket
|
// Resume the socket
|
||||||
tnet_transport_pause_socket(transport, fd, tsk_false);
|
tnet_transport_pause_socket(transport, fd, tsk_false);
|
||||||
|
|
||||||
if(TNET_STUN_IS_VALID_BINDING_ID(bind_id)){
|
if (bind_id != kStunBindingInvalidId) {
|
||||||
char* public_ip = tsk_null;
|
char* public_ip = tsk_null;
|
||||||
if(tnet_nat_stun_get_reflexive_address(transport->natt_ctx, bind_id, &public_ip, port) == 0){
|
if(tnet_nat_stun_get_reflexive_address(transport->natt_ctx, bind_id, &public_ip, port) == 0){
|
||||||
if(ip && public_ip){
|
if(ip && public_ip){
|
||||||
|
@ -600,19 +603,19 @@ int tnet_transport_dtls_set_setup(tnet_transport_handle_t* handle, tnet_dtls_set
|
||||||
{
|
{
|
||||||
tnet_transport_t *transport = handle;
|
tnet_transport_t *transport = handle;
|
||||||
|
|
||||||
if(!transport){
|
if (!transport) {
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!transport->dtls.enabled){
|
if (!transport->dtls.enabled) {
|
||||||
TSK_DEBUG_ERROR("DTLS not enabled on this transport");
|
TSK_DEBUG_ERROR("DTLS not enabled on this transport");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
if(sockets && sockets_count){
|
if (sockets && sockets_count) {
|
||||||
tsk_size_t i;
|
tsk_size_t i;
|
||||||
for(i = 0; i < sockets_count; ++i){
|
for (i = 0; i < sockets_count; ++i) {
|
||||||
if(!sockets[i] || !sockets[i]->dtlshandle){
|
if (!sockets[i] || !sockets[i]->dtlshandle) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tnet_dtls_socket_set_setup(sockets[i]->dtlshandle, setup);
|
tnet_dtls_socket_set_setup(sockets[i]->dtlshandle, setup);
|
||||||
|
@ -621,26 +624,51 @@ int tnet_transport_dtls_set_setup(tnet_transport_handle_t* handle, tnet_dtls_set
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tnet_transport_dtls_set_store_handshakingdata(tnet_transport_handle_t* handle, tsk_bool_t handshake_storedata, struct tnet_socket_s** sockets, tsk_size_t sockets_count)
|
||||||
|
{
|
||||||
|
tnet_transport_t *transport = handle;
|
||||||
|
|
||||||
|
if (!transport) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!transport->dtls.enabled) {
|
||||||
|
TSK_DEBUG_ERROR("DTLS not enabled on this transport");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
if (sockets && sockets_count) {
|
||||||
|
tsk_size_t i;
|
||||||
|
for (i = 0; i < sockets_count; ++i) {
|
||||||
|
if (!sockets[i] || !sockets[i]->dtlshandle) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tnet_dtls_socket_set_store_handshakingdata(sockets[i]->dtlshandle, handshake_storedata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int tnet_transport_dtls_do_handshake(tnet_transport_handle_t *handle, struct tnet_socket_s** sockets, tsk_size_t sockets_count, const struct sockaddr_storage** remote_addrs, tsk_size_t remote_addrs_count)
|
int tnet_transport_dtls_do_handshake(tnet_transport_handle_t *handle, struct tnet_socket_s** sockets, tsk_size_t sockets_count, const struct sockaddr_storage** remote_addrs, tsk_size_t remote_addrs_count)
|
||||||
{
|
{
|
||||||
tnet_transport_t *transport = handle;
|
tnet_transport_t *transport = handle;
|
||||||
tsk_size_t i;
|
tsk_size_t i;
|
||||||
|
|
||||||
if(!transport || !sockets){
|
if (!transport || !sockets) {
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!transport->dtls.enabled){
|
if (!transport->dtls.enabled) {
|
||||||
TSK_DEBUG_ERROR("DTLS not enabled on this transport");
|
TSK_DEBUG_ERROR("DTLS not enabled on this transport");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sockets){
|
if (sockets) {
|
||||||
int ret;
|
int ret;
|
||||||
for(i = 0; i < sockets_count; ++i){
|
for (i = 0; i < sockets_count; ++i) {
|
||||||
if(sockets[i] && sockets[i]->dtlshandle){
|
if (sockets[i] && sockets[i]->dtlshandle) {
|
||||||
if((ret = tnet_dtls_socket_do_handshake(sockets[i]->dtlshandle,
|
if ((ret = tnet_dtls_socket_do_handshake(sockets[i]->dtlshandle,
|
||||||
(remote_addrs && i < remote_addrs_count) ? remote_addrs[i] : tsk_null)) != 0){
|
(remote_addrs && i < remote_addrs_count) ? remote_addrs[i] : tsk_null)) != 0){
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -651,6 +679,39 @@ int tnet_transport_dtls_do_handshake(tnet_transport_handle_t *handle, struct tne
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tnet_transport_dtls_get_handshakingdata(tnet_transport_handle_t* handle, const struct tnet_socket_s** sockets, tsk_size_t sockets_count, const void* data[], tsk_size_t size[])
|
||||||
|
{
|
||||||
|
tnet_transport_t *transport = handle;
|
||||||
|
tsk_size_t i;
|
||||||
|
|
||||||
|
if (!transport || !sockets) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!transport->dtls.enabled) {
|
||||||
|
TSK_DEBUG_ERROR("DTLS not enabled on this transport");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sockets) {
|
||||||
|
int ret;
|
||||||
|
for (i = 0; i < sockets_count; ++i) {
|
||||||
|
if (sockets[i] && sockets[i]->dtlshandle) {
|
||||||
|
if ((ret = tnet_dtls_socket_get_handshakingdata(sockets[i]->dtlshandle, &data[i], &size[i])) != 0){
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data[i] = tsk_null;
|
||||||
|
size[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
tnet_socket_type_t tnet_transport_get_type(const tnet_transport_handle_t *handle)
|
tnet_socket_type_t tnet_transport_get_type(const tnet_transport_handle_t *handle)
|
||||||
{
|
{
|
||||||
if(!handle){
|
if(!handle){
|
||||||
|
@ -795,13 +856,13 @@ int tnet_transport_shutdown(tnet_transport_handle_t* handle)
|
||||||
static int _tnet_transport_dtls_cb(const void* usrdata, tnet_dtls_socket_event_type_t dtls_e, const tnet_dtls_socket_handle_t* handle, const void* data, tsk_size_t size)
|
static int _tnet_transport_dtls_cb(const void* usrdata, tnet_dtls_socket_event_type_t dtls_e, const tnet_dtls_socket_handle_t* handle, const void* data, tsk_size_t size)
|
||||||
{
|
{
|
||||||
tnet_transport_t *transport = (tnet_transport_t*)usrdata;
|
tnet_transport_t *transport = (tnet_transport_t*)usrdata;
|
||||||
if(transport){
|
if (transport) {
|
||||||
tnet_transport_event_type_t t_e;
|
tnet_transport_event_type_t t_e;
|
||||||
const struct sockaddr_storage* remote_addr;
|
const struct sockaddr_storage* remote_addr;
|
||||||
tnet_fd_t fd;
|
tnet_fd_t fd;
|
||||||
tnet_transport_event_t* e;
|
tnet_transport_event_t* e;
|
||||||
|
|
||||||
switch(dtls_e){
|
switch (dtls_e) {
|
||||||
case tnet_dtls_socket_event_type_handshake_started: t_e = event_dtls_handshake_started; break;
|
case tnet_dtls_socket_event_type_handshake_started: t_e = event_dtls_handshake_started; break;
|
||||||
case tnet_dtls_socket_event_type_handshake_succeed: t_e = event_dtls_handshake_succeed; break;
|
case tnet_dtls_socket_event_type_handshake_succeed: t_e = event_dtls_handshake_succeed; break;
|
||||||
case tnet_dtls_socket_event_type_handshake_failed: t_e = event_dtls_handshake_failed; break;
|
case tnet_dtls_socket_event_type_handshake_failed: t_e = event_dtls_handshake_failed; break;
|
||||||
|
@ -813,15 +874,25 @@ static int _tnet_transport_dtls_cb(const void* usrdata, tnet_dtls_socket_event_t
|
||||||
}
|
}
|
||||||
remote_addr = tnet_dtls_socket_get_remote_addr(handle);
|
remote_addr = tnet_dtls_socket_get_remote_addr(handle);
|
||||||
fd = tnet_dtls_socket_get_fd(handle);
|
fd = tnet_dtls_socket_get_fd(handle);
|
||||||
if((e = tnet_transport_event_create(t_e, transport->callback_data, fd))){
|
if ((e = tnet_transport_event_create(t_e, transport->callback_data, fd))) {
|
||||||
if(data && size && (e ->data = tsk_malloc(size))){
|
if (data && size && (e ->data = tsk_malloc(size))) {
|
||||||
memcpy(e ->data, data, size);
|
memcpy(e ->data, data, size);
|
||||||
e->size = size;
|
e->size = size;
|
||||||
}
|
}
|
||||||
if(remote_addr){
|
if (remote_addr) {
|
||||||
e->remote_addr = *remote_addr;
|
e->remote_addr = *remote_addr;
|
||||||
}
|
}
|
||||||
|
if (TSK_RUNNABLE(transport)->initialized && TSK_RUNNABLE(transport)->running && TSK_RUNNABLE(transport)->started) {
|
||||||
TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(transport), e);
|
TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(transport), e);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TSK_DEBUG_INFO("Delivering network event synchronously.");
|
||||||
|
// network transport not started (happens when TURN is using the sockets instead of the RTP manager)
|
||||||
|
if (transport->callback) {
|
||||||
|
transport->callback(e);
|
||||||
|
}
|
||||||
|
TSK_OBJECT_SAFE_FREE(e);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -858,7 +929,7 @@ static void* TSK_STDCALL run(void* self)
|
||||||
if((curr = TSK_RUNNABLE_POP_FIRST_SAFE(TSK_RUNNABLE(transport)))){
|
if((curr = TSK_RUNNABLE_POP_FIRST_SAFE(TSK_RUNNABLE(transport)))){
|
||||||
const tnet_transport_event_t *e = (const tnet_transport_event_t*)curr->data;
|
const tnet_transport_event_t *e = (const tnet_transport_event_t*)curr->data;
|
||||||
|
|
||||||
if(transport->callback){
|
if (transport->callback) {
|
||||||
transport->callback(e);
|
transport->callback(e);
|
||||||
}
|
}
|
||||||
tsk_object_unref(curr);
|
tsk_object_unref(curr);
|
||||||
|
|
|
@ -85,7 +85,7 @@ TINYNET_API int tnet_transport_issecure(const tnet_transport_handle_t *handle);
|
||||||
TINYNET_API const char* tnet_transport_get_description(const tnet_transport_handle_t *handle);
|
TINYNET_API const char* tnet_transport_get_description(const tnet_transport_handle_t *handle);
|
||||||
TINYNET_API int tnet_transport_get_ip_n_port(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_ip_t *ip, tnet_port_t *port);
|
TINYNET_API int tnet_transport_get_ip_n_port(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_ip_t *ip, tnet_port_t *port);
|
||||||
TINYNET_API int tnet_transport_get_ip_n_port_2(const tnet_transport_handle_t *handle, tnet_ip_t *ip, tnet_port_t *port);
|
TINYNET_API int tnet_transport_get_ip_n_port_2(const tnet_transport_handle_t *handle, tnet_ip_t *ip, tnet_port_t *port);
|
||||||
TINYNET_API int tnet_transport_set_natt_ctx(tnet_transport_handle_t *handle, tnet_nat_context_handle_t* natt_ctx);
|
TINYNET_API int tnet_transport_set_natt_ctx(tnet_transport_handle_t *handle, struct tnet_nat_ctx_s* natt_ctx);
|
||||||
TINYNET_API int tnet_transport_get_public_ip_n_port(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_ip_t *ip, tnet_port_t *port);
|
TINYNET_API int tnet_transport_get_public_ip_n_port(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_ip_t *ip, tnet_port_t *port);
|
||||||
|
|
||||||
TINYNET_API int tnet_transport_isconnected(const tnet_transport_handle_t *handle, tnet_fd_t fd);
|
TINYNET_API int tnet_transport_isconnected(const tnet_transport_handle_t *handle, tnet_fd_t fd);
|
||||||
|
@ -109,7 +109,9 @@ TINYNET_API int tnet_transport_dtls_set_remote_fingerprint(tnet_transport_handle
|
||||||
TINYNET_API tsk_bool_t tnet_transport_dtls_is_enabled(const tnet_transport_handle_t *handle);
|
TINYNET_API tsk_bool_t tnet_transport_dtls_is_enabled(const tnet_transport_handle_t *handle);
|
||||||
TINYNET_API int tnet_transport_dtls_set_enabled(tnet_transport_handle_t *handle, tsk_bool_t enabled, struct tnet_socket_s** sockets, tsk_size_t sockets_count);
|
TINYNET_API int tnet_transport_dtls_set_enabled(tnet_transport_handle_t *handle, tsk_bool_t enabled, struct tnet_socket_s** sockets, tsk_size_t sockets_count);
|
||||||
TINYNET_API int tnet_transport_dtls_set_setup(tnet_transport_handle_t* handle, tnet_dtls_setup_t setup, struct tnet_socket_s** sockets, tsk_size_t sockets_count);
|
TINYNET_API int tnet_transport_dtls_set_setup(tnet_transport_handle_t* handle, tnet_dtls_setup_t setup, struct tnet_socket_s** sockets, tsk_size_t sockets_count);
|
||||||
|
TINYNET_API int tnet_transport_dtls_set_store_handshakingdata(tnet_transport_handle_t* handle, tsk_bool_t handshake_storedata, struct tnet_socket_s** sockets, tsk_size_t sockets_count);
|
||||||
TINYNET_API int tnet_transport_dtls_do_handshake(tnet_transport_handle_t *handle, struct tnet_socket_s** sockets, tsk_size_t sockets_count, const struct sockaddr_storage** remote_addrs, tsk_size_t remote_addrs_count);
|
TINYNET_API int tnet_transport_dtls_do_handshake(tnet_transport_handle_t *handle, struct tnet_socket_s** sockets, tsk_size_t sockets_count, const struct sockaddr_storage** remote_addrs, tsk_size_t remote_addrs_count);
|
||||||
|
TINYNET_API int tnet_transport_dtls_get_handshakingdata(tnet_transport_handle_t* handle, const struct tnet_socket_s** sockets, tsk_size_t sockets_count, const void* data[], tsk_size_t size[]);
|
||||||
|
|
||||||
TINYNET_API tnet_socket_type_t tnet_transport_get_type(const tnet_transport_handle_t *handle);
|
TINYNET_API tnet_socket_type_t tnet_transport_get_type(const tnet_transport_handle_t *handle);
|
||||||
TINYNET_API tnet_fd_t tnet_transport_get_master_fd(const tnet_transport_handle_t *handle);
|
TINYNET_API tnet_fd_t tnet_transport_get_master_fd(const tnet_transport_handle_t *handle);
|
||||||
|
@ -124,7 +126,7 @@ typedef struct tnet_transport_s
|
||||||
char* local_host;
|
char* local_host;
|
||||||
tnet_port_t req_local_port; // user requested local port
|
tnet_port_t req_local_port; // user requested local port
|
||||||
tnet_port_t bind_local_port; // local port on which we are listening (same as master socket)
|
tnet_port_t bind_local_port; // local port on which we are listening (same as master socket)
|
||||||
tnet_nat_context_handle_t* natt_ctx;
|
struct tnet_nat_ctx_s* natt_ctx;
|
||||||
tnet_socket_t *master;
|
tnet_socket_t *master;
|
||||||
|
|
||||||
tsk_object_t *context;
|
tsk_object_t *context;
|
||||||
|
@ -152,6 +154,7 @@ typedef struct tnet_transport_s
|
||||||
/* DTLS */
|
/* DTLS */
|
||||||
struct{
|
struct{
|
||||||
tsk_bool_t enabled;
|
tsk_bool_t enabled;
|
||||||
|
tsk_bool_t activated;
|
||||||
tsk_bool_t use_srtp;
|
tsk_bool_t use_srtp;
|
||||||
struct ssl_ctx_st *ctx;
|
struct ssl_ctx_st *ctx;
|
||||||
tnet_fingerprint_t fingerprints[TNET_DTLS_HASH_TYPE_MAX];
|
tnet_fingerprint_t fingerprints[TNET_DTLS_HASH_TYPE_MAX];
|
||||||
|
|
|
@ -714,15 +714,16 @@ void* TSK_STDCALL tnet_transport_mainthread(void *param)
|
||||||
|
|
||||||
if(ret){
|
if(ret){
|
||||||
ret = WSAGetLastError();
|
ret = WSAGetLastError();
|
||||||
if(ret == WSAEWOULDBLOCK){
|
if (ret == WSAEWOULDBLOCK) {
|
||||||
|
// Doesn't (always) mean congestion but... another thread is also poll()ing the FD. For example, when TURN session has a reference to the fd.
|
||||||
TSK_DEBUG_WARN("WSAEWOULDBLOCK error for READ SSESSION");
|
TSK_DEBUG_WARN("WSAEWOULDBLOCK error for READ SSESSION");
|
||||||
}
|
}
|
||||||
else if(ret == WSAECONNRESET && TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type)){
|
else if (ret == WSAECONNRESET && TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type)) {
|
||||||
/* For DGRAM ==> The sent packet gernerated "ICMP Destination/Port unreachable" result. */
|
/* For DGRAM ==> The sent packet gernerated "ICMP Destination/Port unreachable" result. */
|
||||||
TSK_FREE(wsaBuffer.buf);
|
TSK_FREE(wsaBuffer.buf);
|
||||||
goto done; // ignore and retry.
|
goto done; // ignore and retry.
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
TSK_FREE(wsaBuffer.buf);
|
TSK_FREE(wsaBuffer.buf);
|
||||||
|
|
||||||
removeSocket(index, context);
|
removeSocket(index, context);
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
* Copyright (C) 2010-2011 Mamadou Diop.
|
||||||
*
|
*
|
||||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
|
||||||
*
|
|
||||||
* This file is part of Open Source Doubango Framework.
|
* This file is part of Open Source Doubango Framework.
|
||||||
*
|
*
|
||||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
|
@ -23,9 +21,6 @@
|
||||||
/**@file tnet_types.h
|
/**@file tnet_types.h
|
||||||
* @brief ????.
|
* @brief ????.
|
||||||
*
|
*
|
||||||
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#ifndef TNET_TYPES_H
|
#ifndef TNET_TYPES_H
|
||||||
#define TNET_TYPES_H
|
#define TNET_TYPES_H
|
||||||
|
|
|
@ -1273,13 +1273,13 @@ int tnet_inet_pton(int af, const char* src, void* dst)
|
||||||
# if (_WIN32_WINNT <= 0x0501)
|
# if (_WIN32_WINNT <= 0x0501)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage addr = { 0 };
|
struct sockaddr_storage addr = { 0 };
|
||||||
int addr_len = sizeof(addr);
|
int addr_len = (af == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
|
||||||
if (WSAStringToAddressA((LPSTR)src, af, NULL, (struct sockaddr *)&addr, &addr_len) == 0) {
|
if (WSAStringToAddressA((LPSTR)src, af, NULL, (struct sockaddr *)&addr, &addr_len) == 0) {
|
||||||
if (af == AF_INET6) {
|
if (af == AF_INET6) {
|
||||||
*((struct in6_addr *)dst) = ((struct sockaddr_in6 *)&addr)->sin6_addr;
|
memcpy(dst, &((struct sockaddr_in6 *)&addr)->sin6_addr, 16);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*((struct in_addr *)dst) = ((struct sockaddr_in *)&addr)->sin_addr;
|
memcpy(dst, &((struct sockaddr_in *)&addr)->sin_addr, 4);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1287,7 +1287,7 @@ int tnet_inet_pton(int af, const char* src, void* dst)
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
return InetPton(af, src, dst);
|
return InetPtonA(af, src, dst);
|
||||||
# endif // TNET_UNDER_WINDOWS
|
# endif // TNET_UNDER_WINDOWS
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
|
@ -1329,16 +1329,16 @@ const char *tnet_inet_ntop(int af, const void *src, char *dst, int size)
|
||||||
TSK_DEBUG_ERROR("Destination size too short(%d)", size);
|
TSK_DEBUG_ERROR("Destination size too short(%d)", size);
|
||||||
return tsk_null;
|
return tsk_null;
|
||||||
}
|
}
|
||||||
addr.ss_family = AF_INET6;
|
((struct sockaddr_in6 *)&addr)->sin6_family = AF_INET6;
|
||||||
((struct sockaddr_in6 *)&addr)->sin6_addr = *((struct in6_addr *)src);
|
memcpy(&((struct sockaddr_in6 *)&addr)->sin6_addr, src, 16);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (size < INET_ADDRSTRLEN) {
|
if (size < INET_ADDRSTRLEN) {
|
||||||
TSK_DEBUG_ERROR("Destination size too short(%d)", size);
|
TSK_DEBUG_ERROR("Destination size too short(%d)", size);
|
||||||
return tsk_null;
|
return tsk_null;
|
||||||
}
|
}
|
||||||
addr.ss_family = AF_INET;
|
((struct sockaddr_in *)&addr)->sin_family = AF_INET;
|
||||||
((struct sockaddr_in *)&addr)->sin_addr = *((struct in_addr *)src);
|
memcpy(&((struct sockaddr_in *)&addr)->sin_addr, src, 4);
|
||||||
}
|
}
|
||||||
if (WSAAddressToStringA((struct sockaddr*)&addr, addr_len, NULL, dst, &size) == 0) {
|
if (WSAAddressToStringA((struct sockaddr*)&addr, addr_len, NULL, dst, &size) == 0) {
|
||||||
return dst;
|
return dst;
|
||||||
|
@ -1347,7 +1347,7 @@ const char *tnet_inet_ntop(int af, const void *src, char *dst, int size)
|
||||||
return tsk_null;
|
return tsk_null;
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
return InetNtop(af, src, dst, size);
|
return InetNtopA(af, (PVOID)src, dst, size);
|
||||||
# endif // TNET_UNDER_WINDOWS
|
# endif // TNET_UNDER_WINDOWS
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
|
@ -1637,6 +1637,34 @@ int tnet_sockfd_set_mode(tnet_fd_t fd, int nonBlocking)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**@ingroup tnet_utils_group
|
||||||
|
*/
|
||||||
|
int tnet_sockfd_reuseaddr(tnet_fd_t fd, int reuseAddr)
|
||||||
|
{
|
||||||
|
if (fd != TNET_INVALID_FD) {
|
||||||
|
int ret;
|
||||||
|
#if defined(SOLARIS)
|
||||||
|
static const char yes = '1';
|
||||||
|
static const char no = '0';
|
||||||
|
#else
|
||||||
|
static const int yes = 1;
|
||||||
|
static const int no = 0;
|
||||||
|
#endif
|
||||||
|
if ((ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*)(reuseAddr ? &yes : &no), sizeof(int)))) {
|
||||||
|
TNET_PRINT_LAST_ERROR("setsockopt(SO_REUSEADDR, fd=%d) have failed", fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#if defined(SO_REUSEPORT)
|
||||||
|
if ((ret = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char*)(reuseAddr ? &yes : &no), sizeof(int)))) {
|
||||||
|
TNET_PRINT_LAST_ERROR("setsockopt(SO_REUSEPORT, fd=%d) have failed", fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**@ingroup tnet_utils_group
|
/**@ingroup tnet_utils_group
|
||||||
* Sends data to a specific destination.
|
* Sends data to a specific destination.
|
||||||
* @param fd The source socket.
|
* @param fd The source socket.
|
||||||
|
|
|
@ -146,6 +146,7 @@ TINYNET_API int tnet_sockaddr_init(const char *host, tnet_port_t port, tnet_sock
|
||||||
TINYNET_API int tnet_sockfd_init(const char *host, tnet_port_t port, tnet_socket_type_t type, tnet_fd_t *fd);
|
TINYNET_API int tnet_sockfd_init(const char *host, tnet_port_t port, tnet_socket_type_t type, tnet_fd_t *fd);
|
||||||
|
|
||||||
TINYNET_API int tnet_sockfd_set_mode(tnet_fd_t fd, int nonBlocking);
|
TINYNET_API int tnet_sockfd_set_mode(tnet_fd_t fd, int nonBlocking);
|
||||||
|
TINYNET_API int tnet_sockfd_reuseaddr(tnet_fd_t fd, int reuseAddr);
|
||||||
#define tnet_sockfd_set_nonblocking(fd) tnet_sockfd_set_mode(fd, 1)
|
#define tnet_sockfd_set_nonblocking(fd) tnet_sockfd_set_mode(fd, 1)
|
||||||
#define tnet_sockfd_set_blocking(fd) tnet_sockfd_set_mode(fd, 0)
|
#define tnet_sockfd_set_blocking(fd) tnet_sockfd_set_mode(fd, 0)
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,175 +1,175 @@
|
||||||
/*
|
///*
|
||||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
//* Copyright (C) 2010-2011 Mamadou Diop.
|
||||||
*
|
//*
|
||||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
//*
|
||||||
* This file is part of Open Source Doubango Framework.
|
//* This file is part of Open Source Doubango Framework.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
//* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
//* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
//* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
//* (at your option) any later version.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is distributed in the hope that it will be useful,
|
//* DOUBANGO is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
//* GNU General Public License for more details.
|
||||||
*
|
//*
|
||||||
* You should have received a copy of the GNU General Public License
|
//* You should have received a copy of the GNU General Public License
|
||||||
* along with DOUBANGO.
|
//* along with DOUBANGO.
|
||||||
*
|
//*
|
||||||
*/
|
//*/
|
||||||
|
//
|
||||||
/**@file tnet_turn.h
|
///**@file tnet_turn.h
|
||||||
* @brief Traversal Using Relays around NAT (TURN) implementation as per 'draft-ietf-behave-turn-16', 'draft-ietf-behave-turn-tcp-05'
|
// * @brief Traversal Using Relays around NAT (TURN) implementation as per 'draft-ietf-behave-turn-16', 'draft-ietf-behave-turn-tcp-05'
|
||||||
* and 'draft-ietf-behave-turn-ipv6'.
|
// * and 'draft-ietf-behave-turn-ipv6'.
|
||||||
* http://tools.ietf.org/html/draft-ietf-behave-turn-16
|
// * http://tools.ietf.org/html/draft-ietf-behave-turn-16
|
||||||
* http://tools.ietf.org/html/draft-ietf-behave-turn-tcp-05
|
// * http://tools.ietf.org/html/draft-ietf-behave-turn-tcp-05
|
||||||
* http://tools.ietf.org/html/draft-ietf-behave-turn-ipv6-07
|
// * http://tools.ietf.org/html/draft-ietf-behave-turn-ipv6-07
|
||||||
*
|
// *
|
||||||
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
// * @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
// *
|
||||||
|
//
|
||||||
*/
|
// */
|
||||||
#ifndef TNET_TURN_H
|
//#ifndef TNET_TURN_H
|
||||||
#define TNET_TURN_H
|
//#define TNET_TURN_H
|
||||||
|
//
|
||||||
#include "tinynet_config.h"
|
//#include "tinynet_config.h"
|
||||||
|
//
|
||||||
#include "turn/tnet_turn_attribute.h"
|
//#include "turn/tnet_turn_attribute.h"
|
||||||
|
//
|
||||||
#include "tnet_proto.h"
|
//#include "tnet_proto.h"
|
||||||
#include "tnet_socket.h"
|
//#include "tnet_socket.h"
|
||||||
#include "tnet_types.h"
|
//#include "tnet_types.h"
|
||||||
|
//
|
||||||
#include "tsk_object.h"
|
//#include "tsk_object.h"
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* @def TNET_TURN_PERMISSION_TIMEOUT_DEFAULT
|
//* @def TNET_TURN_PERMISSION_TIMEOUT_DEFAULT
|
||||||
*/
|
//*/
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* @def TNET_TURN_CHANBIND_TIMEOUT_DEFAULT
|
//* @def TNET_TURN_CHANBIND_TIMEOUT_DEFAULT
|
||||||
*/
|
//*/
|
||||||
TNET_BEGIN_DECLS
|
//TNET_BEGIN_DECLS
|
||||||
|
//
|
||||||
#define TNET_TURN_PERMISSION_TIMEOUT_DEFAULT 300 /* draft-ietf-behave-turn-16 subclause 8 */
|
//#define TNET_TURN_PERMISSION_TIMEOUT_DEFAULT 300 /* draft-ietf-behave-turn-16 subclause 8 */
|
||||||
#define TNET_TURN_CHANBIND_TIMEOUT_DEFAULT 600 /* draft-ietf-behave-turn-16 subclause 11 */
|
//#define TNET_TURN_CHANBIND_TIMEOUT_DEFAULT 600 /* draft-ietf-behave-turn-16 subclause 11 */
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* @def tnet_turn_allocation_id_t.
|
//* @def tnet_turn_allocation_id_t.
|
||||||
*/
|
//*/
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* @def TNET_TURN_INVALID_ALLOCATION_ID.
|
//* @def TNET_TURN_INVALID_ALLOCATION_ID.
|
||||||
*/
|
//*/
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* @def TNET_TURN_IS_VALID_ALLOCATION_ID.
|
//* @def TNET_TURN_IS_VALID_ALLOCATION_ID.
|
||||||
*/
|
//*/
|
||||||
typedef uint64_t tnet_turn_allocation_id_t;
|
//typedef uint64_t tnet_turn_allocation_id_t;
|
||||||
#define TNET_TURN_INVALID_ALLOCATION_ID 0
|
//#define TNET_TURN_INVALID_ALLOCATION_ID 0
|
||||||
#define TNET_TURN_IS_VALID_ALLOCATION_ID(id) (id != TNET_TURN_INVALID_ALLOCATION_ID)
|
//#define TNET_TURN_IS_VALID_ALLOCATION_ID(id) (id != TNET_TURN_INVALID_ALLOCATION_ID)
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* @def tnet_turn_channel_binding_id_t.
|
//* @def tnet_turn_channel_binding_id_t.
|
||||||
*/
|
//*/
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* @def TNET_TURN_INVALID_CHANNEL_BINDING_ID.
|
//* @def TNET_TURN_INVALID_CHANNEL_BINDING_ID.
|
||||||
*/
|
//*/
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* @def TNET_TURN_IS_VALID_CHANNEL_BINDING_ID.
|
//* @def TNET_TURN_IS_VALID_CHANNEL_BINDING_ID.
|
||||||
*/
|
//*/
|
||||||
typedef uint16_t tnet_turn_channel_binding_id_t;
|
//typedef uint16_t tnet_turn_channel_binding_id_t;
|
||||||
#define TNET_TURN_INVALID_CHANNEL_BINDING_ID 0x00
|
//#define TNET_TURN_INVALID_CHANNEL_BINDING_ID 0x00
|
||||||
#define TNET_TURN_IS_VALID_CHANNEL_BINDING_ID(id) ( (0x4000 <= id) && (id <= 0x7FFF) ) /* see draft-ietf-behave-turn-16 subcaluse 11. */
|
//#define TNET_TURN_IS_VALID_CHANNEL_BINDING_ID(id) ( (0x4000 <= id) && (id <= 0x7FFF) ) /* see draft-ietf-behave-turn-16 subcaluse 11. */
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_turn_permission_s
|
//typedef struct tnet_turn_permission_s
|
||||||
{
|
//{
|
||||||
TSK_DECLARE_OBJECT;
|
// TSK_DECLARE_OBJECT;
|
||||||
|
//
|
||||||
tnet_turn_attribute_xpeer_addr_t *xpeer;
|
// tnet_turn_attribute_xpeer_addr_t *xpeer;
|
||||||
uint32_t timeout; /**< Timeout value in seconds. Default is 300s(5 minutes). */
|
// uint32_t timeout; /**< Timeout value in seconds. Default is 300s(5 minutes). */
|
||||||
}
|
//}
|
||||||
tnet_turn_permission_t;
|
//tnet_turn_permission_t;
|
||||||
typedef tsk_list_t tnet_turn_permissions_L_t; /**< List of @ref tnet_turn_permission_t elements. */
|
//typedef tsk_list_t tnet_turn_permissions_L_t; /**< List of @ref tnet_turn_permission_t elements. */
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_turn_channel_binding_s
|
//typedef struct tnet_turn_channel_binding_s
|
||||||
{
|
//{
|
||||||
TSK_DECLARE_OBJECT;
|
// TSK_DECLARE_OBJECT;
|
||||||
|
//
|
||||||
tnet_turn_channel_binding_id_t id;
|
// tnet_turn_channel_binding_id_t id;
|
||||||
const struct tnet_turn_allocation_s *allocation;
|
// const struct tnet_turn_allocation_s *allocation;
|
||||||
tnet_turn_attribute_xpeer_addr_t *xpeer;
|
// tnet_turn_attribute_xpeer_addr_t *xpeer;
|
||||||
uint32_t timeout; /**< Timeout value in seconds. Default is 600s(10 minutes). */
|
// uint32_t timeout; /**< Timeout value in seconds. Default is 600s(10 minutes). */
|
||||||
}
|
//}
|
||||||
tnet_turn_channel_binding_t;
|
//tnet_turn_channel_binding_t;
|
||||||
typedef tsk_list_t tnet_turn_channel_bindings_L_t; /**< List of @ref tnet_turn_channel_binding_t elements. */
|
//typedef tsk_list_t tnet_turn_channel_bindings_L_t; /**< List of @ref tnet_turn_channel_binding_t elements. */
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_turn_allocation_s
|
//typedef struct tnet_turn_allocation_s
|
||||||
{
|
//{
|
||||||
TSK_DECLARE_OBJECT;
|
// TSK_DECLARE_OBJECT;
|
||||||
|
//
|
||||||
tnet_turn_allocation_id_t id; /**< Unique id. */
|
// tnet_turn_allocation_id_t id; /**< Unique id. */
|
||||||
|
//
|
||||||
char* relay_address; /**< the relayed transport address */
|
// char* relay_address; /**< the relayed transport address */
|
||||||
//! Server reflexive address of the local socket(STUN1 as per RFC 3489).
|
// //! Server reflexive address of the local socket(STUN1 as per RFC 3489).
|
||||||
tnet_stun_attribute_mapped_addr_t *maddr;
|
// tnet_stun_attribute_mapped_addr_t *maddr;
|
||||||
//! XORed server reflexive address (STUN2 as per RFC 5389).
|
// //! XORed server reflexive address (STUN2 as per RFC 5389).
|
||||||
tnet_stun_attribute_xmapped_addr_t *xmaddr;
|
// tnet_stun_attribute_xmapped_addr_t *xmaddr;
|
||||||
|
//
|
||||||
/* 5-tuple */
|
// /* 5-tuple */
|
||||||
tnet_fd_t localFD;
|
// tnet_fd_t localFD;
|
||||||
tnet_socket_type_t socket_type;
|
// tnet_socket_type_t socket_type;
|
||||||
|
//
|
||||||
struct sockaddr_storage server;
|
// struct sockaddr_storage server;
|
||||||
|
//
|
||||||
/*---*/
|
// /*---*/
|
||||||
|
//
|
||||||
/* the authentication information */
|
// /* the authentication information */
|
||||||
char* username;
|
// char* username;
|
||||||
char* password;
|
// char* password;
|
||||||
char* realm;
|
// char* realm;
|
||||||
char* nonce;
|
// char* nonce;
|
||||||
/*---*/
|
// /*---*/
|
||||||
|
//
|
||||||
/* the time-to-expiry */
|
// /* the time-to-expiry */
|
||||||
uint32_t timeout; /**< Timeout value in seconds. Default is 600s(10 minutes). */
|
// uint32_t timeout; /**< Timeout value in seconds. Default is 600s(10 minutes). */
|
||||||
/*---*/
|
// /*---*/
|
||||||
|
//
|
||||||
/* A list of permissions */
|
// /* A list of permissions */
|
||||||
/* A list of channel to peer bindings */
|
// /* A list of channel to peer bindings */
|
||||||
|
//
|
||||||
char* software;
|
// char* software;
|
||||||
|
//
|
||||||
tnet_turn_channel_bindings_L_t *channel_bindings;
|
// tnet_turn_channel_bindings_L_t *channel_bindings;
|
||||||
tnet_turn_permissions_L_t *permissions;
|
// tnet_turn_permissions_L_t *permissions;
|
||||||
}
|
//}
|
||||||
tnet_turn_allocation_t;
|
//tnet_turn_allocation_t;
|
||||||
typedef tsk_list_t tnet_turn_allocations_L_t; /**< List of @ref tnet_turn_allocation_t elements. */
|
//typedef tsk_list_t tnet_turn_allocations_L_t; /**< List of @ref tnet_turn_allocation_t elements. */
|
||||||
|
//
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_permission_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_permission_def_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_channel_binding_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_channel_binding_def_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_allocation_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_allocation_def_t;
|
||||||
|
//
|
||||||
//#if defined(__SYMBIAN32__) || ANDROID /* Forward declaration */
|
////#if defined(__SYMBIAN32__) || ANDROID /* Forward declaration */
|
||||||
struct tnet_nat_context_s;
|
//struct struct tnet_nat_ctx_s;
|
||||||
//#endif
|
////#endif
|
||||||
|
//
|
||||||
tnet_turn_allocation_id_t tnet_turn_allocate(const struct tnet_nat_context_s* nat_context, const tnet_fd_t localFD, tnet_socket_type_t socket_type);
|
//tnet_turn_allocation_id_t tnet_turn_allocate(const struct struct tnet_nat_ctx_s* nat_context, const tnet_fd_t localFD, tnet_socket_type_t socket_type);
|
||||||
int tnet_turn_allocation_refresh(const struct tnet_nat_context_s* nat_context, tnet_turn_allocation_t *allocation);
|
//int tnet_turn_allocation_refresh(const struct struct tnet_nat_ctx_s* nat_context, tnet_turn_allocation_t *allocation);
|
||||||
int tnet_turn_unallocate(const struct tnet_nat_context_s* nat_context, tnet_turn_allocation_t *allocation);
|
//int tnet_turn_unallocate(const struct struct tnet_nat_ctx_s* nat_context, tnet_turn_allocation_t *allocation);
|
||||||
tnet_turn_channel_binding_id_t tnet_turn_channel_bind(const struct tnet_nat_context_s* nat_context, tnet_turn_allocation_t *allocation, struct sockaddr_storage *peer);
|
//tnet_turn_channel_binding_id_t tnet_turn_channel_bind(const struct struct tnet_nat_ctx_s* nat_context, tnet_turn_allocation_t *allocation, struct sockaddr_storage *peer);
|
||||||
int tnet_turn_channel_refresh(const struct tnet_nat_context_s* nat_context, const tnet_turn_channel_binding_t * channel_bind);
|
//int tnet_turn_channel_refresh(const struct struct tnet_nat_ctx_s* nat_context, const tnet_turn_channel_binding_t * channel_bind);
|
||||||
int tnet_turn_channel_senddata(const struct tnet_nat_context_s* nat_context, const tnet_turn_channel_binding_t * channel_bind, const void* data, tsk_size_t size, int indication);
|
//int tnet_turn_channel_senddata(const struct struct tnet_nat_ctx_s* nat_context, const tnet_turn_channel_binding_t * channel_bind, const void* data, tsk_size_t size, int indication);
|
||||||
int tnet_turn_add_permission(const struct tnet_nat_context_s* nat_context, tnet_turn_allocation_t *allocation, const char* ipaddress, uint32_t timeout);
|
//int tnet_turn_add_permission(const struct struct tnet_nat_ctx_s* nat_context, tnet_turn_allocation_t *allocation, const char* ipaddress, uint32_t timeout);
|
||||||
|
//
|
||||||
|
//
|
||||||
TNET_END_DECLS
|
//TNET_END_DECLS
|
||||||
|
//
|
||||||
#endif /* TNET_TURN_H */
|
//#endif /* TNET_TURN_H */
|
||||||
|
//
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
/* Copyright (C) 2014 Mamadou DIOP.
|
///* Copyright (C) 2014 Mamadou DIOP.
|
||||||
*
|
//*
|
||||||
* This file is part of Open Source Doubango Framework.
|
//* This file is part of Open Source Doubango Framework.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
//* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
//* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
//* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
//* (at your option) any later version.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is distributed in the hope that it will be useful,
|
//* DOUBANGO is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Lesser General Public License for more details.
|
//* GNU Lesser General Public License for more details.
|
||||||
*
|
//*
|
||||||
* You should have received a copy of the GNU General Public License
|
//* You should have received a copy of the GNU General Public License
|
||||||
* along with DOUBANGO.
|
//* along with DOUBANGO.
|
||||||
*
|
//*
|
||||||
*/
|
//*/
|
||||||
#include "turn/tnet_turn_attr.h"
|
//#include "turn/tnet_turn_attr.h"
|
||||||
|
//
|
||||||
#include "tsk_debug.h"
|
//#include "tsk_debug.h"
|
|
@ -1,32 +1,32 @@
|
||||||
/* Copyright (C) 2014 Mamadou DIOP.
|
///* Copyright (C) 2014 Mamadou DIOP.
|
||||||
*
|
//*
|
||||||
* This file is part of Open Source Doubango Framework.
|
//* This file is part of Open Source Doubango Framework.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
//* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
//* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
//* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
//* (at your option) any later version.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is distributed in the hope that it will be useful,
|
//* DOUBANGO is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Lesser General Public License for more details.
|
//* GNU Lesser General Public License for more details.
|
||||||
*
|
//*
|
||||||
* You should have received a copy of the GNU General Public License
|
//* You should have received a copy of the GNU General Public License
|
||||||
* along with DOUBANGO.
|
//* along with DOUBANGO.
|
||||||
*
|
//*
|
||||||
*/
|
//*/
|
||||||
#ifndef TNET_TURN_ATTR_H
|
//#ifndef TNET_TURN_ATTR_H
|
||||||
#define TNET_TURN_ATTR_H
|
//#define TNET_TURN_ATTR_H
|
||||||
|
//
|
||||||
#include "tinynet_config.h"
|
//#include "tinynet_config.h"
|
||||||
#include "stun/tnet_stun_types.h"
|
//#include "stun/tnet_stun_types.h"
|
||||||
|
//
|
||||||
#include "tsk_object.h"
|
//#include "tsk_object.h"
|
||||||
#include "tsk_list.h"
|
//#include "tsk_list.h"
|
||||||
|
//
|
||||||
TNET_BEGIN_DECLS
|
//TNET_BEGIN_DECLS
|
||||||
|
//
|
||||||
TNET_END_DECLS
|
//TNET_END_DECLS
|
||||||
|
//
|
||||||
#endif /* TNET_TURN_ATTR_H */
|
//#endif /* TNET_TURN_ATTR_H */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,196 +1,196 @@
|
||||||
/*
|
///*
|
||||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
//* Copyright (C) 2010-2011 Mamadou Diop.
|
||||||
*
|
//*
|
||||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
//*
|
||||||
* This file is part of Open Source Doubango Framework.
|
//* This file is part of Open Source Doubango Framework.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
//* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
//* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
//* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
//* (at your option) any later version.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is distributed in the hope that it will be useful,
|
//* DOUBANGO is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
//* GNU General Public License for more details.
|
||||||
*
|
//*
|
||||||
* You should have received a copy of the GNU General Public License
|
//* You should have received a copy of the GNU General Public License
|
||||||
* along with DOUBANGO.
|
//* along with DOUBANGO.
|
||||||
*
|
//*
|
||||||
*/
|
//*/
|
||||||
|
//
|
||||||
/**@file tnet_turn_attribute.h
|
///**@file tnet_turn_attribute.h
|
||||||
* @brief New STUN Attributes as per draft-ietf-behave-turn-16 subclause 14.
|
// * @brief New STUN Attributes as per draft-ietf-behave-turn-16 subclause 14.
|
||||||
*
|
// *
|
||||||
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
// * @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
// *
|
||||||
|
//
|
||||||
*/
|
// */
|
||||||
#ifndef TNET_TURN_ATTRIBUTE_H
|
//#ifndef TNET_TURN_ATTRIBUTE_H
|
||||||
#define TNET_TURN_ATTRIBUTE_H
|
//#define TNET_TURN_ATTRIBUTE_H
|
||||||
|
//
|
||||||
#include "tinynet_config.h"
|
//#include "tinynet_config.h"
|
||||||
#include "tnet_proto.h"
|
//#include "tnet_proto.h"
|
||||||
#include "stun/tnet_stun_attribute.h"
|
//#include "stun/tnet_stun_attribute.h"
|
||||||
|
//
|
||||||
TNET_BEGIN_DECLS
|
//TNET_BEGIN_DECLS
|
||||||
|
//
|
||||||
typedef tnet_stun_attribute_t tnet_turn_attribute_t;
|
//typedef tnet_stun_attr_t tnet_turn_attribute_t;
|
||||||
|
//
|
||||||
/* draft-ietf-behave-turn-16 - 14.1. CHANNEL-NUMBER
|
///* draft-ietf-behave-turn-16 - 14.1. CHANNEL-NUMBER
|
||||||
0 1 2 3
|
// 0 1 2 3
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Channel Number | RFFU = 0 |
|
// | Channel Number | RFFU = 0 |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*/
|
//*/
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_turn_attribute_channelnum_s
|
//typedef struct tnet_turn_attribute_channelnum_s
|
||||||
{
|
//{
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
uint16_t number;
|
// uint16_t number;
|
||||||
uint16_t rffu;
|
// uint16_t rffu;
|
||||||
}
|
//}
|
||||||
tnet_turn_attribute_channelnum_t;
|
//tnet_turn_attribute_channelnum_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_channelnum_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_channelnum_def_t;
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* draft-ietf-behave-turn-16 - 14.2. LIFETIME
|
//* draft-ietf-behave-turn-16 - 14.2. LIFETIME
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_turn_attribute_lifetime_s
|
//typedef struct tnet_turn_attribute_lifetime_s
|
||||||
{
|
//{
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
uint32_t value;
|
// uint32_t value;
|
||||||
}
|
//}
|
||||||
tnet_turn_attribute_lifetime_t;
|
//tnet_turn_attribute_lifetime_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_lifetime_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_lifetime_def_t;
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* draft-ietf-behave-turn-16 - 14.3. XOR-PEER-ADDRESS
|
//* draft-ietf-behave-turn-16 - 14.3. XOR-PEER-ADDRESS
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_turn_attribute_xpeer_addr_s
|
//typedef struct tnet_turn_attribute_xpeer_addr_s
|
||||||
{
|
//{
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
tnet_stun_addr_family_t family;
|
// tnet_stun_addr_family_t family;
|
||||||
uint16_t xport;
|
// uint16_t xport;
|
||||||
uint8_t xaddress[16];
|
// uint8_t xaddress[16];
|
||||||
}
|
//}
|
||||||
tnet_turn_attribute_xpeer_addr_t;
|
//tnet_turn_attribute_xpeer_addr_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_xpeer_addr_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_xpeer_addr_def_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* draft-ietf-behave-turn-16 - 14.4. DATA
|
//* draft-ietf-behave-turn-16 - 14.4. DATA
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_turn_attribute_data_s
|
//typedef struct tnet_turn_attribute_data_s
|
||||||
{
|
//{
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
tsk_buffer_t* value;
|
// tsk_buffer_t* value;
|
||||||
}
|
//}
|
||||||
tnet_turn_attribute_data_t;
|
//tnet_turn_attribute_data_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_data_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_data_def_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* draft-ietf-behave-turn-16 - 14.5. XOR-RELAYED-ADDRESS
|
//* draft-ietf-behave-turn-16 - 14.5. XOR-RELAYED-ADDRESS
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_turn_attribute_xrelayed_addr_s
|
//typedef struct tnet_turn_attribute_xrelayed_addr_s
|
||||||
{
|
//{
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
tnet_stun_addr_family_t family;
|
// tnet_stun_addr_family_t family;
|
||||||
uint16_t xport;
|
// uint16_t xport;
|
||||||
uint8_t xaddress[16];
|
// uint8_t xaddress[16];
|
||||||
}
|
//}
|
||||||
tnet_turn_attribute_xrelayed_addr_t;
|
//tnet_turn_attribute_xrelayed_addr_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_xrelayed_addr_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_xrelayed_addr_def_t;
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* draft-ietf-behave-turn-16 - 14.6. EVEN-PORT
|
//* draft-ietf-behave-turn-16 - 14.6. EVEN-PORT
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_turn_attribute_even_port_s
|
//typedef struct tnet_turn_attribute_even_port_s
|
||||||
{
|
//{
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
/*
|
///*
|
||||||
0 1 2 3 4 5 6 7
|
// 0 1 2 3 4 5 6 7
|
||||||
+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
|R| RFFU |
|
// |R| RFFU |
|
||||||
+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
*/
|
//*/
|
||||||
unsigned R:1;
|
// unsigned R:1;
|
||||||
unsigned rffu:7;
|
// unsigned rffu:7;
|
||||||
}
|
//}
|
||||||
tnet_turn_attribute_even_port_t;
|
//tnet_turn_attribute_even_port_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_even_port_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_even_port_def_t;
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_turn_attribute_reqtrans_s
|
//typedef struct tnet_turn_attribute_reqtrans_s
|
||||||
{
|
//{
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
/*
|
///*
|
||||||
draft-ietf-behave-turn-16 - 14.7. REQUESTED-TRANSPORT
|
// draft-ietf-behave-turn-16 - 14.7. REQUESTED-TRANSPORT
|
||||||
0 1 2 3
|
// 0 1 2 3
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Protocol | RFFU |
|
// | Protocol | RFFU |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*/
|
//*/
|
||||||
tnet_proto_t protocol;
|
// tnet_proto_t protocol;
|
||||||
uint8_t rffu[3];
|
// uint8_t rffu[3];
|
||||||
}
|
//}
|
||||||
tnet_turn_attribute_reqtrans_t;
|
//tnet_turn_attribute_reqtrans_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_reqtrans_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_reqtrans_def_t;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* draft-ietf-behave-turn-16 - 14.8. DONT-FRAGMENT
|
//* draft-ietf-behave-turn-16 - 14.8. DONT-FRAGMENT
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_turn_attribute_dontfrag_s
|
//typedef struct tnet_turn_attribute_dontfrag_s
|
||||||
{
|
//{
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
}
|
//}
|
||||||
tnet_turn_attribute_dontfrag_t;
|
//tnet_turn_attribute_dontfrag_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_dontfrag_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_dontfrag_def_t;
|
||||||
|
//
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* draft-ietf-behave-turn-16 - 14.9. RESERVATION-TOKEN
|
//* draft-ietf-behave-turn-16 - 14.9. RESERVATION-TOKEN
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_turn_attribute_restoken_s
|
//typedef struct tnet_turn_attribute_restoken_s
|
||||||
{
|
//{
|
||||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
// TNET_STUN_DECLARE_ATTRIBUTE;
|
||||||
|
//
|
||||||
uint8_t value[8];
|
// uint8_t value[8];
|
||||||
}
|
//}
|
||||||
tnet_turn_attribute_restoken_t;
|
//tnet_turn_attribute_restoken_t;
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_restoken_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_attribute_restoken_def_t;
|
||||||
|
//
|
||||||
|
//
|
||||||
tnet_stun_attribute_t* tnet_turn_attribute_deserialize(tnet_stun_attribute_type_t type, uint16_t length, const void* payload, tsk_size_t payload_size);
|
//tnet_stun_attr_t* tnet_turn_attribute_deserialize(tnet_stun_attr_type_t type, uint16_t length, const void* payload, tsk_size_t payload_size);
|
||||||
int tnet_turn_attribute_serialize(const tnet_stun_attribute_t* attribute, tsk_buffer_t *output);
|
//int tnet_turn_attribute_serialize(const tnet_stun_attr_t* attribute, tsk_buffer_t *output);
|
||||||
|
//
|
||||||
tnet_turn_attribute_channelnum_t* tnet_turn_attribute_channelnum_create(uint16_t number);
|
//tnet_turn_attribute_channelnum_t* tnet_turn_attribute_channelnum_create(uint16_t number);
|
||||||
tnet_turn_attribute_lifetime_t* tnet_turn_attribute_lifetime_create(uint32_t lifetime);
|
//tnet_turn_attribute_lifetime_t* tnet_turn_attribute_lifetime_create(uint32_t lifetime);
|
||||||
tnet_turn_attribute_xpeer_addr_t* tnet_turn_attribute_xpeer_addr_create(const void* payload, tsk_size_t payload_size);
|
//tnet_turn_attribute_xpeer_addr_t* tnet_turn_attribute_xpeer_addr_create(const void* payload, tsk_size_t payload_size);
|
||||||
tnet_turn_attribute_xpeer_addr_t* tnet_turn_attribute_xpeer_addr_create_null();
|
//tnet_turn_attribute_xpeer_addr_t* tnet_turn_attribute_xpeer_addr_create_null();
|
||||||
tnet_turn_attribute_data_t* tnet_turn_attribute_data_create(const void* payload, tsk_size_t payload_size);
|
//tnet_turn_attribute_data_t* tnet_turn_attribute_data_create(const void* payload, tsk_size_t payload_size);
|
||||||
tnet_turn_attribute_xrelayed_addr_t* tnet_turn_attribute_xrelayed_addr_create(const void* payload, tsk_size_t payload_size);
|
//tnet_turn_attribute_xrelayed_addr_t* tnet_turn_attribute_xrelayed_addr_create(const void* payload, tsk_size_t payload_size);
|
||||||
tnet_turn_attribute_even_port_t* tnet_turn_attribute_even_port_create(unsigned R);
|
//tnet_turn_attribute_even_port_t* tnet_turn_attribute_even_port_create(unsigned R);
|
||||||
tnet_turn_attribute_reqtrans_t* tnet_turn_attribute_reqtrans_create(tnet_proto_t protocol);
|
//tnet_turn_attribute_reqtrans_t* tnet_turn_attribute_reqtrans_create(tnet_proto_t protocol);
|
||||||
tnet_turn_attribute_dontfrag_t* tnet_turn_attribute_dontfrag_create();
|
//tnet_turn_attribute_dontfrag_t* tnet_turn_attribute_dontfrag_create();
|
||||||
tnet_turn_attribute_restoken_t* tnet_turn_attribute_restoken_create(const void* payload, tsk_size_t payload_size);
|
//tnet_turn_attribute_restoken_t* tnet_turn_attribute_restoken_create(const void* payload, tsk_size_t payload_size);
|
||||||
|
//
|
||||||
TNET_END_DECLS
|
//TNET_END_DECLS
|
||||||
|
//
|
||||||
#endif /* TNET_TURN_ATTRIBUTE_H */
|
//#endif /* TNET_TURN_ATTRIBUTE_H */
|
||||||
|
//
|
||||||
|
|
|
@ -1,163 +1,163 @@
|
||||||
/*
|
///*
|
||||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
//* Copyright (C) 2010-2011 Mamadou Diop.
|
||||||
*
|
//*
|
||||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
//*
|
||||||
* This file is part of Open Source Doubango Framework.
|
//* This file is part of Open Source Doubango Framework.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
//* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
//* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
//* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
//* (at your option) any later version.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is distributed in the hope that it will be useful,
|
//* DOUBANGO is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
//* GNU General Public License for more details.
|
||||||
*
|
//*
|
||||||
* You should have received a copy of the GNU General Public License
|
//* You should have received a copy of the GNU General Public License
|
||||||
* along with DOUBANGO.
|
//* along with DOUBANGO.
|
||||||
*
|
//*
|
||||||
*/
|
//*/
|
||||||
|
|
||||||
/**@file tnet_turn_message.c
|
|
||||||
* @brief Traversal Using Relays around NAT (TURN) messages.
|
|
||||||
*
|
|
||||||
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
|
||||||
#include "tnet_turn_message.h"
|
|
||||||
|
|
||||||
#include "../tnet_types.h"
|
|
||||||
#include "../tnet_endianness.h"
|
|
||||||
|
|
||||||
#include "tsk_memory.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
tnet_turn_channel_data_t* tnet_turn_channel_data_create(uint16_t number, uint16_t length, const void* data)
|
|
||||||
{
|
|
||||||
return tsk_object_new(tnet_turn_channel_data_def_t, number, length, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
tnet_turn_channel_data_t* tnet_turn_channel_data_create_null()
|
|
||||||
{
|
|
||||||
return tnet_turn_channel_data_create(0, 0, tsk_null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@ingroup tnet_turn_group
|
|
||||||
*/
|
|
||||||
tsk_buffer_t* tnet_turn_channel_data_serialize(const tnet_turn_channel_data_t *message)
|
|
||||||
{
|
|
||||||
tsk_buffer_t *output = 0;
|
|
||||||
|
|
||||||
if(!message) goto bail;
|
|
||||||
|
|
||||||
output = tsk_buffer_create_null();
|
|
||||||
|
|
||||||
/* draft-ietf-behave-turn-16 11.4. The ChannelData Message
|
|
||||||
0 1 2 3
|
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
| Channel Number | Length |
|
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
| |
|
|
||||||
/ Application Data /
|
|
||||||
/ /
|
|
||||||
| |
|
|
||||||
| +-------------------------------+
|
|
||||||
| |
|
|
||||||
+-------------------------------+
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Channel Number
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
uint16_t number = tnet_htons(message->chanel_number);
|
|
||||||
tsk_buffer_append(output, &(number), 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Length
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
uint16_t length = tnet_htons(message->length);
|
|
||||||
tsk_buffer_append(output, &(length), 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Application Data
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
tsk_buffer_append(output, message->data, message->length);
|
|
||||||
|
|
||||||
/* === Padding:
|
|
||||||
Over stream transports, the ChannelData message MUST be padded to a
|
|
||||||
multiple of four bytes in order to ensure the alignment of subsequent
|
|
||||||
messages. The padding is not reflected in the length field of the
|
|
||||||
ChannelData message, so the actual size of a ChannelData message
|
|
||||||
(including padding) is (4 + Length) rounded up to the nearest
|
|
||||||
multiple of 4. Over UDP, the padding is not required but MAY be included.
|
|
||||||
*/
|
|
||||||
if(message->length%4)
|
|
||||||
{
|
|
||||||
static uint32_t zeros = 0x00000000;
|
|
||||||
tsk_buffer_append(output, &zeros, 4-(message->length%4));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bail:
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=================================================================================================
|
|
||||||
// TURN CHANNEL-DATA message object definition
|
|
||||||
//
|
//
|
||||||
static tsk_object_t* tnet_turn_channel_data_ctor(tsk_object_t * self, va_list * app)
|
///**@file tnet_turn_message.c
|
||||||
{
|
// * @brief Traversal Using Relays around NAT (TURN) messages.
|
||||||
tnet_turn_channel_data_t *message = self;
|
// *
|
||||||
if(message){
|
// * @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
const void* data;
|
// *
|
||||||
message->chanel_number = tsk_va_arg_u16(*app);
|
//
|
||||||
message->length = tsk_va_arg_u16(*app);
|
// */
|
||||||
data = va_arg(*app, const void*);
|
//#include "tnet_turn_message.h"
|
||||||
if(data && message->length){
|
//
|
||||||
if((message->data = tsk_calloc(message->length, sizeof(uint8_t)))){
|
//#include "../tnet_types.h"
|
||||||
memcpy(message->data, data, message->length);
|
//#include "../tnet_endianness.h"
|
||||||
}
|
//
|
||||||
}
|
//#include "tsk_memory.h"
|
||||||
}
|
//
|
||||||
return self;
|
//#include <string.h>
|
||||||
}
|
//
|
||||||
|
//tnet_turn_channel_data_t* tnet_turn_channel_data_create(uint16_t number, uint16_t length, const void* data)
|
||||||
static tsk_object_t* tnet_turn_channel_data_dtor(tsk_object_t * self)
|
//{
|
||||||
{
|
// return tsk_object_new(tnet_turn_channel_data_def_t, number, length, data);
|
||||||
tnet_turn_channel_data_t *message = self;
|
//}
|
||||||
if(message){
|
//
|
||||||
TSK_FREE(message->data);
|
//tnet_turn_channel_data_t* tnet_turn_channel_data_create_null()
|
||||||
}
|
//{
|
||||||
|
// return tnet_turn_channel_data_create(0, 0, tsk_null);
|
||||||
return self;
|
//}
|
||||||
}
|
//
|
||||||
|
///**@ingroup tnet_turn_group
|
||||||
static const tsk_object_def_t tnet_turn_channel_data_def_s =
|
//*/
|
||||||
{
|
//tsk_buffer_t* tnet_turn_channel_data_serialize(const tnet_turn_channel_data_t *message)
|
||||||
sizeof(tnet_turn_channel_data_t),
|
//{
|
||||||
tnet_turn_channel_data_ctor,
|
// tsk_buffer_t *output = 0;
|
||||||
tnet_turn_channel_data_dtor,
|
//
|
||||||
tsk_null,
|
// if(!message) goto bail;
|
||||||
};
|
//
|
||||||
const tsk_object_def_t *tnet_turn_channel_data_def_t = &tnet_turn_channel_data_def_s;
|
// output = tsk_buffer_create_null();
|
||||||
|
//
|
||||||
|
// /* draft-ietf-behave-turn-16 11.4. The ChannelData Message
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Channel Number | Length |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | |
|
||||||
|
// / Application Data /
|
||||||
|
// / /
|
||||||
|
// | |
|
||||||
|
// | +-------------------------------+
|
||||||
|
// | |
|
||||||
|
// +-------------------------------+
|
||||||
|
// */
|
||||||
|
//
|
||||||
|
// /* Channel Number
|
||||||
|
// */
|
||||||
|
// {
|
||||||
|
// uint16_t number = tnet_htons(message->chanel_number);
|
||||||
|
// tsk_buffer_append(output, &(number), 2);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /* Length
|
||||||
|
// */
|
||||||
|
// {
|
||||||
|
// uint16_t length = tnet_htons(message->length);
|
||||||
|
// tsk_buffer_append(output, &(length), 2);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /* Application Data
|
||||||
|
// */
|
||||||
|
// {
|
||||||
|
// tsk_buffer_append(output, message->data, message->length);
|
||||||
|
//
|
||||||
|
// /* === Padding:
|
||||||
|
// Over stream transports, the ChannelData message MUST be padded to a
|
||||||
|
// multiple of four bytes in order to ensure the alignment of subsequent
|
||||||
|
// messages. The padding is not reflected in the length field of the
|
||||||
|
// ChannelData message, so the actual size of a ChannelData message
|
||||||
|
// (including padding) is (4 + Length) rounded up to the nearest
|
||||||
|
// multiple of 4. Over UDP, the padding is not required but MAY be included.
|
||||||
|
// */
|
||||||
|
// if(message->length%4)
|
||||||
|
// {
|
||||||
|
// static uint32_t zeros = 0x00000000;
|
||||||
|
// tsk_buffer_append(output, &zeros, 4-(message->length%4));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//bail:
|
||||||
|
// return output;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
////=================================================================================================
|
||||||
|
//// TURN CHANNEL-DATA message object definition
|
||||||
|
////
|
||||||
|
//static tsk_object_t* tnet_turn_channel_data_ctor(tsk_object_t * self, va_list * app)
|
||||||
|
//{
|
||||||
|
// tnet_turn_channel_data_t *message = self;
|
||||||
|
// if(message){
|
||||||
|
// const void* data;
|
||||||
|
// message->chanel_number = tsk_va_arg_u16(*app);
|
||||||
|
// message->length = tsk_va_arg_u16(*app);
|
||||||
|
// data = va_arg(*app, const void*);
|
||||||
|
// if(data && message->length){
|
||||||
|
// if((message->data = tsk_calloc(message->length, sizeof(uint8_t)))){
|
||||||
|
// memcpy(message->data, data, message->length);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return self;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//static tsk_object_t* tnet_turn_channel_data_dtor(tsk_object_t * self)
|
||||||
|
//{
|
||||||
|
// tnet_turn_channel_data_t *message = self;
|
||||||
|
// if(message){
|
||||||
|
// TSK_FREE(message->data);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return self;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//static const tsk_object_def_t tnet_turn_channel_data_def_s =
|
||||||
|
//{
|
||||||
|
// sizeof(tnet_turn_channel_data_t),
|
||||||
|
// tnet_turn_channel_data_ctor,
|
||||||
|
// tnet_turn_channel_data_dtor,
|
||||||
|
// tsk_null,
|
||||||
|
//};
|
||||||
|
//const tsk_object_def_t *tnet_turn_channel_data_def_t = &tnet_turn_channel_data_def_s;
|
||||||
|
|
|
@ -1,75 +1,75 @@
|
||||||
/*
|
///*
|
||||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
//* Copyright (C) 2010-2011 Mamadou Diop.
|
||||||
*
|
//*
|
||||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
//*
|
||||||
* This file is part of Open Source Doubango Framework.
|
//* This file is part of Open Source Doubango Framework.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
//* DOUBANGO is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
//* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
//* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
//* (at your option) any later version.
|
||||||
*
|
//*
|
||||||
* DOUBANGO is distributed in the hope that it will be useful,
|
//* DOUBANGO is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
//* GNU General Public License for more details.
|
||||||
*
|
//*
|
||||||
* You should have received a copy of the GNU General Public License
|
//* You should have received a copy of the GNU General Public License
|
||||||
* along with DOUBANGO.
|
//* along with DOUBANGO.
|
||||||
*
|
//*
|
||||||
*/
|
//*/
|
||||||
|
//
|
||||||
/**@file tnet_turn_message.h
|
///**@file tnet_turn_message.h
|
||||||
* @brief Traversal Using Relays around NAT (TURN) messages.
|
// * @brief Traversal Using Relays around NAT (TURN) messages.
|
||||||
*
|
// *
|
||||||
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
// * @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||||
*
|
// *
|
||||||
|
//
|
||||||
*/
|
// */
|
||||||
#ifndef TNET_TURN_MESSAGE_H
|
//#ifndef TNET_TURN_MESSAGE_H
|
||||||
#define TNET_TURN_MESSAGE_H
|
//#define TNET_TURN_MESSAGE_H
|
||||||
|
//
|
||||||
#include "../tinynet_config.h"
|
//#include "../tinynet_config.h"
|
||||||
|
//
|
||||||
#include "tsk_buffer.h"
|
//#include "tsk_buffer.h"
|
||||||
|
//
|
||||||
TNET_BEGIN_DECLS
|
//TNET_BEGIN_DECLS
|
||||||
|
//
|
||||||
/**@ingroup tnet_turn_group
|
///**@ingroup tnet_turn_group
|
||||||
* TURN channel data message as per draft-ietf-behave-turn-16 subclause 11.4.
|
// * TURN channel data message as per draft-ietf-behave-turn-16 subclause 11.4.
|
||||||
*/
|
//*/
|
||||||
typedef struct tnet_turn_channel_data_s
|
//typedef struct tnet_turn_channel_data_s
|
||||||
{
|
//{
|
||||||
TSK_DECLARE_OBJECT;
|
// TSK_DECLARE_OBJECT;
|
||||||
|
//
|
||||||
/* draft-ietf-behave-turn-16 11.4. The ChannelData Message
|
// /* draft-ietf-behave-turn-16 11.4. The ChannelData Message
|
||||||
0 1 2 3
|
// 0 1 2 3
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Channel Number | Length |
|
// | Channel Number | Length |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| |
|
// | |
|
||||||
/ Application Data /
|
// / Application Data /
|
||||||
/ /
|
// / /
|
||||||
| |
|
// | |
|
||||||
| +-------------------------------+
|
// | +-------------------------------+
|
||||||
| |
|
// | |
|
||||||
+-------------------------------+
|
// +-------------------------------+
|
||||||
*/
|
// */
|
||||||
uint16_t chanel_number;
|
// uint16_t chanel_number;
|
||||||
uint16_t length;
|
// uint16_t length;
|
||||||
void* data;
|
// void* data;
|
||||||
}
|
//}
|
||||||
tnet_turn_channel_data_t;
|
//tnet_turn_channel_data_t;
|
||||||
|
//
|
||||||
tsk_buffer_t* tnet_turn_channel_data_serialize(const tnet_turn_channel_data_t *message);
|
//tsk_buffer_t* tnet_turn_channel_data_serialize(const tnet_turn_channel_data_t *message);
|
||||||
|
//
|
||||||
tnet_turn_channel_data_t* tnet_turn_channel_data_create(uint16_t number, uint16_t length, const void* data);
|
//tnet_turn_channel_data_t* tnet_turn_channel_data_create(uint16_t number, uint16_t length, const void* data);
|
||||||
tnet_turn_channel_data_t* tnet_turn_channel_data_create_null();
|
//tnet_turn_channel_data_t* tnet_turn_channel_data_create_null();
|
||||||
|
//
|
||||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_channel_data_def_t;
|
//TINYNET_GEXTERN const tsk_object_def_t *tnet_turn_channel_data_def_t;
|
||||||
|
//
|
||||||
TNET_END_DECLS
|
//TNET_END_DECLS
|
||||||
|
//
|
||||||
#endif /* TNET_TURN_MESSAGE_H */
|
//#endif /* TNET_TURN_MESSAGE_H */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -29,6 +29,7 @@ TNET_BEGIN_DECLS
|
||||||
struct tnet_turn_session_s;
|
struct tnet_turn_session_s;
|
||||||
struct tnet_socket_s;
|
struct tnet_socket_s;
|
||||||
enum tnet_socket_type_e;
|
enum tnet_socket_type_e;
|
||||||
|
#define kTurnPeerIdInvalid -1
|
||||||
|
|
||||||
typedef enum tnet_turn_session_event_type_e
|
typedef enum tnet_turn_session_event_type_e
|
||||||
{
|
{
|
||||||
|
@ -46,7 +47,10 @@ tnet_turn_session_event_type_t;
|
||||||
|
|
||||||
typedef struct tnet_turn_session_event_xs {
|
typedef struct tnet_turn_session_event_xs {
|
||||||
enum tnet_turn_session_event_type_e e_type;
|
enum tnet_turn_session_event_type_e e_type;
|
||||||
|
tnet_turn_peer_id_t u_peer_id;
|
||||||
const void* pc_usr_data;
|
const void* pc_usr_data;
|
||||||
|
const struct tnet_transport_event_s* pc_enet;
|
||||||
|
struct tnet_turn_session_s* pc_session;
|
||||||
struct {
|
struct {
|
||||||
const void* pc_data_ptr;
|
const void* pc_data_ptr;
|
||||||
tsk_size_t u_data_size;
|
tsk_size_t u_data_size;
|
||||||
|
@ -68,9 +72,13 @@ TINYNET_API int tnet_turn_session_start(struct tnet_turn_session_s* p_self);
|
||||||
TINYNET_API int tnet_turn_session_allocate(struct tnet_turn_session_s* p_self);
|
TINYNET_API int tnet_turn_session_allocate(struct tnet_turn_session_s* p_self);
|
||||||
TINYNET_API int tnet_turn_session_get_relayed_addr(const struct tnet_turn_session_s* p_self, char** pp_ip, uint16_t *pu_port, tsk_bool_t *pb_ipv6);
|
TINYNET_API int tnet_turn_session_get_relayed_addr(const struct tnet_turn_session_s* p_self, char** pp_ip, uint16_t *pu_port, tsk_bool_t *pb_ipv6);
|
||||||
TINYNET_API int tnet_turn_session_get_srflx_addr(const struct tnet_turn_session_s* p_self, char** pp_ip, uint16_t *pu_port, tsk_bool_t *pb_ipv6);
|
TINYNET_API int tnet_turn_session_get_srflx_addr(const struct tnet_turn_session_s* p_self, char** pp_ip, uint16_t *pu_port, tsk_bool_t *pb_ipv6);
|
||||||
TINYNET_API int tnet_turn_session_createpermission(struct tnet_turn_session_s* p_self, const char* pc_peer_addr, uint16_t u_peer_port);
|
TINYNET_API int tnet_turn_session_get_state_alloc(const struct tnet_turn_session_s* pc_self, enum tnet_stun_state_e *pe_state);
|
||||||
TINYNET_API int tnet_turn_session_chanbind(struct tnet_turn_session_s* p_self);
|
TINYNET_API int tnet_turn_session_get_state_createperm(const struct tnet_turn_session_s* pc_self, tnet_turn_peer_id_t u_peer_id, enum tnet_stun_state_e *pe_state);
|
||||||
TINYNET_API int tnet_turn_session_send_data(struct tnet_turn_session_s* p_self, const void* pc_data_ptr, uint16_t u_data_size);
|
TINYNET_API int tnet_turn_session_createpermission(struct tnet_turn_session_s* p_self, const char* pc_peer_addr, uint16_t u_peer_port, tnet_turn_peer_id_t* pu_peer_id);
|
||||||
|
TINYNET_API int tnet_turn_session_deletepermission(struct tnet_turn_session_s* p_self, tnet_turn_peer_id_t u_peer_id);
|
||||||
|
TINYNET_API int tnet_turn_session_chanbind(struct tnet_turn_session_s* p_self, tnet_turn_peer_id_t u_peer_id);
|
||||||
|
TINYNET_API int tnet_turn_session_send_data(struct tnet_turn_session_s* p_self, tnet_turn_peer_id_t u_peer_id, const void* pc_data_ptr, uint16_t u_data_size);
|
||||||
|
TINYNET_API int tnet_turn_session_is_active(const struct tnet_turn_session_s* pc_self, tnet_turn_peer_id_t u_peer_id, tsk_bool_t *pb_active);
|
||||||
TINYNET_API int tnet_turn_session_stop(struct tnet_turn_session_s* p_self);
|
TINYNET_API int tnet_turn_session_stop(struct tnet_turn_session_s* p_self);
|
||||||
|
|
||||||
TNET_END_DECLS
|
TNET_END_DECLS
|
||||||
|
|
|
@ -42,8 +42,8 @@
|
||||||
#define RUN_TEST_SOCKETS 0 /* FIXME: Android */
|
#define RUN_TEST_SOCKETS 0 /* FIXME: Android */
|
||||||
#define RUN_TEST_TRANSPORT 0
|
#define RUN_TEST_TRANSPORT 0
|
||||||
#define RUN_TEST_AUTH 0
|
#define RUN_TEST_AUTH 0
|
||||||
#define RUN_TEST_STUN 1
|
#define RUN_TEST_STUN 0
|
||||||
#define RUN_TEST_ICE 0
|
#define RUN_TEST_ICE 1
|
||||||
#define RUN_TEST_NAT 0
|
#define RUN_TEST_NAT 0
|
||||||
#define RUN_TEST_IFACES 0
|
#define RUN_TEST_IFACES 0
|
||||||
#define RUN_TEST_DNS 0
|
#define RUN_TEST_DNS 0
|
||||||
|
|
|
@ -20,125 +20,194 @@
|
||||||
#ifndef TNET_TEST_ICE_H
|
#ifndef TNET_TEST_ICE_H
|
||||||
#define TNET_TEST_ICE_H
|
#define TNET_TEST_ICE_H
|
||||||
|
|
||||||
#define ICE_CANDIDATES "1 1 udp 1 192.168.196.1 57806 typ host name video_rtcp network_name {0C0137CC-DB78-46B6-9B6C-7E097FFA79FE} username StFEVThMK2DHThkv password qkhKUDr4WqKRwZTo generation 0\r\n" \
|
#define kStunUsrName "bossiel@yahoo.fr"
|
||||||
"1 2 udp 1 192.168.211.1 57808 typ srflx name video_rtcp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username 9ONjPsYvSFh0JvAc password rDHSkokdvp9dyXqQ generation 0\r\n" \
|
#define kStunPwd "tinynet"
|
||||||
"1 1 udp 1 192.168.196.1 57809 typ prflx name video_rtp network_name {0C0137CC-DB78-46B6-9B6C-7E097FFA79FE} username S1vDZTVVky3r0pT+ password XgLb+H9uofxuWg7G generation 0\r\n" \
|
#define kStunServerIP "ns313841.ovh.net" /*"numb.viagenie.ca"*/ /*stun.ekiga.net*/
|
||||||
"1 2 udp 1 192.168.211.1 57811 typ relay name video_rtp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username x64BhO4BXjBFkpz2 password ZwHhRhu0KU9R6iWd generation 0\r\n" \
|
|
||||||
"1 1 udp 1 192.168.211.1 57811 typ token name video_rtp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username x64BhO4BXjBFkpz2 password ZwHhRhu0KU9R6iWd generation 0\r\n"
|
|
||||||
|
|
||||||
static int tnet_ice_callback(const tnet_ice_event_t *e)
|
#define kSkipHosts 0
|
||||||
|
#define kSkipReflexives 1 // server reflexive: STUN
|
||||||
|
#define kSkipPeers 1 // peer reflexive
|
||||||
|
#define kSkipRelays 0 // relays: TURN
|
||||||
|
|
||||||
|
static struct tnet_ice_ctx_s *p_ice_ctx1 = tsk_null;
|
||||||
|
static struct tnet_ice_ctx_s *p_ice_ctx2 = tsk_null;
|
||||||
|
|
||||||
|
static void test_ice_print_local_candidates(const struct tnet_ice_ctx_s *pc_ctx)
|
||||||
{
|
{
|
||||||
TSK_DEBUG_INFO("ICE callback: %s", e->phrase);
|
tsk_size_t index = 0;
|
||||||
|
const tnet_ice_candidate_t* candidate;
|
||||||
|
char* p_str = tsk_null;
|
||||||
|
|
||||||
|
while ((candidate = tnet_ice_ctx_get_local_candidate_at(pc_ctx, index++))) {
|
||||||
|
tsk_strcat_2(&p_str, "%s\r\n", tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate));
|
||||||
|
}
|
||||||
|
TSK_DEBUG_INFO("ICE LOCAL CANDIDATES:\n%s", p_str);
|
||||||
|
TSK_FREE(p_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* test_ice_get_local_candidates(const struct tnet_ice_ctx_s *pc_ctx)
|
||||||
|
{
|
||||||
|
tsk_size_t index = 0;
|
||||||
|
const tnet_ice_candidate_t* candidate;
|
||||||
|
char* p_str = tsk_null;
|
||||||
|
|
||||||
|
while ((candidate = tnet_ice_ctx_get_local_candidate_at(pc_ctx, index++))) {
|
||||||
|
if (kSkipHosts && candidate->type_e == tnet_ice_cand_type_host) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (kSkipReflexives && candidate->type_e == tnet_ice_cand_type_srflx) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (kSkipRelays && candidate->type_e == tnet_ice_cand_type_relay) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (kSkipPeers && candidate->type_e == tnet_ice_cand_type_prflx) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tsk_strcat_2(&p_str, "%s\r\n", tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate));
|
||||||
|
}
|
||||||
|
return p_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_ice_rtp_callback(const void* callback_data, const uint8_t* data_ptr, tsk_size_t data_size, tnet_fd_t local_fd, const struct sockaddr_storage* remote_addr)
|
||||||
|
{
|
||||||
|
struct tnet_ice_ctx_s *p_ice_ctx = (struct tnet_ice_ctx_s *)callback_data;
|
||||||
|
|
||||||
|
TSK_DEBUG_INFO("\n\nICE rtp callback: %.*s\n\n", data_size, data_ptr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_ice_state_callback(const tnet_ice_event_t *e)
|
||||||
|
{
|
||||||
|
struct tnet_ice_ctx_s *p_ice_ctx = (struct tnet_ice_ctx_s *)e->ctx;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
TSK_DEBUG_INFO("ICE state callback: %s", e->phrase);
|
||||||
|
|
||||||
switch(e->type)
|
switch(e->type)
|
||||||
{
|
{
|
||||||
case tnet_ice_event_type_gathering_completed:
|
case tnet_ice_event_type_gathering_completed:
|
||||||
{
|
{
|
||||||
struct tnet_ice_ctx_s *ctx;
|
test_ice_print_local_candidates(p_ice_ctx);
|
||||||
if((ctx = (struct tnet_ice_ctx_s *)e->userdata)){
|
if (p_ice_ctx == p_ice_ctx1) {
|
||||||
tnet_ice_ctx_set_remote_candidates(ctx, ICE_CANDIDATES, "ice-ufrag", "ice-pwd", tsk_true, tsk_false);
|
if ((ret = tnet_ice_ctx_start(p_ice_ctx2))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const tnet_ice_candidate_t* candidate;
|
||||||
|
char* p_cand;
|
||||||
|
|
||||||
|
p_cand = test_ice_get_local_candidates(p_ice_ctx2);
|
||||||
|
candidate = tnet_ice_ctx_get_local_candidate_first(p_ice_ctx2);
|
||||||
|
ret = tnet_ice_ctx_set_remote_candidates(p_ice_ctx1, p_cand, candidate->ufrag, candidate->pwd, tsk_true, tsk_false);
|
||||||
|
if (ret == 0) {
|
||||||
|
TSK_FREE(p_cand);
|
||||||
|
p_cand = test_ice_get_local_candidates(p_ice_ctx1);
|
||||||
|
candidate = tnet_ice_ctx_get_local_candidate_first(p_ice_ctx1);
|
||||||
|
ret = tnet_ice_ctx_set_remote_candidates(p_ice_ctx2, p_cand, candidate->ufrag, candidate->pwd, tsk_false, tsk_false);
|
||||||
|
TSK_FREE(p_cand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case tnet_ice_event_type_conncheck_succeed:
|
||||||
|
{
|
||||||
|
const char kTurnData[] = "TURN data to send for testing";
|
||||||
|
const tnet_ice_candidate_t *candidate_offer, *candidate_answer_src, *candidate_answer_dest;
|
||||||
|
ret = tnet_ice_ctx_get_nominated_symetric_candidates(p_ice_ctx, TNET_ICE_CANDIDATE_COMPID_RTP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
|
||||||
|
if (ret == 0) {
|
||||||
|
TSK_DEBUG_INFO("Nominated candidate(RTP): Offer=[[%s]], AnswerSrc=[[%s]], AnswerDest=[[%s]]",
|
||||||
|
tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate_offer),
|
||||||
|
tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate_answer_src),
|
||||||
|
tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate_answer_dest));
|
||||||
|
|
||||||
|
if (tnet_ice_ctx_is_turn_rtp_active(p_ice_ctx)) {
|
||||||
|
tnet_ice_ctx_send_turn_rtp(p_ice_ctx, kTurnData, sizeof(kTurnData));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = tnet_ice_ctx_get_nominated_symetric_candidates(p_ice_ctx, TNET_ICE_CANDIDATE_COMPID_RTCP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
|
||||||
|
if (ret == 0) {
|
||||||
|
TSK_DEBUG_INFO("Nominated candidate(RTCP): Offer=[[%s]], AnswerSrc=[[%s]], AnswerDest=[[%s]]",
|
||||||
|
tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate_offer),
|
||||||
|
tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate_answer_src),
|
||||||
|
tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate_answer_dest));
|
||||||
|
if (tnet_ice_ctx_is_turn_rtcp_active(p_ice_ctx)) {
|
||||||
|
tnet_ice_ctx_send_turn_rtcp(p_ice_ctx, kTurnData, sizeof(kTurnData));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
bail:
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_ice()
|
void test_ice()
|
||||||
{
|
{
|
||||||
struct tnet_ice_ctx_s *ctx;
|
|
||||||
int ret;
|
int ret;
|
||||||
static const tsk_bool_t use_ipv6 = tsk_false;
|
static const tsk_bool_t use_ipv6 = tsk_false;
|
||||||
static const tsk_bool_t use_rtcp = tsk_true;
|
static const tsk_bool_t use_rtcp = tsk_true;
|
||||||
static const tsk_bool_t use_ice_jingle = tsk_false;
|
static const tsk_bool_t use_ice_jingle = tsk_false;
|
||||||
static const tsk_bool_t use_video = tsk_false;
|
static const tsk_bool_t use_video = tsk_false;
|
||||||
|
|
||||||
long a = tnet_htonl(0x6b0c76a7);
|
if (!(p_ice_ctx1 = tnet_ice_ctx_create(use_ice_jingle, use_ipv6, use_rtcp, use_video, test_ice_state_callback, tsk_null))) {
|
||||||
long b = tnet_htonl(0x034aa76b);
|
goto bail;
|
||||||
long c = tnet_htonl(0x510da598);
|
}
|
||||||
|
if (!(p_ice_ctx2 = tnet_ice_ctx_create(use_ice_jingle, use_ipv6, use_rtcp, use_video, test_ice_state_callback, tsk_null))) {
|
||||||
ctx = tnet_ice_ctx_create(use_ice_jingle, use_ipv6, use_rtcp, use_video, tnet_ice_callback, tsk_null);
|
goto bail;
|
||||||
tnet_ice_ctx_set_userdata(ctx, ctx);
|
}
|
||||||
ret = tnet_ice_ctx_set_stun(ctx, "numb.viagenie.ca", 3478, "Doubango", "bossiel@yahoo.fr", "stun-password");
|
if ((ret = tnet_ice_ctx_set_turn_enabled(p_ice_ctx1, 1))) {
|
||||||
ret = tnet_ice_ctx_start(ctx);
|
goto bail;
|
||||||
// ret = tnet_ice_ctx_set_remote_candidates(ctx, ICE_CANDIDATES);
|
}
|
||||||
|
if ((ret = tnet_ice_ctx_set_turn_enabled(p_ice_ctx2, 1))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if ((ret = tnet_ice_ctx_set_stun_enabled(p_ice_ctx1, 1))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if ((ret = tnet_ice_ctx_set_stun_enabled(p_ice_ctx2, 1))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if ((ret = tnet_ice_ctx_set_userdata(p_ice_ctx1, p_ice_ctx1))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if ((ret = tnet_ice_ctx_set_userdata(p_ice_ctx2, p_ice_ctx2))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if ((ret = tnet_ice_ctx_rtp_callback(p_ice_ctx1, test_ice_rtp_callback, p_ice_ctx1))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if ((ret = tnet_ice_ctx_rtp_callback(p_ice_ctx2, test_ice_rtp_callback, p_ice_ctx2))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if ((ret = tnet_ice_ctx_set_stun(p_ice_ctx1, kStunServerIP, 3478, kStunSoftware, kStunUsrName, kStunPwd))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if ((ret = tnet_ice_ctx_set_stun(p_ice_ctx2, kStunServerIP, 3478, kStunSoftware, kStunUsrName, kStunPwd))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if ((ret = tnet_ice_ctx_start(p_ice_ctx1))) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
// start ctx2 when we finish gathering ctx1's candidates
|
||||||
|
//if ((ret = tnet_ice_ctx_start(p_ice_ctx2))) {
|
||||||
|
// goto bail;
|
||||||
|
//}
|
||||||
|
|
||||||
getchar();
|
getchar();
|
||||||
|
|
||||||
ret = tnet_ice_ctx_stop(ctx);
|
// ret = tnet_ice_ctx_stop(p_ice_ctx1);
|
||||||
|
// ret = tnet_ice_ctx_stop(p_ice_ctx2);
|
||||||
|
|
||||||
TSK_OBJECT_SAFE_FREE(ctx);
|
bail:
|
||||||
|
TSK_OBJECT_SAFE_FREE(p_ice_ctx1);
|
||||||
|
TSK_OBJECT_SAFE_FREE(p_ice_ctx2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* TNET_TEST_ICE_H */
|
#endif /* TNET_TEST_ICE_H */
|
||||||
/*
|
|
||||||
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
|
|
||||||
*
|
|
||||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
|
||||||
*
|
|
||||||
* This file is part of Open Source Doubango Framework.
|
|
||||||
*
|
|
||||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* DOUBANGO is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with DOUBANGO.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TNET_TEST_ICE_H
|
|
||||||
#define TNET_TEST_ICE_H
|
|
||||||
|
|
||||||
#define ICE_CANDIDATES "1 1 udp 1 192.168.196.1 57806 typ host name video_rtcp network_name {0C0137CC-DB78-46B6-9B6C-7E097FFA79FE} username StFEVThMK2DHThkv password qkhKUDr4WqKRwZTo generation 0\r\n" \
|
|
||||||
"1 2 udp 1 192.168.211.1 57808 typ srflx name video_rtcp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username 9ONjPsYvSFh0JvAc password rDHSkokdvp9dyXqQ generation 0\r\n" \
|
|
||||||
"1 1 udp 1 192.168.196.1 57809 typ prflx name video_rtp network_name {0C0137CC-DB78-46B6-9B6C-7E097FFA79FE} username S1vDZTVVky3r0pT+ password XgLb+H9uofxuWg7G generation 0\r\n" \
|
|
||||||
"1 2 udp 1 192.168.211.1 57811 typ relay name video_rtp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username x64BhO4BXjBFkpz2 password ZwHhRhu0KU9R6iWd generation 0\r\n" \
|
|
||||||
"1 1 udp 1 192.168.211.1 57811 typ token name video_rtp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username x64BhO4BXjBFkpz2 password ZwHhRhu0KU9R6iWd generation 0\r\n"
|
|
||||||
|
|
||||||
static int tnet_ice_callback(const tnet_ice_event_t *e)
|
|
||||||
{
|
|
||||||
TSK_DEBUG_INFO("ICE callback: %s", e->phrase);
|
|
||||||
|
|
||||||
switch(e->type)
|
|
||||||
{
|
|
||||||
case tnet_ice_event_type_gathering_completed:
|
|
||||||
{
|
|
||||||
struct tnet_ice_ctx_s *ctx;
|
|
||||||
if((ctx = (struct tnet_ice_ctx_s *)e->userdata)){
|
|
||||||
tnet_ice_ctx_set_remote_candidates(ctx, ICE_CANDIDATES);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_ice()
|
|
||||||
{
|
|
||||||
struct tnet_ice_ctx_s *ctx;
|
|
||||||
int ret;
|
|
||||||
static const tsk_bool_t use_ipv6 = tsk_false;
|
|
||||||
static const tsk_bool_t use_rtcp = tsk_true;
|
|
||||||
|
|
||||||
ctx = tnet_ice_ctx_create(use_ipv6, use_rtcp, tnet_ice_callback, tsk_null);
|
|
||||||
tnet_ice_ctx_set_userdata(ctx, ctx);
|
|
||||||
ret = tnet_ice_ctx_stun_configure(ctx, "numb.viagenie.ca", 3478, "Doubango", "bossiel@yahoo.fr", "stun-password");
|
|
||||||
ret = tnet_ice_ctx_start(ctx);
|
|
||||||
// ret = tnet_ice_ctx_set_remote_candidates(ctx, ICE_CANDIDATES);
|
|
||||||
|
|
||||||
getchar();
|
|
||||||
|
|
||||||
ret = tnet_ice_ctx_stop(ctx);
|
|
||||||
|
|
||||||
TSK_OBJECT_SAFE_FREE(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* TNET_TEST_ICE_H */
|
|
||||||
|
|
|
@ -19,9 +19,7 @@
|
||||||
#ifndef TNET_TEST_NAT_H
|
#ifndef TNET_TEST_NAT_H
|
||||||
#define TNET_TEST_NAT_H
|
#define TNET_TEST_NAT_H
|
||||||
|
|
||||||
//stun.ekiga.net
|
#define STUN_SERVER_IP "ns313841.ovh.net" // "numb.viagenie.ca" /* stun.ekiga.net, */
|
||||||
//#define STUN_SERVER_IP "numb.viagenie.ca"
|
|
||||||
#define STUN_SERVER_IP "numb.viagenie.ca"
|
|
||||||
#define STUN_USERNAME "bossiel@yahoo.fr"
|
#define STUN_USERNAME "bossiel@yahoo.fr"
|
||||||
#define STUN_PASSWORD "tinynet"
|
#define STUN_PASSWORD "tinynet"
|
||||||
#define STUN_SERVER_PORT TNET_STUN_TCP_UDP_DEFAULT_PORT
|
#define STUN_SERVER_PORT TNET_STUN_TCP_UDP_DEFAULT_PORT
|
||||||
|
@ -30,7 +28,7 @@
|
||||||
void test_nat_stun()
|
void test_nat_stun()
|
||||||
{
|
{
|
||||||
tnet_socket_t *socket1 = 0, *socket2 = 0;
|
tnet_socket_t *socket1 = 0, *socket2 = 0;
|
||||||
tnet_nat_context_handle_t *context = 0;
|
struct tnet_nat_ctx_s *context = 0;
|
||||||
|
|
||||||
tnet_stun_binding_id_t bind_id1, bind_id2;
|
tnet_stun_binding_id_t bind_id1, bind_id2;
|
||||||
|
|
||||||
|
@ -38,42 +36,35 @@ void test_nat_stun()
|
||||||
tnet_port_t public_port1 = 0, public_port2 = 0;
|
tnet_port_t public_port1 = 0, public_port2 = 0;
|
||||||
|
|
||||||
if(!(socket1 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO))
|
if(!(socket1 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO))
|
||||||
|| !(socket2 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO)))
|
|| !(socket2 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO))) {
|
||||||
{
|
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
context = tnet_nat_context_create(STUN_SERVER_PROTO, STUN_USERNAME, STUN_PASSWORD);
|
context = tnet_nat_context_create(STUN_SERVER_PROTO, STUN_USERNAME, STUN_PASSWORD);
|
||||||
|
|
||||||
if(tnet_nat_set_server_address(context, STUN_SERVER_IP))
|
if(tnet_nat_set_server_address(context, STUN_SERVER_IP)) {
|
||||||
{
|
|
||||||
TSK_DEBUG_ERROR("Failed to set STUN/TURN address.");
|
TSK_DEBUG_ERROR("Failed to set STUN/TURN address.");
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* == BIND
|
// == BIND == //
|
||||||
*/
|
|
||||||
bind_id1 = tnet_nat_stun_bind(context, socket1->fd);
|
bind_id1 = tnet_nat_stun_bind(context, socket1->fd);
|
||||||
bind_id2 = tnet_nat_stun_bind(context, socket2->fd);
|
bind_id2 = tnet_nat_stun_bind(context, socket2->fd);
|
||||||
|
|
||||||
if(!TNET_STUN_IS_VALID_BINDING_ID(bind_id1) ||!TNET_STUN_IS_VALID_BINDING_ID(bind_id2))
|
if(!bind_id1 || !bind_id2) {
|
||||||
{
|
|
||||||
TSK_DEBUG_ERROR("Failed to get public IP/port using stun");
|
TSK_DEBUG_ERROR("Failed to get public IP/port using stun");
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tnet_nat_stun_get_reflexive_address(context, bind_id1, &public_ip1, &public_port1))
|
if (tnet_nat_stun_get_reflexive_address(context, bind_id1, &public_ip1, &public_port1) == 0) {
|
||||||
{
|
|
||||||
TSK_DEBUG_INFO("Public IP1/Port1 ==> %s:%u", public_ip1, public_port1);
|
TSK_DEBUG_INFO("Public IP1/Port1 ==> %s:%u", public_ip1, public_port1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tnet_nat_stun_get_reflexive_address(context, bind_id2, &public_ip2, &public_port2))
|
if (tnet_nat_stun_get_reflexive_address(context, bind_id2, &public_ip2, &public_port2) == 0) {
|
||||||
{
|
|
||||||
TSK_DEBUG_INFO("Public IP2/Port2 ==> %s:%u", public_ip2, public_port2);
|
TSK_DEBUG_INFO("Public IP2/Port2 ==> %s:%u", public_ip2, public_port2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* == UNBIND
|
// == UNBIND == //
|
||||||
*/
|
|
||||||
tnet_nat_stun_unbind(context, bind_id1);
|
tnet_nat_stun_unbind(context, bind_id1);
|
||||||
tnet_nat_stun_unbind(context, bind_id2);
|
tnet_nat_stun_unbind(context, bind_id2);
|
||||||
|
|
||||||
|
@ -89,129 +80,129 @@ bail:
|
||||||
|
|
||||||
void test_nat_turn()
|
void test_nat_turn()
|
||||||
{
|
{
|
||||||
tnet_socket_t *socket1 = 0, *socket2 = 0;
|
// tnet_socket_t *socket1 = 0, *socket2 = 0;
|
||||||
tnet_nat_context_handle_t *context = 0;
|
// struct tnet_nat_ctx_s *context = 0;
|
||||||
tnet_turn_allocation_id_t alloc_id1, alloc_id2;
|
// tnet_turn_allocation_id_t alloc_id1, alloc_id2;
|
||||||
|
//
|
||||||
char* public_ip1 = 0, *public_ip2 = 0;
|
// char* public_ip1 = 0, *public_ip2 = 0;
|
||||||
tnet_port_t public_port1 = 0, public_port2 = 0;
|
// tnet_port_t public_port1 = 0, public_port2 = 0;
|
||||||
|
//
|
||||||
tnet_turn_channel_binding_id_t channel_id;
|
// tnet_turn_channel_binding_id_t channel_id;
|
||||||
|
//
|
||||||
int ret;
|
// int ret;
|
||||||
|
//
|
||||||
if(!(socket1 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO))
|
// if(!(socket1 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO))
|
||||||
|| !(socket2 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO)))
|
// || !(socket2 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO)))
|
||||||
{
|
// {
|
||||||
goto bail;
|
// goto bail;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
context = tnet_nat_context_create(STUN_SERVER_PROTO, STUN_USERNAME, STUN_PASSWORD);
|
// context = tnet_nat_context_create(STUN_SERVER_PROTO, STUN_USERNAME, STUN_PASSWORD);
|
||||||
((tnet_nat_context_t*)context)->enable_evenport = 0;
|
// ((tnet_nat_context_t*)context)->enable_evenport = 0;
|
||||||
((tnet_nat_context_t*)context)->enable_fingerprint = 0;
|
// ((tnet_nat_context_t*)context)->enable_fingerprint = 0;
|
||||||
((tnet_nat_context_t*)context)->enable_dontfrag = 0;
|
// ((tnet_nat_context_t*)context)->enable_dontfrag = 0;
|
||||||
((tnet_nat_context_t*)context)->enable_integrity = 0;
|
// ((tnet_nat_context_t*)context)->enable_integrity = 0;
|
||||||
|
//
|
||||||
if(tnet_nat_set_server_address(context, STUN_SERVER_IP))
|
// if(tnet_nat_set_server_address(context, STUN_SERVER_IP))
|
||||||
{
|
// {
|
||||||
TSK_DEBUG_ERROR("Failed to set STUN/TURN address.");
|
// TSK_DEBUG_ERROR("Failed to set STUN/TURN address.");
|
||||||
goto bail;
|
// goto bail;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/* == ALLOC
|
// /* == ALLOC
|
||||||
*/
|
// */
|
||||||
alloc_id1 = tnet_nat_turn_allocate(context, socket1->fd);
|
// alloc_id1 = tnet_nat_turn_allocate(context, socket1->fd);
|
||||||
alloc_id2 = tnet_nat_turn_allocate(context, socket2->fd);
|
// alloc_id2 = tnet_nat_turn_allocate(context, socket2->fd);
|
||||||
if(!TNET_TURN_IS_VALID_ALLOCATION_ID(alloc_id1) || !TNET_TURN_IS_VALID_ALLOCATION_ID(alloc_id2))
|
// if(!TNET_TURN_IS_VALID_ALLOCATION_ID(alloc_id1) || !TNET_TURN_IS_VALID_ALLOCATION_ID(alloc_id2))
|
||||||
{
|
// {
|
||||||
TSK_DEBUG_ERROR("TURN allocation failed.");
|
// TSK_DEBUG_ERROR("TURN allocation failed.");
|
||||||
goto bail;
|
// goto bail;
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
TSK_DEBUG_INFO("TURN allocation succeeded and id1=%llu and id2=%llu", alloc_id1, alloc_id2);
|
// TSK_DEBUG_INFO("TURN allocation succeeded and id1=%llu and id2=%llu", alloc_id1, alloc_id2);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
tsk_thread_sleep(2000);
|
// tsk_thread_sleep(2000);
|
||||||
|
//
|
||||||
/* == RETRIEVE STUN SERVER REFLEXIVE ADDRESSES
|
// /* == RETRIEVE STUN SERVER REFLEXIVE ADDRESSES
|
||||||
*/
|
// */
|
||||||
if(!tnet_nat_turn_get_reflexive_address(context, alloc_id1, &public_ip1, &public_port1))
|
// if(!tnet_nat_turn_get_reflexive_address(context, alloc_id1, &public_ip1, &public_port1))
|
||||||
{
|
// {
|
||||||
TSK_DEBUG_INFO("Public IP1/Port1 ==> %s:%u", public_ip1, public_port1);
|
// TSK_DEBUG_INFO("Public IP1/Port1 ==> %s:%u", public_ip1, public_port1);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if(!tnet_nat_turn_get_reflexive_address(context, alloc_id2, &public_ip2, &public_port2))
|
// if(!tnet_nat_turn_get_reflexive_address(context, alloc_id2, &public_ip2, &public_port2))
|
||||||
{
|
// {
|
||||||
TSK_DEBUG_INFO("Public IP2/Port2 ==> %s:%u", public_ip2, public_port2);
|
// TSK_DEBUG_INFO("Public IP2/Port2 ==> %s:%u", public_ip2, public_port2);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/* == CREATE PERMISSION
|
// /* == CREATE PERMISSION
|
||||||
*/
|
// */
|
||||||
//tnet_nat_turn_add_permission(context, alloc_id1, "192.168.0.11", 300);
|
// //tnet_nat_turn_add_permission(context, alloc_id1, "192.168.0.11", 300);
|
||||||
|
//
|
||||||
/* == CHANNEL BINDING
|
// /* == CHANNEL BINDING
|
||||||
*/
|
// */
|
||||||
{
|
// {
|
||||||
/* Try to bind (channel binding) to the socket1 to socket2 */
|
// /* Try to bind (channel binding) to the socket1 to socket2 */
|
||||||
struct sockaddr_storage peer;
|
// struct sockaddr_storage peer;
|
||||||
if((ret = tnet_sockaddr_init(public_ip2, public_port2, STUN_SERVER_PROTO, &peer)))
|
// if((ret = tnet_sockaddr_init(public_ip2, public_port2, STUN_SERVER_PROTO, &peer)))
|
||||||
{
|
// {
|
||||||
TSK_DEBUG_ERROR("Failed to init peer with error code %d.", ret);
|
// TSK_DEBUG_ERROR("Failed to init peer with error code %d.", ret);
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
channel_id = tnet_nat_turn_channel_bind(context, alloc_id1,&peer);
|
// channel_id = tnet_nat_turn_channel_bind(context, alloc_id1,&peer);
|
||||||
if(TNET_TURN_IS_VALID_CHANNEL_BINDING_ID(channel_id))
|
// if(TNET_TURN_IS_VALID_CHANNEL_BINDING_ID(channel_id))
|
||||||
{
|
// {
|
||||||
TSK_DEBUG_INFO("TURN channel binding succeeded.");
|
// TSK_DEBUG_INFO("TURN channel binding succeeded.");
|
||||||
|
//
|
||||||
/* Try to send data using the newly create channel */
|
// /* Try to send data using the newly create channel */
|
||||||
if(tnet_nat_turn_channel_senddata(context, channel_id, "Doubango", strlen("Doubango")))
|
// if(tnet_nat_turn_channel_senddata(context, channel_id, "Doubango", strlen("Doubango")))
|
||||||
{
|
// {
|
||||||
TSK_DEBUG_ERROR("Failed to send data using channel id [%u].", channel_id);
|
// TSK_DEBUG_ERROR("Failed to send data using channel id [%u].", channel_id);
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
TSK_DEBUG_INFO("Data successfuly sent using channel if[%u].", channel_id);
|
// TSK_DEBUG_INFO("Data successfuly sent using channel if[%u].", channel_id);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
TSK_DEBUG_ERROR("TURN channel binding failed.");
|
// TSK_DEBUG_ERROR("TURN channel binding failed.");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
tsk_thread_sleep(2000);
|
// tsk_thread_sleep(2000);
|
||||||
|
//
|
||||||
/* == UNALLOC
|
// /* == UNALLOC
|
||||||
*/
|
// */
|
||||||
if((ret = tnet_nat_turn_unallocate(context, alloc_id1)) || (ret = tnet_nat_turn_unallocate(context, alloc_id2)))
|
// if((ret = tnet_nat_turn_unallocate(context, alloc_id1)) || (ret = tnet_nat_turn_unallocate(context, alloc_id2)))
|
||||||
{
|
// {
|
||||||
TSK_DEBUG_ERROR("TURN unallocation failed with error code: %d.", ret);
|
// TSK_DEBUG_ERROR("TURN unallocation failed with error code: %d.", ret);
|
||||||
goto bail;
|
// goto bail;
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
TSK_DEBUG_INFO("TURN unallocation succeeded.");
|
// TSK_DEBUG_INFO("TURN unallocation succeeded.");
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
bail:
|
//bail:
|
||||||
TSK_OBJECT_SAFE_FREE(socket1);
|
// TSK_OBJECT_SAFE_FREE(socket1);
|
||||||
TSK_OBJECT_SAFE_FREE(socket2);
|
// TSK_OBJECT_SAFE_FREE(socket2);
|
||||||
|
//
|
||||||
TSK_FREE(public_ip1);
|
// TSK_FREE(public_ip1);
|
||||||
TSK_FREE(public_ip1);
|
// TSK_FREE(public_ip1);
|
||||||
|
//
|
||||||
TSK_OBJECT_SAFE_FREE(context);
|
// TSK_OBJECT_SAFE_FREE(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void test_nat()
|
void test_nat()
|
||||||
{
|
{
|
||||||
//test_nat_stun();
|
test_nat_stun();
|
||||||
test_nat_turn();
|
//test_nat_turn();
|
||||||
//tsk_thread_sleep(1000);
|
//tsk_thread_sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,16 +63,6 @@ static int test_stun_buff_cmp(const uint8_t* pc_buf1_ptr, tsk_size_t n_buff1_siz
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_stun_dump_transacid(tnet_stun_transacid_t transcid)
|
|
||||||
{
|
|
||||||
char transac_idstriing[TNET_STUN_TRANSACID_SIZE*2+1];
|
|
||||||
tsk_str_from_hex(transcid, TNET_STUN_TRANSACID_SIZE, transac_idstriing);
|
|
||||||
|
|
||||||
transac_idstriing[sizeof(transac_idstriing)-1] = '\0';
|
|
||||||
|
|
||||||
TSK_DEBUG_INFO("STUN transac id:%s", transac_idstriing);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_stun_parser()
|
static void test_stun_parser()
|
||||||
{
|
{
|
||||||
tnet_stun_pkt_t* p_pkt = tsk_null;
|
tnet_stun_pkt_t* p_pkt = tsk_null;
|
||||||
|
@ -155,9 +145,11 @@ static struct tnet_turn_session_s* __pc_ss2 = tsk_null;
|
||||||
static char* __p_rel_ip_ss1 = tsk_null;
|
static char* __p_rel_ip_ss1 = tsk_null;
|
||||||
static uint16_t __u_rel_port_ss1 = 0;
|
static uint16_t __u_rel_port_ss1 = 0;
|
||||||
static tsk_bool_t __b_rel_ipv6_ss1 = 0;
|
static tsk_bool_t __b_rel_ipv6_ss1 = 0;
|
||||||
|
static tnet_turn_peer_id_t __u_peer_id1 = kTurnPeerIdInvalid;
|
||||||
static char* __p_rel_ip_ss2 = tsk_null;
|
static char* __p_rel_ip_ss2 = tsk_null;
|
||||||
static uint16_t __u_rel_port_ss2 = 0;
|
static uint16_t __u_rel_port_ss2 = 0;
|
||||||
static tsk_bool_t __b_rel_ipv6_ss2 = 0;
|
static tsk_bool_t __b_rel_ipv6_ss2 = 0;
|
||||||
|
static tnet_turn_peer_id_t __u_peer_id2 = kTurnPeerIdInvalid;
|
||||||
|
|
||||||
static int _test_turn_session_callback(const struct tnet_turn_session_event_xs *e)
|
static int _test_turn_session_callback(const struct tnet_turn_session_event_xs *e)
|
||||||
{
|
{
|
||||||
|
@ -169,10 +161,11 @@ static int _test_turn_session_callback(const struct tnet_turn_session_event_xs *
|
||||||
uint16_t *pu_port = (pc_ss == __pc_ss2) ? &__u_rel_port_ss1 : &__u_rel_port_ss2;
|
uint16_t *pu_port = (pc_ss == __pc_ss2) ? &__u_rel_port_ss1 : &__u_rel_port_ss2;
|
||||||
char** pp_ip = (pc_ss == __pc_ss2) ? &__p_rel_ip_ss1 : &__p_rel_ip_ss2;
|
char** pp_ip = (pc_ss == __pc_ss2) ? &__p_rel_ip_ss1 : &__p_rel_ip_ss2;
|
||||||
tsk_bool_t *pb_ipv6 = (pc_ss == __pc_ss2) ? &__b_rel_ipv6_ss1 : &__b_rel_ipv6_ss2;
|
tsk_bool_t *pb_ipv6 = (pc_ss == __pc_ss2) ? &__b_rel_ipv6_ss1 : &__b_rel_ipv6_ss2;
|
||||||
|
tnet_turn_peer_id_t *pu_peer_id = (pc_ss == __pc_ss2) ? &__u_peer_id2 : &__u_peer_id1;
|
||||||
|
|
||||||
BAIL_IF_ERR(tnet_turn_session_get_relayed_addr(pc_ss, pp_ip, pu_port, pb_ipv6));
|
BAIL_IF_ERR(tnet_turn_session_get_relayed_addr(pc_ss, pp_ip, pu_port, pb_ipv6));
|
||||||
// BAIL_IF_ERR(tnet_turn_session_get_srflx_addr(pc_ss, pu_port, &u_port, &b_ipv6)); // get my own server reflexive address (in order to send data to myself)
|
// BAIL_IF_ERR(tnet_turn_session_get_srflx_addr(pc_ss, pu_port, &u_port, &b_ipv6)); // get my own server reflexive address (in order to send data to myself)
|
||||||
BAIL_IF_ERR(tnet_turn_session_createpermission((struct tnet_turn_session_s*)pc_ss, *pp_ip, *pu_port)); // Input = ADDR(remote.candidate.relay)
|
BAIL_IF_ERR(tnet_turn_session_createpermission((struct tnet_turn_session_s*)pc_ss, *pp_ip, *pu_port, pu_peer_id)); // Input = ADDR(remote.candidate.relay)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tnet_turn_session_event_type_alloc_nok:
|
case tnet_turn_session_event_type_alloc_nok:
|
||||||
|
@ -184,11 +177,12 @@ static int _test_turn_session_callback(const struct tnet_turn_session_event_xs *
|
||||||
{
|
{
|
||||||
static const char __pc_data[] = { "TURN Sample Data (Send Indication)" };
|
static const char __pc_data[] = { "TURN Sample Data (Send Indication)" };
|
||||||
int i;
|
int i;
|
||||||
|
tnet_turn_peer_id_t u_peer_id = (pc_ss == __pc_ss2) ? __u_peer_id2 : __u_peer_id1;
|
||||||
// Bind a channel (not required). If succeed, will be used to save data.
|
// Bind a channel (not required). If succeed, will be used to save data.
|
||||||
tnet_turn_session_chanbind((struct tnet_turn_session_s*)pc_ss);
|
tnet_turn_session_chanbind((struct tnet_turn_session_s*)pc_ss, u_peer_id);
|
||||||
// Send data (will use channel if one is active. Otherwise (no channel), SendIndications will be used)
|
// Send data (will use channel if one is active. Otherwise (no channel), SendIndications will be used)
|
||||||
for (i = 0; i < 10; ++i) {
|
for (i = 0; i < 10; ++i) {
|
||||||
BAIL_IF_ERR(tnet_turn_session_send_data((struct tnet_turn_session_s*)pc_ss, __pc_data, sizeof(__pc_data)));
|
BAIL_IF_ERR(tnet_turn_session_send_data((struct tnet_turn_session_s*)pc_ss, u_peer_id, __pc_data, sizeof(__pc_data)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -201,8 +195,9 @@ static int _test_turn_session_callback(const struct tnet_turn_session_event_xs *
|
||||||
{
|
{
|
||||||
static const char __pc_data[] = { "TURN Sample Data (ChannelData)" };
|
static const char __pc_data[] = { "TURN Sample Data (ChannelData)" };
|
||||||
int i;
|
int i;
|
||||||
|
tnet_turn_peer_id_t u_peer_id = (pc_ss == __pc_ss2) ? __u_peer_id2 : __u_peer_id1;
|
||||||
for (i = 0; i < 10; ++i) {
|
for (i = 0; i < 10; ++i) {
|
||||||
BAIL_IF_ERR(tnet_turn_session_send_data((struct tnet_turn_session_s*)pc_ss, __pc_data, sizeof(__pc_data)));
|
BAIL_IF_ERR(tnet_turn_session_send_data((struct tnet_turn_session_s*)pc_ss, u_peer_id, __pc_data, sizeof(__pc_data)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@
|
||||||
Optimization="3"
|
Optimization="3"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
AdditionalIncludeDirectories="src;"..\thirdparties\win32\include";"..\tinySAK\src""
|
AdditionalIncludeDirectories="src;"..\thirdparties\win32\include";"..\tinySAK\src""
|
||||||
PreprocessorDefinitions="DEBUG_LEVEL=DEBUG_LEVEL_ERROR;HAVE_OPENSSL=1;WIN32;NDEBUG;_WINDOWS;_USRDLL;TINYNET_EXPORTS"
|
PreprocessorDefinitions="DEBUG_LEVEL=DEBUG_LEVEL_ERROR;HAVE_OPENSSL=1;WIN32;_WIN32_WINNT=0x0501;NDEBUG;_WINDOWS;_USRDLL;TINYNET_EXPORTS"
|
||||||
RuntimeLibrary="2"
|
RuntimeLibrary="2"
|
||||||
EnableFunctionLevelLinking="false"
|
EnableFunctionLevelLinking="false"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
|
@ -236,6 +236,10 @@
|
||||||
RelativePath=".\src\stun\tnet_stun_attribute.c"
|
RelativePath=".\src\stun\tnet_stun_attribute.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\stun\tnet_stun_binding.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\stun\tnet_stun_message.c"
|
RelativePath=".\src\stun\tnet_stun_message.c"
|
||||||
>
|
>
|
||||||
|
@ -488,6 +492,10 @@
|
||||||
RelativePath=".\src\stun\tnet_stun_attribute.h"
|
RelativePath=".\src\stun\tnet_stun_attribute.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\stun\tnet_stun_binding.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\stun\tnet_stun_message.h"
|
RelativePath=".\src\stun\tnet_stun_message.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -40,10 +40,12 @@ TRTP_BEGIN_DECLS
|
||||||
|
|
||||||
struct trtp_rtcp_packet_s;
|
struct trtp_rtcp_packet_s;
|
||||||
struct trtp_rtp_packet_s;
|
struct trtp_rtp_packet_s;
|
||||||
|
struct tnet_ice_ctx_s;
|
||||||
|
|
||||||
typedef int (*trtp_rtcp_cb_f)(const void* callback_data, const struct trtp_rtcp_packet_s* packet);
|
typedef int (*trtp_rtcp_cb_f)(const void* callback_data, const struct trtp_rtcp_packet_s* packet);
|
||||||
|
|
||||||
struct trtp_rtcp_session_s* trtp_rtcp_session_create(uint32_t ssrc, const char* cname);
|
struct trtp_rtcp_session_s* trtp_rtcp_session_create(uint32_t ssrc, const char* cname);
|
||||||
|
struct trtp_rtcp_session_s* trtp_rtcp_session_create_2(struct tnet_ice_ctx_s* ice_ctx, uint32_t ssrc, const char* cname);
|
||||||
int trtp_rtcp_session_set_callback(struct trtp_rtcp_session_s* self, trtp_rtcp_cb_f callback, const void* callback_data);
|
int trtp_rtcp_session_set_callback(struct trtp_rtcp_session_s* self, trtp_rtcp_cb_f callback, const void* callback_data);
|
||||||
#if HAVE_SRTP
|
#if HAVE_SRTP
|
||||||
int trtp_rtcp_session_set_srtp_sess(struct trtp_rtcp_session_s* self, const srtp_t* session);
|
int trtp_rtcp_session_set_srtp_sess(struct trtp_rtcp_session_s* self, const srtp_t* session);
|
||||||
|
|
|
@ -50,6 +50,7 @@ typedef struct trtp_manager_s
|
||||||
tsk_bool_t use_rtcpmux;
|
tsk_bool_t use_rtcpmux;
|
||||||
tsk_bool_t is_socket_disabled;
|
tsk_bool_t is_socket_disabled;
|
||||||
tsk_bool_t is_ice_neg_ok;
|
tsk_bool_t is_ice_neg_ok;
|
||||||
|
tsk_bool_t is_ice_turn_active;
|
||||||
tsk_bool_t is_force_symetric_rtp;
|
tsk_bool_t is_force_symetric_rtp;
|
||||||
tsk_bool_t is_symetric_rtp_checked;
|
tsk_bool_t is_symetric_rtp_checked;
|
||||||
tsk_bool_t is_symetric_rtcp_checked;
|
tsk_bool_t is_symetric_rtcp_checked;
|
||||||
|
@ -189,7 +190,7 @@ TINYRTP_API int trtp_manager_set_srtp_type_remote(trtp_manager_t* self, enum tme
|
||||||
TINYRTP_API int trtp_manager_set_srtp_type_local(trtp_manager_t* self, enum tmedia_srtp_type_e srtp_type, enum tmedia_srtp_mode_e srtp_mode);
|
TINYRTP_API int trtp_manager_set_srtp_type_local(trtp_manager_t* self, enum tmedia_srtp_type_e srtp_type, enum tmedia_srtp_mode_e srtp_mode);
|
||||||
#endif /* HAVE_SRTP */
|
#endif /* HAVE_SRTP */
|
||||||
TINYRTP_API tsk_bool_t trtp_manager_is_ready(trtp_manager_t* self);
|
TINYRTP_API tsk_bool_t trtp_manager_is_ready(trtp_manager_t* self);
|
||||||
TINYRTP_API int trtp_manager_set_natt_ctx(trtp_manager_t* self, tnet_nat_context_handle_t* natt_ctx);
|
TINYRTP_API int trtp_manager_set_natt_ctx(trtp_manager_t* self, struct tnet_nat_ctx_s* natt_ctx);
|
||||||
TINYRTP_API int trtp_manager_set_rtp_callback(trtp_manager_t* self, trtp_rtp_cb_f fun, const void* usrdata);
|
TINYRTP_API int trtp_manager_set_rtp_callback(trtp_manager_t* self, trtp_rtp_cb_f fun, const void* usrdata);
|
||||||
TINYRTP_API int trtp_manager_set_rtcp_callback(trtp_manager_t* self, trtp_rtcp_cb_f fun, const void* usrdata);
|
TINYRTP_API int trtp_manager_set_rtcp_callback(trtp_manager_t* self, trtp_rtcp_cb_f fun, const void* usrdata);
|
||||||
TINYRTP_API int trtp_manager_set_rtp_dscp(trtp_manager_t* self, int32_t dscp);
|
TINYRTP_API int trtp_manager_set_rtp_dscp(trtp_manager_t* self, int32_t dscp);
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
#include "tinyrtp/rtcp/trtp_rtcp_report_fb.h"
|
#include "tinyrtp/rtcp/trtp_rtcp_report_fb.h"
|
||||||
#include "tinyrtp/rtp/trtp_rtp_packet.h"
|
#include "tinyrtp/rtp/trtp_rtp_packet.h"
|
||||||
|
|
||||||
|
#include "ice/tnet_ice_ctx.h"
|
||||||
|
#include "turn/tnet_turn_session.h"
|
||||||
|
|
||||||
#include "tnet_utils.h"
|
#include "tnet_utils.h"
|
||||||
|
|
||||||
#include "tsk_string.h"
|
#include "tsk_string.h"
|
||||||
|
@ -263,9 +266,11 @@ typedef struct trtp_rtcp_session_s
|
||||||
{
|
{
|
||||||
TSK_DECLARE_OBJECT;
|
TSK_DECLARE_OBJECT;
|
||||||
|
|
||||||
tsk_bool_t started;
|
tsk_bool_t is_started;
|
||||||
tnet_fd_t local_fd;
|
tnet_fd_t local_fd;
|
||||||
const struct sockaddr * remote_addr;
|
const struct sockaddr * remote_addr;
|
||||||
|
struct tnet_ice_ctx_s* ice_ctx;
|
||||||
|
tsk_bool_t is_ice_turn_active;
|
||||||
|
|
||||||
const void* callback_data;
|
const void* callback_data;
|
||||||
trtp_rtcp_cb_f callback;
|
trtp_rtcp_cb_f callback;
|
||||||
|
@ -350,6 +355,7 @@ static tsk_object_t* trtp_rtcp_session_dtor(tsk_object_t * self)
|
||||||
TSK_OBJECT_SAFE_FREE(session->sources);
|
TSK_OBJECT_SAFE_FREE(session->sources);
|
||||||
TSK_OBJECT_SAFE_FREE(session->source_local);
|
TSK_OBJECT_SAFE_FREE(session->source_local);
|
||||||
TSK_OBJECT_SAFE_FREE(session->sdes);
|
TSK_OBJECT_SAFE_FREE(session->sdes);
|
||||||
|
TSK_OBJECT_SAFE_FREE(session->ice_ctx);
|
||||||
TSK_FREE(session->cname);
|
TSK_FREE(session->cname);
|
||||||
// release the handle for the global timer manager
|
// release the handle for the global timer manager
|
||||||
tsk_timer_mgr_global_unref(&session->timer.handle_global);
|
tsk_timer_mgr_global_unref(&session->timer.handle_global);
|
||||||
|
@ -375,6 +381,7 @@ static int _trtp_rtcp_session_add_source(trtp_rtcp_session_t* self, trtp_rtcp_so
|
||||||
static int _trtp_rtcp_session_add_source_2(trtp_rtcp_session_t* self, uint32_t ssrc, uint16_t seq, uint32_t ts, tsk_bool_t *added);
|
static int _trtp_rtcp_session_add_source_2(trtp_rtcp_session_t* self, uint32_t ssrc, uint16_t seq, uint32_t ts, tsk_bool_t *added);
|
||||||
static int _trtp_rtcp_session_remove_source(trtp_rtcp_session_t* self, uint32_t ssrc, tsk_bool_t *removed);
|
static int _trtp_rtcp_session_remove_source(trtp_rtcp_session_t* self, uint32_t ssrc, tsk_bool_t *removed);
|
||||||
static tsk_size_t _trtp_rtcp_session_send_pkt(trtp_rtcp_session_t* self, trtp_rtcp_packet_t* pkt);
|
static tsk_size_t _trtp_rtcp_session_send_pkt(trtp_rtcp_session_t* self, trtp_rtcp_packet_t* pkt);
|
||||||
|
static tsk_size_t _trtp_rtcp_session_send_raw(trtp_rtcp_session_t* self, const void* data, tsk_size_t size);
|
||||||
static int _trtp_rtcp_session_timer_callback(const void* arg, tsk_timer_id_t timer_id);
|
static int _trtp_rtcp_session_timer_callback(const void* arg, tsk_timer_id_t timer_id);
|
||||||
|
|
||||||
static void Schedule(trtp_rtcp_session_t* session, double tn, event_ e);
|
static void Schedule(trtp_rtcp_session_t* session, double tn, event_ e);
|
||||||
|
@ -409,6 +416,17 @@ bail:
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct trtp_rtcp_session_s* trtp_rtcp_session_create_2(struct tnet_ice_ctx_s* ice_ctx, uint32_t ssrc, const char* cname)
|
||||||
|
{
|
||||||
|
struct trtp_rtcp_session_s* session = trtp_rtcp_session_create(ssrc, cname);
|
||||||
|
if (session) {
|
||||||
|
if ((session->ice_ctx = tsk_object_ref(ice_ctx))) {
|
||||||
|
session->is_ice_turn_active = tnet_ice_ctx_is_turn_rtcp_active(session->ice_ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
int trtp_rtcp_session_set_callback(trtp_rtcp_session_t* self, trtp_rtcp_cb_f callback, const void* callback_data)
|
int trtp_rtcp_session_set_callback(trtp_rtcp_session_t* self, trtp_rtcp_cb_f callback, const void* callback_data)
|
||||||
{
|
{
|
||||||
if(!self){
|
if(!self){
|
||||||
|
@ -451,7 +469,7 @@ int trtp_rtcp_session_set_app_bandwidth_max(trtp_rtcp_session_t* self, int32_t b
|
||||||
self->app_bw_max_upload = bw_upload_kbps;
|
self->app_bw_max_upload = bw_upload_kbps;
|
||||||
self->app_bw_max_download = bw_download_kbps;
|
self->app_bw_max_download = bw_download_kbps;
|
||||||
|
|
||||||
if(self->started && self->source_local && self->app_bw_max_download > 0 && self->app_bw_max_download != INT_MAX){ // INT_MAX or <=0 means undefined
|
if(self->is_started && self->source_local && self->app_bw_max_download > 0 && self->app_bw_max_download != INT_MAX){ // INT_MAX or <=0 means undefined
|
||||||
tsk_list_item_t* item;
|
tsk_list_item_t* item;
|
||||||
uint32_t media_ssrc_list[256] = {0};
|
uint32_t media_ssrc_list[256] = {0};
|
||||||
uint32_t media_ssrc_list_count = 0;
|
uint32_t media_ssrc_list_count = 0;
|
||||||
|
@ -492,7 +510,7 @@ int trtp_rtcp_session_start(trtp_rtcp_session_t* self, tnet_fd_t local_fd, const
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(self->started){
|
if(self->is_started){
|
||||||
TSK_DEBUG_WARN("Already started");
|
TSK_DEBUG_WARN("Already started");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -512,7 +530,7 @@ int trtp_rtcp_session_start(trtp_rtcp_session_t* self, tnet_fd_t local_fd, const
|
||||||
// set start time
|
// set start time
|
||||||
self->time_start = tsk_time_now();
|
self->time_start = tsk_time_now();
|
||||||
|
|
||||||
self->started = tsk_true;
|
self->is_started = tsk_true;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -526,7 +544,7 @@ int trtp_rtcp_session_stop(trtp_rtcp_session_t* self)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(self->started){
|
if(self->is_started){
|
||||||
// send BYE synchronous way
|
// send BYE synchronous way
|
||||||
SendBYEPacket(self, EVENT_REPORT);
|
SendBYEPacket(self, EVENT_REPORT);
|
||||||
|
|
||||||
|
@ -542,7 +560,7 @@ int trtp_rtcp_session_stop(trtp_rtcp_session_t* self)
|
||||||
self->timer.id_report = TSK_INVALID_TIMER_ID;
|
self->timer.id_report = TSK_INVALID_TIMER_ID;
|
||||||
}
|
}
|
||||||
tsk_safeobj_unlock(self);
|
tsk_safeobj_unlock(self);
|
||||||
self->started = tsk_false;
|
self->is_started = tsk_false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -557,7 +575,7 @@ int trtp_rtcp_session_process_rtp_out(trtp_rtcp_session_t* self, const trtp_rtp_
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!self->started){
|
if(!self->is_started){
|
||||||
TSK_DEBUG_ERROR("Not started");
|
TSK_DEBUG_ERROR("Not started");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
@ -612,7 +630,7 @@ int trtp_rtcp_session_process_rtp_in(trtp_rtcp_session_t* self, const trtp_rtp_p
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!self->started){
|
if(!self->is_started){
|
||||||
TSK_DEBUG_INFO("RTCP session not started");
|
TSK_DEBUG_INFO("RTCP session not started");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
@ -648,7 +666,7 @@ int trtp_rtcp_session_process_rtcp_in(trtp_rtcp_session_t* self, const void* buf
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!self->started){
|
if(!self->is_started){
|
||||||
TSK_DEBUG_ERROR("Not started");
|
TSK_DEBUG_ERROR("Not started");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
@ -690,7 +708,7 @@ int trtp_rtcp_session_signal_pkt_loss(trtp_rtcp_session_t* self, uint32_t ssrc_m
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(!self->started){
|
if(!self->is_started){
|
||||||
TSK_DEBUG_ERROR("Not started");
|
TSK_DEBUG_ERROR("Not started");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -720,7 +738,7 @@ int trtp_rtcp_session_signal_frame_corrupted(trtp_rtcp_session_t* self, uint32_t
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(!self->started){
|
if(!self->is_started){
|
||||||
TSK_DEBUG_ERROR("Not started");
|
TSK_DEBUG_ERROR("Not started");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -889,15 +907,31 @@ static tsk_size_t _trtp_rtcp_session_send_pkt(trtp_rtcp_session_t* self, trtp_rt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(tnet_sockfd_sendto(self->local_fd, self->remote_addr, data, size) > 0){
|
ret = _trtp_rtcp_session_send_raw(self, data, size);
|
||||||
ret = size;
|
|
||||||
}
|
|
||||||
TSK_OBJECT_SAFE_FREE(buffer);
|
TSK_OBJECT_SAFE_FREE(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static tsk_size_t _trtp_rtcp_session_send_raw(trtp_rtcp_session_t* self, const void* data, tsk_size_t size)
|
||||||
|
{
|
||||||
|
tsk_size_t ret = 0;
|
||||||
|
if (!self || !data || !size) {
|
||||||
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (self->is_ice_turn_active) {
|
||||||
|
ret = (tnet_ice_ctx_send_turn_rtcp(self->ice_ctx, data, size) == 0) ? size : 0; // returns #0 if ok
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (tnet_sockfd_sendto(self->local_fd, self->remote_addr, data, size) == size){ // returns number of sent bytes
|
||||||
|
ret = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int _trtp_rtcp_session_timer_callback(const void* arg, tsk_timer_id_t timer_id)
|
static int _trtp_rtcp_session_timer_callback(const void* arg, tsk_timer_id_t timer_id)
|
||||||
{
|
{
|
||||||
trtp_rtcp_session_t* session = (trtp_rtcp_session_t*)arg;
|
trtp_rtcp_session_t* session = (trtp_rtcp_session_t*)arg;
|
||||||
|
@ -1150,7 +1184,7 @@ static void SendBYEPacket(trtp_rtcp_session_t* session, event_ e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
tnet_sockfd_sendto(session->local_fd, session->remote_addr, data, size);
|
_trtp_rtcp_session_send_raw(session, data, size);
|
||||||
TSK_OBJECT_SAFE_FREE(buffer);
|
TSK_OBJECT_SAFE_FREE(buffer);
|
||||||
}
|
}
|
||||||
TSK_OBJECT_SAFE_FREE(bye);
|
TSK_OBJECT_SAFE_FREE(bye);
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "tinyrtp/rtcp/trtp_rtcp_packet.h"
|
#include "tinyrtp/rtcp/trtp_rtcp_packet.h"
|
||||||
#include "tinyrtp/rtcp/trtp_rtcp_session.h"
|
#include "tinyrtp/rtcp/trtp_rtcp_session.h"
|
||||||
|
|
||||||
|
#include "turn/tnet_turn_session.h"
|
||||||
#include "ice/tnet_ice_candidate.h"
|
#include "ice/tnet_ice_candidate.h"
|
||||||
|
|
||||||
#include "tsk_string.h"
|
#include "tsk_string.h"
|
||||||
|
@ -92,28 +93,18 @@ static int _trtp_transport_layer_cb(const tnet_transport_event_t* e)
|
||||||
/* DTLS - SRTP events */
|
/* DTLS - SRTP events */
|
||||||
case event_dtls_handshake_succeed:
|
case event_dtls_handshake_succeed:
|
||||||
{
|
{
|
||||||
const tnet_socket_t* socket = manager->transport->master && (manager->transport->master->fd == e->local_fd)
|
const tnet_socket_t* socket = manager->transport && manager->transport->master && (manager->transport->master->fd == e->local_fd)
|
||||||
? manager->transport->master
|
? manager->transport->master
|
||||||
: ((manager->rtcp.local_socket && manager->rtcp.local_socket->fd == e->local_fd) ? manager->rtcp.local_socket : tsk_null);
|
: ((manager->rtcp.local_socket && manager->rtcp.local_socket->fd == e->local_fd) ? manager->rtcp.local_socket : tsk_null);
|
||||||
if(!socket){
|
if(!socket){
|
||||||
TSK_DEBUG_ERROR("DTLS data from unknown socket");
|
TSK_DEBUG_ERROR("DTLS data from unknown socket");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// cancel handshaking timer when both SRTP and SRTCP are connected
|
|
||||||
tsk_safeobj_lock(manager);
|
|
||||||
if(manager->dtls.srtp_connected && manager->dtls.srtcp_connected){
|
|
||||||
if(manager->dtls.timer_hanshaking.id != TSK_INVALID_TIMER_ID){
|
|
||||||
tsk_timer_manager_cancel(manager->timer_mgr_global, manager->dtls.timer_hanshaking.id);
|
|
||||||
manager->dtls.timer_hanshaking.id = TSK_INVALID_TIMER_ID; // invalidate timer id (not required but should be done by good citizen)
|
|
||||||
manager->dtls.timer_hanshaking.timeout = TRTP_DTLS_HANDSHAKING_TIMEOUT; // reset timeout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tsk_safeobj_unlock(manager);
|
|
||||||
|
|
||||||
if(!manager->dtls.srtp_handshake_succeed){
|
if (!manager->dtls.srtp_handshake_succeed) {
|
||||||
manager->dtls.srtp_handshake_succeed = (socket == manager->transport->master);
|
manager->dtls.srtp_handshake_succeed = (socket == manager->transport->master);
|
||||||
}
|
}
|
||||||
if(!manager->dtls.srtcp_handshake_succeed){
|
if (!manager->dtls.srtcp_handshake_succeed) {
|
||||||
manager->dtls.srtcp_handshake_succeed = (socket == manager->rtcp.local_socket) || _trtp_manager_is_rtcpmux_active(manager);
|
manager->dtls.srtcp_handshake_succeed = (socket == manager->rtcp.local_socket) || _trtp_manager_is_rtcpmux_active(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,26 +240,43 @@ static int _trtp_transport_dtls_handshaking_timer_cb(const void* arg, tsk_timer_
|
||||||
{
|
{
|
||||||
#if HAVE_SRTP
|
#if HAVE_SRTP
|
||||||
trtp_manager_t* manager = (trtp_manager_t*)arg;
|
trtp_manager_t* manager = (trtp_manager_t*)arg;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
tsk_safeobj_lock(manager);
|
tsk_safeobj_lock(manager);
|
||||||
if(manager->is_started && manager->dtls.timer_hanshaking.id == timer_id && manager->srtp_state == trtp_srtp_state_activated && manager->srtp_type == tmedia_srtp_type_dtls){
|
if (manager->is_started && manager->dtls.timer_hanshaking.id == timer_id && manager->srtp_state == trtp_srtp_state_activated && manager->srtp_type == tmedia_srtp_type_dtls) {
|
||||||
// retry DTLS-SRTP handshaking if srtp-type is DTLS-SRTP and the engine is activated
|
// retry DTLS-SRTP handshaking if srtp-type is DTLS-SRTP and the engine is activated
|
||||||
struct tnet_socket_s* sockets[] = { manager->transport->master , manager->rtcp.local_socket };
|
struct tnet_socket_s* sockets[] = { manager->dtls.srtp_connected ? tsk_null : manager->transport->master , manager->dtls.srtcp_connected ? tsk_null : manager->rtcp.local_socket };
|
||||||
const struct sockaddr_storage* remote_addrs[] = { &manager->rtp.remote_addr, &manager->rtcp.remote_addr };
|
const struct sockaddr_storage* remote_addrs[] = { &manager->rtp.remote_addr, &manager->rtcp.remote_addr };
|
||||||
TSK_DEBUG_INFO("_trtp_transport_dtls_handshaking_timer_cb(timeout=%llu)", manager->dtls.timer_hanshaking.timeout);
|
TSK_DEBUG_INFO("_trtp_transport_dtls_handshaking_timer_cb(timeout=%llu)", manager->dtls.timer_hanshaking.timeout);
|
||||||
tnet_transport_dtls_do_handshake(manager->transport, sockets, 2, remote_addrs, 2);
|
tnet_transport_dtls_do_handshake(manager->transport, sockets, 2, remote_addrs, 2);
|
||||||
|
if (manager->is_ice_turn_active) {
|
||||||
|
// means TURN is active and handshaking data must be sent using the channel
|
||||||
|
const void* data[] = { tsk_null, tsk_null };
|
||||||
|
tsk_size_t size[] = { 0, 0 };
|
||||||
|
if ((ret = tnet_transport_dtls_get_handshakingdata(manager->transport, sockets, 2, data, size))) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (data[0] && size[0]) {
|
||||||
|
ret = tnet_ice_ctx_send_turn_rtp(manager->ice_ctx, data[0], size[0]);
|
||||||
|
}
|
||||||
|
if (data[1] && size[1]) {
|
||||||
|
ret = tnet_ice_ctx_send_turn_rtcp(manager->ice_ctx, data[1], size[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
// increase timeout
|
// increase timeout
|
||||||
manager->dtls.timer_hanshaking.timeout += (TRTP_DTLS_HANDSHAKING_TIMEOUT >> 1);
|
manager->dtls.timer_hanshaking.timeout += (TRTP_DTLS_HANDSHAKING_TIMEOUT >> 1);
|
||||||
if(manager->dtls.timer_hanshaking.timeout < TRTP_DTLS_HANDSHAKING_TIMEOUT_MAX){
|
if ((manager->dtls.timer_hanshaking.timeout < TRTP_DTLS_HANDSHAKING_TIMEOUT_MAX) && !(manager->dtls.srtp_connected && manager->dtls.srtcp_connected)) {
|
||||||
manager->dtls.timer_hanshaking.id = tsk_timer_manager_schedule(manager->timer_mgr_global, manager->dtls.timer_hanshaking.timeout, _trtp_transport_dtls_handshaking_timer_cb, manager);
|
manager->dtls.timer_hanshaking.id = tsk_timer_manager_schedule(manager->timer_mgr_global, manager->dtls.timer_hanshaking.timeout, _trtp_transport_dtls_handshaking_timer_cb, manager);
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
manager->dtls.timer_hanshaking.id = TSK_INVALID_TIMER_ID; // not required but we're good citizen
|
manager->dtls.timer_hanshaking.id = TSK_INVALID_TIMER_ID; // invalidate timer id (not required but should be done by good citizen)
|
||||||
|
manager->dtls.timer_hanshaking.timeout = TRTP_DTLS_HANDSHAKING_TIMEOUT; // reset timeout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tsk_safeobj_unlock(manager);
|
tsk_safeobj_unlock(manager);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -333,6 +341,11 @@ static int _trtp_manager_recv_data(const trtp_manager_t* self, const uint8_t* da
|
||||||
{
|
{
|
||||||
tsk_bool_t is_rtp_rtcp, is_rtcp = tsk_false, is_rtp = tsk_false, is_stun, is_dtls;
|
tsk_bool_t is_rtp_rtcp, is_rtcp = tsk_false, is_rtp = tsk_false, is_stun, is_dtls;
|
||||||
|
|
||||||
|
if (!self->is_started) {
|
||||||
|
TSK_DEBUG_INFO("RTP manager not started yet");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// defined when RTCP-MUX is disabled and RTCP port is equal to "RTP Port + 1"
|
// defined when RTCP-MUX is disabled and RTCP port is equal to "RTP Port + 1"
|
||||||
|
|
||||||
// rfc5764 - 5.1.2. Reception
|
// rfc5764 - 5.1.2. Reception
|
||||||
|
@ -356,16 +369,30 @@ static int _trtp_manager_recv_data(const trtp_manager_t* self, const uint8_t* da
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
is_dtls = !is_rtp_rtcp && (19 < *data_ptr && *data_ptr < 64);
|
is_dtls = !is_rtp_rtcp && (19 < *data_ptr && *data_ptr < 64);
|
||||||
is_stun = !is_dtls && TNET_IS_STUN2_MSG(data_ptr, data_size); /* MUST NOT USE: "(*data_ptr < 2)" beacause of "Old VAT" which starts with "0x00" */;
|
is_stun = !is_dtls && TNET_STUN_BUFF_IS_STUN2(data_ptr, data_size); /* MUST NOT USE: "(*data_ptr < 2)" beacause of "Old VAT" which starts with "0x00" */;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_dtls){
|
if(is_dtls){
|
||||||
tnet_socket_t* socket = (self->transport->master && self->transport->master->fd == local_fd)
|
tnet_socket_t* socket = (self->transport && self->transport->master && self->transport->master->fd == local_fd)
|
||||||
? self->transport->master
|
? self->transport->master
|
||||||
: ((self->rtcp.local_socket && self->rtcp.local_socket->fd == local_fd) ? self->rtcp.local_socket : tsk_null);
|
: ((self->rtcp.local_socket && self->rtcp.local_socket->fd == local_fd) ? self->rtcp.local_socket : tsk_null);
|
||||||
if(socket){
|
if (socket && socket->dtlshandle) {
|
||||||
TSK_DEBUG_INFO("Receive %s-DTLS data on ip=%s and port=%d", (socket == self->transport->master) ? "RTP" : "RTCP", socket->ip, socket->port);
|
TSK_DEBUG_INFO("Receive %s-DTLS data on ip=%s and port=%d", (socket == self->transport->master) ? "RTP" : "RTCP", socket->ip, socket->port);
|
||||||
return tnet_dtls_socket_handle_incoming_data(socket->dtlshandle, data_ptr, data_size);
|
// Handle incoming data then do handshaking
|
||||||
|
tnet_dtls_socket_handle_incoming_data(socket->dtlshandle, data_ptr, data_size);
|
||||||
|
if (self->is_ice_turn_active) {
|
||||||
|
// means TURN is active and handshaking data must be sent using the channel
|
||||||
|
const void* data = tsk_null;
|
||||||
|
tsk_size_t size = 0;
|
||||||
|
if (tnet_transport_dtls_get_handshakingdata(self->transport, &socket, 1, &data, &size) == 0) {
|
||||||
|
if (self->rtcp.local_socket == socket) {
|
||||||
|
/*ret = */tnet_ice_ctx_send_turn_rtcp(self->ice_ctx, data, size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*ret = */tnet_ice_ctx_send_turn_rtp(self->ice_ctx, data, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -543,6 +570,7 @@ static int _trtp_manager_srtp_activate(trtp_manager_t* self, tmedia_srtp_type_t
|
||||||
*/
|
*/
|
||||||
struct tnet_socket_s* sockets[] = { self->transport->master , self->rtcp.local_socket };
|
struct tnet_socket_s* sockets[] = { self->transport->master , self->rtcp.local_socket };
|
||||||
const struct sockaddr_storage* remote_addrs[] = { &self->rtp.remote_addr, &self->rtcp.remote_addr };
|
const struct sockaddr_storage* remote_addrs[] = { &self->rtp.remote_addr, &self->rtcp.remote_addr };
|
||||||
|
tsk_bool_t store_handshakingdata[] = { self->is_ice_turn_active, self->is_ice_turn_active };
|
||||||
|
|
||||||
// check if DTLS-SRTP enabling was postponed because the net transport was not ready (could happen if ICE is ON)
|
// check if DTLS-SRTP enabling was postponed because the net transport was not ready (could happen if ICE is ON)
|
||||||
if(self->dtls.enable_postponed){
|
if(self->dtls.enable_postponed){
|
||||||
|
@ -575,10 +603,28 @@ static int _trtp_manager_srtp_activate(trtp_manager_t* self, tmedia_srtp_type_t
|
||||||
if((ret = tnet_transport_dtls_set_setup(self->transport, self->dtls.local.setup, sockets, 2))){
|
if((ret = tnet_transport_dtls_set_setup(self->transport, self->dtls.local.setup, sockets, 2))){
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
// start handshaking process (will do nothing if already completed)
|
// whether to send DTLS handshaking data using the provided sockets or TURN session
|
||||||
if((ret = tnet_transport_dtls_do_handshake(self->transport, sockets, 2, remote_addrs, 2))){
|
if ((ret = tnet_transport_dtls_set_store_handshakingdata(self->transport, store_handshakingdata[0], sockets, 2))) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
// start handshaking process (will do nothing if already completed)
|
||||||
|
if ((ret = tnet_transport_dtls_do_handshake(self->transport, sockets, 2, remote_addrs, 2))) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (store_handshakingdata[0]) {
|
||||||
|
// means TURN is active and handshaking data must be sent using the channel
|
||||||
|
const void* data[] = { tsk_null, tsk_null };
|
||||||
|
tsk_size_t size[] = { 0, 0 };
|
||||||
|
if ((ret = tnet_transport_dtls_get_handshakingdata(self->transport, sockets, 2, data, size))) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (data[0] && size[0]) {
|
||||||
|
ret = tnet_ice_ctx_send_turn_rtp(self->ice_ctx, data[0], size[0]);
|
||||||
|
}
|
||||||
|
if (data[1] && size[1]) {
|
||||||
|
ret = tnet_ice_ctx_send_turn_rtcp(self->ice_ctx, data[1], size[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self->dtls.state = trtp_srtp_state_activated;
|
self->dtls.state = trtp_srtp_state_activated;
|
||||||
}
|
}
|
||||||
|
@ -586,7 +632,7 @@ static int _trtp_manager_srtp_activate(trtp_manager_t* self, tmedia_srtp_type_t
|
||||||
self->srtp_state = trtp_srtp_state_activated;
|
self->srtp_state = trtp_srtp_state_activated;
|
||||||
|
|
||||||
// SDES-SRTP could be started right now while DTLS requires the handshaking to terminate
|
// SDES-SRTP could be started right now while DTLS requires the handshaking to terminate
|
||||||
if(srtp_type & tmedia_srtp_type_sdes){
|
if (srtp_type & tmedia_srtp_type_sdes) {
|
||||||
return _trtp_manager_srtp_start(self, self->srtp_type);
|
return _trtp_manager_srtp_start(self, self->srtp_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -656,21 +702,22 @@ static int _trtp_manager_ice_init(trtp_manager_t* self)
|
||||||
int ret;
|
int ret;
|
||||||
const tnet_ice_candidate_t *candidate_offer, *candidate_answer_src, *candidate_answer_dest;
|
const tnet_ice_candidate_t *candidate_offer, *candidate_answer_src, *candidate_answer_dest;
|
||||||
|
|
||||||
if(!self || !self->ice_ctx){
|
if (!self || !self->ice_ctx) {
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!self->transport){
|
if (!self->transport) {
|
||||||
// get rtp nominated symetric candidates
|
// get rtp nominated symetric candidates
|
||||||
ret = tnet_ice_ctx_get_nominated_symetric_candidates(self->ice_ctx, TNET_ICE_CANDIDATE_COMPID_RTP,
|
ret = tnet_ice_ctx_get_nominated_symetric_candidates(self->ice_ctx, TNET_ICE_CANDIDATE_COMPID_RTP,
|
||||||
&candidate_offer, &candidate_answer_src, &candidate_answer_dest);
|
&candidate_offer, &candidate_answer_src, &candidate_answer_dest);
|
||||||
self->is_ice_neg_ok = (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest);
|
self->is_ice_neg_ok = (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest);
|
||||||
if(!self->is_ice_neg_ok){
|
self->is_ice_turn_active = self->is_ice_neg_ok && tnet_ice_ctx_is_turn_rtp_active(self->ice_ctx);
|
||||||
|
if (!self->is_ice_neg_ok) {
|
||||||
// If this code is called this means that ICE negotiation has failed
|
// If this code is called this means that ICE negotiation has failed
|
||||||
// This is not really an error because it could happen if the remote peer is not an ICE agent or is an ICE-lite
|
// This is not really an error because it could happen if the remote peer is not an ICE agent or is an ICE-lite
|
||||||
// in this case, use the first offered candidate which is the best one and already used in the "c=" line
|
// in this case, use the first offered candidate which is the best one and already used in the "c=" line
|
||||||
if(!(candidate_offer = tnet_ice_ctx_get_local_candidate_at(self->ice_ctx, 0))){
|
if (!(candidate_offer = tnet_ice_ctx_get_local_candidate_first(self->ice_ctx))) {
|
||||||
// Must never happen as we always have at least one local "host" candidate
|
// Must never happen as we always have at least one local "host" candidate
|
||||||
TSK_DEBUG_ERROR("ICE context not ready");
|
TSK_DEBUG_ERROR("ICE context not ready");
|
||||||
return -3;
|
return -3;
|
||||||
|
@ -678,12 +725,12 @@ static int _trtp_manager_ice_init(trtp_manager_t* self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create transport
|
// create transport
|
||||||
if(!(self->transport = tnet_transport_create_2(candidate_offer->socket, TRTP_TRANSPORT_NAME))){
|
if (!(self->transport = tnet_transport_create_2(candidate_offer->socket, TRTP_TRANSPORT_NAME))) {
|
||||||
TSK_DEBUG_ERROR("Failed to create transport(%s:%u)", candidate_offer->socket->ip, candidate_offer->socket->port);
|
TSK_DEBUG_ERROR("Failed to create transport(%s:%u)", candidate_offer->socket->ip, candidate_offer->socket->port);
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
// set rtp local and remote IPs and ports
|
// set rtp local and remote IPs and ports
|
||||||
if(candidate_answer_dest){ // could be "null" if remote peer is ICE-lite
|
if (candidate_answer_dest) { // could be "null" if remote peer is ICE-lite
|
||||||
tsk_strupdate(&self->rtp.remote_ip, candidate_answer_dest->connection_addr);
|
tsk_strupdate(&self->rtp.remote_ip, candidate_answer_dest->connection_addr);
|
||||||
self->rtp.remote_port = candidate_answer_dest->port;
|
self->rtp.remote_port = candidate_answer_dest->port;
|
||||||
tsk_strupdate(&self->rtp.public_ip, candidate_offer->connection_addr);
|
tsk_strupdate(&self->rtp.public_ip, candidate_offer->connection_addr);
|
||||||
|
@ -691,10 +738,10 @@ static int _trtp_manager_ice_init(trtp_manager_t* self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get rtp nominated symetric candidates
|
// get rtp nominated symetric candidates
|
||||||
if(self->use_rtcp){
|
if (self->use_rtcp) {
|
||||||
ret = tnet_ice_ctx_get_nominated_symetric_candidates(self->ice_ctx, TNET_ICE_CANDIDATE_COMPID_RTCP,
|
ret = tnet_ice_ctx_get_nominated_symetric_candidates(self->ice_ctx, TNET_ICE_CANDIDATE_COMPID_RTCP,
|
||||||
&candidate_offer, &candidate_answer_src, &candidate_answer_dest);
|
&candidate_offer, &candidate_answer_src, &candidate_answer_dest);
|
||||||
if(ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest){
|
if (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest) {
|
||||||
// set rtp local and remote IPs and ports
|
// set rtp local and remote IPs and ports
|
||||||
tsk_strupdate(&self->rtcp.remote_ip, candidate_answer_dest->connection_addr);
|
tsk_strupdate(&self->rtcp.remote_ip, candidate_answer_dest->connection_addr);
|
||||||
self->rtcp.remote_port = candidate_answer_dest->port;
|
self->rtcp.remote_port = candidate_answer_dest->port;
|
||||||
|
@ -1046,7 +1093,7 @@ tsk_bool_t trtp_manager_is_ready(trtp_manager_t* self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets NAT Traversal context */
|
/** Sets NAT Traversal context */
|
||||||
int trtp_manager_set_natt_ctx(trtp_manager_t* self, tnet_nat_context_handle_t* natt_ctx)
|
int trtp_manager_set_natt_ctx(trtp_manager_t* self, struct tnet_nat_ctx_s* natt_ctx)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -1196,12 +1243,12 @@ int trtp_manager_start(trtp_manager_t* self)
|
||||||
|
|
||||||
tsk_safeobj_lock(self);
|
tsk_safeobj_lock(self);
|
||||||
|
|
||||||
if(self->is_started){
|
if (self->is_started) {
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize transport with ICE context
|
// Initialize transport with ICE context
|
||||||
if(self->ice_ctx && (ret = _trtp_manager_ice_init(self)) != 0){
|
if (self->ice_ctx && (ret = _trtp_manager_ice_init(self)) != 0) {
|
||||||
TSK_DEBUG_ERROR("_trtp_manager_ice_init() failed");
|
TSK_DEBUG_ERROR("_trtp_manager_ice_init() failed");
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -1300,7 +1347,7 @@ int trtp_manager_start(trtp_manager_t* self)
|
||||||
}
|
}
|
||||||
/* create and start RTCP session */
|
/* create and start RTCP session */
|
||||||
if(!self->rtcp.session && ret == 0){
|
if(!self->rtcp.session && ret == 0){
|
||||||
self->rtcp.session = trtp_rtcp_session_create(self->rtp.ssrc.local, self->rtcp.cname);
|
self->rtcp.session = trtp_rtcp_session_create_2(self->ice_ctx, self->rtp.ssrc.local, self->rtcp.cname);
|
||||||
}
|
}
|
||||||
if(self->rtcp.session){
|
if(self->rtcp.session){
|
||||||
ret = trtp_rtcp_session_set_callback(self->rtcp.session, self->rtcp.cb.fun, self->rtcp.cb.usrdata);
|
ret = trtp_rtcp_session_set_callback(self->rtcp.session, self->rtcp.cb.fun, self->rtcp.cb.usrdata);
|
||||||
|
@ -1322,7 +1369,7 @@ int trtp_manager_start(trtp_manager_t* self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DTLS handshaking Timer */
|
/* DTLS handshaking Timer */
|
||||||
if(self->timer_mgr_global && self->srtp_state == trtp_srtp_state_activated && (self->srtp_type & tmedia_srtp_type_dtls) == tmedia_srtp_type_dtls){
|
if (self->timer_mgr_global && self->srtp_state == trtp_srtp_state_activated && (self->srtp_type & tmedia_srtp_type_dtls) == tmedia_srtp_type_dtls) {
|
||||||
ret = tsk_timer_manager_start(self->timer_mgr_global);
|
ret = tsk_timer_manager_start(self->timer_mgr_global);
|
||||||
self->dtls.timer_hanshaking.timeout = TRTP_DTLS_HANDSHAKING_TIMEOUT;
|
self->dtls.timer_hanshaking.timeout = TRTP_DTLS_HANDSHAKING_TIMEOUT;
|
||||||
// start handshaking timer
|
// start handshaking timer
|
||||||
|
@ -1333,8 +1380,8 @@ int trtp_manager_start(trtp_manager_t* self)
|
||||||
#endif /* HAVE_SRTP */
|
#endif /* HAVE_SRTP */
|
||||||
|
|
||||||
|
|
||||||
/* start the transport */
|
/* start the transport if TURN is not active (otherwise TURN data will be received directly on RTP manager with channel headers) */
|
||||||
if((ret = tnet_transport_start(self->transport))){
|
if (!self->is_ice_turn_active && (ret = tnet_transport_start(self->transport))) {
|
||||||
TSK_DEBUG_ERROR("Failed to start the RTP/RTCP transport");
|
TSK_DEBUG_ERROR("Failed to start the RTP/RTCP transport");
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -1452,9 +1499,9 @@ tsk_size_t trtp_manager_send_rtp_packet(trtp_manager_t* self, const struct trtp_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(/* number of bytes sent */(ret = tnet_sockfd_sendto(self->transport->master->fd, (const struct sockaddr *)&self->rtp.remote_addr, data_ptr, data_size)) > 0){
|
if (/* number of bytes sent */(ret = trtp_manager_send_rtp_raw(self, data_ptr, data_size)) > 0) {
|
||||||
// forward packet to the RTCP session
|
// forward packet to the RTCP session
|
||||||
if(self->rtcp.session){
|
if (self->rtcp.session) {
|
||||||
trtp_rtcp_session_process_rtp_out(self->rtcp.session, packet, data_size);
|
trtp_rtcp_session_process_rtp_out(self->rtcp.session, packet, data_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1479,9 +1526,14 @@ tsk_size_t trtp_manager_send_rtp_raw(trtp_manager_t* self, const void* data, tsk
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
tsk_safeobj_lock(self);
|
tsk_safeobj_lock(self);
|
||||||
ret = tnet_sockfd_sendto(self->transport->master->fd, (const struct sockaddr *)&self->rtp.remote_addr, data, size);
|
if (self->is_ice_turn_active) {
|
||||||
|
ret = (tnet_ice_ctx_send_turn_rtp(self->ice_ctx, data, size) == 0) ? size : 0; // returns #0 if ok
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = tnet_sockfd_sendto(self->transport->master->fd, (const struct sockaddr *)&self->rtp.remote_addr, data, size); // returns number of sent bytes
|
||||||
|
}
|
||||||
tsk_safeobj_unlock(self);
|
tsk_safeobj_unlock(self);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int trtp_manager_set_app_bandwidth_max(trtp_manager_t* self, int32_t bw_upload_kbps, int32_t bw_download_kbps)
|
int trtp_manager_set_app_bandwidth_max(trtp_manager_t* self, int32_t bw_upload_kbps, int32_t bw_download_kbps)
|
||||||
|
@ -1536,6 +1588,14 @@ int trtp_manager_stop(trtp_manager_t* self)
|
||||||
// ret = tnet_ice_ctx_stop(self->ice_ctx);
|
// ret = tnet_ice_ctx_stop(self->ice_ctx);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
// callbacks
|
||||||
|
if (self->transport) {
|
||||||
|
ret = tnet_transport_set_callback(self->transport, tsk_null, tsk_null);
|
||||||
|
}
|
||||||
|
if (self->ice_ctx) {
|
||||||
|
ret = tnet_ice_ctx_rtp_callback(self->ice_ctx, tsk_null, tsk_null);
|
||||||
|
}
|
||||||
|
|
||||||
// Stop the RTCP session first (will send BYE)
|
// Stop the RTCP session first (will send BYE)
|
||||||
if(self->rtcp.session){
|
if(self->rtcp.session){
|
||||||
ret = trtp_rtcp_session_stop(self->rtcp.session);
|
ret = trtp_rtcp_session_stop(self->rtcp.session);
|
||||||
|
@ -1562,6 +1622,7 @@ int trtp_manager_stop(trtp_manager_t* self)
|
||||||
// reset default values
|
// reset default values
|
||||||
self->is_symetric_rtp_checked = self->is_symetric_rtcp_checked = tsk_false;
|
self->is_symetric_rtp_checked = self->is_symetric_rtcp_checked = tsk_false;
|
||||||
self->is_ice_neg_ok = tsk_false;
|
self->is_ice_neg_ok = tsk_false;
|
||||||
|
self->is_ice_turn_active = tsk_false;
|
||||||
self->is_socket_disabled = tsk_false;
|
self->is_socket_disabled = tsk_false;
|
||||||
|
|
||||||
self->is_started = tsk_false;
|
self->is_started = tsk_false;
|
||||||
|
@ -1622,8 +1683,16 @@ static tsk_object_t* trtp_manager_dtor(tsk_object_t * self)
|
||||||
{
|
{
|
||||||
trtp_manager_t *manager = self;
|
trtp_manager_t *manager = self;
|
||||||
if(manager){
|
if(manager){
|
||||||
|
/* callbacks */
|
||||||
|
if (manager->ice_ctx) {
|
||||||
|
tnet_ice_ctx_rtp_callback(manager->ice_ctx, tsk_null, tsk_null);
|
||||||
|
}
|
||||||
|
if (manager->transport) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* stop */
|
/* stop */
|
||||||
if(manager->is_started){
|
if (manager->is_started) {
|
||||||
trtp_manager_stop(manager);
|
trtp_manager_stop(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1673,8 +1742,7 @@ static tsk_object_t* trtp_manager_dtor(tsk_object_t * self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ICE */
|
/* ICE */
|
||||||
if(manager->ice_ctx){
|
if (manager->ice_ctx) {
|
||||||
tnet_ice_ctx_rtp_callback(manager->ice_ctx, tsk_null, tsk_null);
|
|
||||||
TSK_OBJECT_SAFE_FREE(manager->ice_ctx);
|
TSK_OBJECT_SAFE_FREE(manager->ice_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -188,6 +188,7 @@ int tsip_dialog_getCKIK(tsip_dialog_t *self, AKA_CK_T *ck, AKA_IK_T *ik);
|
||||||
|
|
||||||
int tsip_dialog_init(tsip_dialog_t *self, tsip_dialog_type_t type, const char* call_id, tsip_ssession_t* ss, tsk_fsm_state_id curr, tsk_fsm_state_id term);
|
int tsip_dialog_init(tsip_dialog_t *self, tsip_dialog_type_t type, const char* call_id, tsip_ssession_t* ss, tsk_fsm_state_id curr, tsk_fsm_state_id term);
|
||||||
int tsip_dialog_fsm_act(tsip_dialog_t* self, tsk_fsm_action_id , const tsip_message_t* , const tsip_action_handle_t*);
|
int tsip_dialog_fsm_act(tsip_dialog_t* self, tsk_fsm_action_id , const tsip_message_t* , const tsip_action_handle_t*);
|
||||||
|
#define tsip_dialog_fsm_act_2(self, action_id) tsip_dialog_fsm_act((self), (action_id), tsk_null, tsk_null)
|
||||||
tsk_bool_t tsip_dialog_keep_action(const tsip_dialog_t* self, const tsip_response_t *response);
|
tsk_bool_t tsip_dialog_keep_action(const tsip_dialog_t* self, const tsip_response_t *response);
|
||||||
int tsip_dialog_set_connected_fd(tsip_dialog_t* self, tnet_fd_t fd);
|
int tsip_dialog_set_connected_fd(tsip_dialog_t* self, tnet_fd_t fd);
|
||||||
int tsip_dialog_set_curr_action(tsip_dialog_t* self, const tsip_action_t* action);
|
int tsip_dialog_set_curr_action(tsip_dialog_t* self, const tsip_action_t* action);
|
||||||
|
|
|
@ -117,6 +117,10 @@ typedef enum tsip_msession_param_type_e
|
||||||
mstype_set_rtcp,
|
mstype_set_rtcp,
|
||||||
mstype_set_rtcpmux,
|
mstype_set_rtcpmux,
|
||||||
mstype_set_ice,
|
mstype_set_ice,
|
||||||
|
mstype_set_ice_stun,
|
||||||
|
mstype_set_ice_turn,
|
||||||
|
mstype_set_stun_server,
|
||||||
|
mstype_set_stun_cred,
|
||||||
|
|
||||||
mstype_set_qos,
|
mstype_set_qos,
|
||||||
mstype_unset_qos,
|
mstype_unset_qos,
|
||||||
|
@ -142,6 +146,10 @@ tsip_msession_param_type_t;
|
||||||
#define TSIP_MSESSION_SET_RTCP(ENABLED_BOOL) mstype_set_rtcp, (tsk_bool_t)ENABLED_BOOL
|
#define TSIP_MSESSION_SET_RTCP(ENABLED_BOOL) mstype_set_rtcp, (tsk_bool_t)ENABLED_BOOL
|
||||||
#define TSIP_MSESSION_SET_RTCPMUX(ENABLED_BOOL) mstype_set_rtcpmux, (tsk_bool_t)ENABLED_BOOL
|
#define TSIP_MSESSION_SET_RTCPMUX(ENABLED_BOOL) mstype_set_rtcpmux, (tsk_bool_t)ENABLED_BOOL
|
||||||
#define TSIP_MSESSION_SET_ICE(ENABLED_BOOL) mstype_set_ice, (tsk_bool_t)ENABLED_BOOL
|
#define TSIP_MSESSION_SET_ICE(ENABLED_BOOL) mstype_set_ice, (tsk_bool_t)ENABLED_BOOL
|
||||||
|
#define TSIP_MSESSION_SET_ICE_STUN(ENABLED_BOOL) mstype_set_ice_stun, (tsk_bool_t)ENABLED_BOOL
|
||||||
|
#define TSIP_MSESSION_SET_ICE_TURN(ENABLED_BOOL) mstype_set_ice_turn, (tsk_bool_t)ENABLED_BOOL
|
||||||
|
#define TSIP_MSESSION_SET_STUN_SERVER(HOSTNAME, PORT) mstype_set_stun_server, (const char*)HOSTNAME, (uint16_t)PORT
|
||||||
|
#define TSIP_MSESSION_SET_STUN_CRED(USERNAME, PASSWORD) mstype_set_stun_cred, (const char*)USERNAME, (const char*)PASSWORD
|
||||||
#define TSIP_MSESSION_SET_QOS(TYPE_ENUM, STRENGTH_ENUM) mstype_set_qos, (tmedia_qos_stype_t)TYPE_ENUM, (tmedia_qos_strength_t)STRENGTH_ENUM
|
#define TSIP_MSESSION_SET_QOS(TYPE_ENUM, STRENGTH_ENUM) mstype_set_qos, (tmedia_qos_stype_t)TYPE_ENUM, (tmedia_qos_strength_t)STRENGTH_ENUM
|
||||||
#define TSIP_MSESSION_UNSET_QOS() mstype_unset_qos
|
#define TSIP_MSESSION_UNSET_QOS() mstype_unset_qos
|
||||||
#define TSIP_MSESSION_SET_TIMERS(TIMEOUT_UINT, REFRESHER_STR) mstype_set_timers, (unsigned)TIMEOUT_UINT, (const char*)REFRESHER_STR
|
#define TSIP_MSESSION_SET_TIMERS(TIMEOUT_UINT, REFRESHER_STR) mstype_set_timers, (unsigned)TIMEOUT_UINT, (const char*)REFRESHER_STR
|
||||||
|
@ -230,10 +238,19 @@ typedef struct tsip_ssession_s
|
||||||
struct{
|
struct{
|
||||||
tmedia_session_msrp_cb_f callback;
|
tmedia_session_msrp_cb_f callback;
|
||||||
} msrp;
|
} msrp;
|
||||||
|
/* STUN */
|
||||||
|
struct{
|
||||||
|
char* username;
|
||||||
|
char* password;
|
||||||
|
char* hostname;
|
||||||
|
uint16_t port;
|
||||||
|
} stun;
|
||||||
|
|
||||||
/* Features */
|
/* Features */
|
||||||
unsigned enable_100rel:1;
|
unsigned enable_100rel:1;
|
||||||
unsigned enable_ice:1;
|
unsigned enable_ice:1;
|
||||||
|
unsigned enable_icestun:1;
|
||||||
|
unsigned enable_iceturn:1;
|
||||||
unsigned enable_rtcp:1;
|
unsigned enable_rtcp:1;
|
||||||
unsigned enable_rtcpmux:1;
|
unsigned enable_rtcpmux:1;
|
||||||
} media;
|
} media;
|
||||||
|
|
|
@ -111,7 +111,6 @@ typedef enum tsip_stack_param_type_e
|
||||||
tsip_pname_header,
|
tsip_pname_header,
|
||||||
|
|
||||||
/* Nat Traversal */
|
/* Nat Traversal */
|
||||||
tsip_pname_icestun_enabled,
|
|
||||||
tsip_pname_stun_enabled,
|
tsip_pname_stun_enabled,
|
||||||
tsip_pname_stun_server,
|
tsip_pname_stun_server,
|
||||||
tsip_pname_stun_cred,
|
tsip_pname_stun_cred,
|
||||||
|
@ -523,7 +522,6 @@ int ret = tsip_stack_set(stack,
|
||||||
#define TSIP_STACK_SET_STUN_SERVER(IP_STR, PORT_UINT) tsip_pname_stun_server, (const char*)IP_STR, (unsigned)PORT_UINT
|
#define TSIP_STACK_SET_STUN_SERVER(IP_STR, PORT_UINT) tsip_pname_stun_server, (const char*)IP_STR, (unsigned)PORT_UINT
|
||||||
#define TSIP_STACK_SET_STUN_CRED(USR_STR, PASSORD_STR) tsip_pname_stun_cred, (const char*)USR_STR, (const char*)PASSORD_STR
|
#define TSIP_STACK_SET_STUN_CRED(USR_STR, PASSORD_STR) tsip_pname_stun_cred, (const char*)USR_STR, (const char*)PASSORD_STR
|
||||||
#define TSIP_STACK_SET_STUN_ENABLED(ENABLED_BOOL) tsip_pname_stun_enabled, (tsk_bool_t)ENABLED_BOOL
|
#define TSIP_STACK_SET_STUN_ENABLED(ENABLED_BOOL) tsip_pname_stun_enabled, (tsk_bool_t)ENABLED_BOOL
|
||||||
#define TSIP_STACK_SET_ICE_STUN_ENABLED(ENABLED_BOOL) tsip_pname_icestun_enabled, (tsk_bool_t)ENABLED_BOOL
|
|
||||||
|
|
||||||
/* === User Data === */
|
/* === User Data === */
|
||||||
/**@ingroup tsip_stack_group
|
/**@ingroup tsip_stack_group
|
||||||
|
@ -649,12 +647,7 @@ typedef struct tsip_stack_s
|
||||||
char* pwd;
|
char* pwd;
|
||||||
tsk_bool_t enabled;
|
tsk_bool_t enabled;
|
||||||
} stun;
|
} stun;
|
||||||
struct{
|
struct tnet_nat_ctx_s* ctx;
|
||||||
tsk_bool_t stun_enabled;
|
|
||||||
} ice;
|
|
||||||
// TURN
|
|
||||||
// ICE
|
|
||||||
tnet_nat_context_handle_t* ctx;
|
|
||||||
} natt;
|
} natt;
|
||||||
|
|
||||||
/* DHCP context */
|
/* DHCP context */
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "tinysdp/headers/tsdp_header_S.h"
|
#include "tinysdp/headers/tsdp_header_S.h"
|
||||||
#include "tinysdp/headers/tsdp_header_O.h"
|
#include "tinysdp/headers/tsdp_header_O.h"
|
||||||
|
|
||||||
|
#include "stun/tnet_stun_types.h"
|
||||||
#include "ice/tnet_ice_ctx.h"
|
#include "ice/tnet_ice_ctx.h"
|
||||||
|
|
||||||
#include "tsk_debug.h"
|
#include "tsk_debug.h"
|
||||||
|
@ -131,45 +132,46 @@ int tsip_dialog_invite_ice_timers_set(tsip_dialog_invite_t *self, int64_t timeou
|
||||||
static int tsip_dialog_invite_ice_create_ctx(tsip_dialog_invite_t * self, tmedia_type_t media_type)
|
static int tsip_dialog_invite_ice_create_ctx(tsip_dialog_invite_t * self, tmedia_type_t media_type)
|
||||||
{
|
{
|
||||||
int32_t transport_idx;
|
int32_t transport_idx;
|
||||||
|
int ret = 0;
|
||||||
if(!self){
|
if(!self){
|
||||||
TSK_DEBUG_ERROR("Invalid parameter");
|
TSK_DEBUG_ERROR("Invalid parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
transport_idx = TSIP_DIALOG_GET_STACK(self)->network.transport_idx_default;
|
transport_idx = TSIP_DIALOG_GET_STACK(self)->network.transport_idx_default;
|
||||||
if(!self->ice.ctx_audio && (media_type & tmedia_audio)){
|
if (!self->ice.ctx_audio && (media_type & tmedia_audio)) {
|
||||||
self->ice.ctx_audio = tnet_ice_ctx_create(self->ice.is_jingle, TNET_SOCKET_TYPE_IS_IPV6(TSIP_DIALOG_GET_STACK(self)->network.proxy_cscf_type[transport_idx]),
|
self->ice.ctx_audio = tnet_ice_ctx_create(self->ice.is_jingle, TNET_SOCKET_TYPE_IS_IPV6(TSIP_DIALOG_GET_STACK(self)->network.proxy_cscf_type[transport_idx]),
|
||||||
self->use_rtcp, tsk_false, tsip_dialog_invite_ice_audio_callback, self);
|
self->use_rtcp, tsk_false, tsip_dialog_invite_ice_audio_callback, self);
|
||||||
if(!self->ice.ctx_audio){
|
if (!self->ice.ctx_audio) {
|
||||||
TSK_DEBUG_ERROR("Failed to create ICE audio context");
|
TSK_DEBUG_ERROR("Failed to create ICE audio context");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
if(TSIP_DIALOG_GET_STACK(self)->natt.ice.stun_enabled){
|
ret = tnet_ice_ctx_set_stun(self->ice.ctx_audio, TSIP_DIALOG_GET_SS(self)->media.stun.hostname, TSIP_DIALOG_GET_SS(self)->media.stun.port, kStunSoftware, TSIP_DIALOG_GET_STACK(self)->natt.stun.login, TSIP_DIALOG_GET_SS(self)->media.stun.password);
|
||||||
tnet_ice_ctx_set_stun(self->ice.ctx_audio, TSIP_DIALOG_GET_STACK(self)->natt.stun.ip, TSIP_DIALOG_GET_STACK(self)->natt.stun.port, "Doubango", TSIP_DIALOG_GET_STACK(self)->natt.stun.login, TSIP_DIALOG_GET_STACK(self)->natt.stun.pwd);
|
ret = tnet_ice_ctx_set_stun_enabled(self->ice.ctx_audio, TSIP_DIALOG_GET_SS(self)->media.enable_icestun);
|
||||||
|
ret = tnet_ice_ctx_set_turn_enabled(self->ice.ctx_audio, TSIP_DIALOG_GET_SS(self)->media.enable_iceturn);
|
||||||
|
ret = tnet_ice_ctx_set_rtcpmux(self->ice.ctx_audio, self->use_rtcpmux);
|
||||||
}
|
}
|
||||||
tnet_ice_ctx_set_rtcpmux(self->ice.ctx_audio, self->use_rtcpmux);
|
if (!self->ice.ctx_video && (media_type & tmedia_video)) {
|
||||||
}
|
|
||||||
if(!self->ice.ctx_video && (media_type & tmedia_video)){
|
|
||||||
self->ice.ctx_video = tnet_ice_ctx_create(self->ice.is_jingle, TNET_SOCKET_TYPE_IS_IPV6(TSIP_DIALOG_GET_STACK(self)->network.proxy_cscf_type[transport_idx]),
|
self->ice.ctx_video = tnet_ice_ctx_create(self->ice.is_jingle, TNET_SOCKET_TYPE_IS_IPV6(TSIP_DIALOG_GET_STACK(self)->network.proxy_cscf_type[transport_idx]),
|
||||||
self->use_rtcp, tsk_true, tsip_dialog_invite_ice_video_callback, self);
|
self->use_rtcp, tsk_true, tsip_dialog_invite_ice_video_callback, self);
|
||||||
if(!self->ice.ctx_video){
|
if (!self->ice.ctx_video) {
|
||||||
TSK_DEBUG_ERROR("Failed to create ICE video context");
|
TSK_DEBUG_ERROR("Failed to create ICE video context");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
if(TSIP_DIALOG_GET_STACK(self)->natt.ice.stun_enabled){
|
ret = tnet_ice_ctx_set_stun(self->ice.ctx_video, TSIP_DIALOG_GET_SS(self)->media.stun.hostname, TSIP_DIALOG_GET_SS(self)->media.stun.port, kStunSoftware, TSIP_DIALOG_GET_STACK(self)->natt.stun.login, TSIP_DIALOG_GET_SS(self)->media.stun.password);
|
||||||
tnet_ice_ctx_set_stun(self->ice.ctx_video, TSIP_DIALOG_GET_STACK(self)->natt.stun.ip, TSIP_DIALOG_GET_STACK(self)->natt.stun.port, "Doubango", TSIP_DIALOG_GET_STACK(self)->natt.stun.login, TSIP_DIALOG_GET_STACK(self)->natt.stun.pwd);
|
ret = tnet_ice_ctx_set_stun_enabled(self->ice.ctx_video, TSIP_DIALOG_GET_SS(self)->media.enable_icestun);
|
||||||
}
|
ret = tnet_ice_ctx_set_turn_enabled(self->ice.ctx_video, TSIP_DIALOG_GET_SS(self)->media.enable_iceturn);
|
||||||
tnet_ice_ctx_set_rtcpmux(self->ice.ctx_video, self->use_rtcpmux);
|
ret = tnet_ice_ctx_set_rtcpmux(self->ice.ctx_video, self->use_rtcpmux);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set media type
|
// set media type
|
||||||
tsip_dialog_invite_ice_set_media_type(self, media_type);
|
ret = tsip_dialog_invite_ice_set_media_type(self, media_type);
|
||||||
|
|
||||||
// update session manager with the right ICE contexts
|
// update session manager with the right ICE contexts
|
||||||
if(self->msession_mgr){
|
if (self->msession_mgr) {
|
||||||
tmedia_session_mgr_set_ice_ctx(self->msession_mgr, self->ice.ctx_audio, self->ice.ctx_video);
|
ret = tmedia_session_mgr_set_ice_ctx(self->msession_mgr, self->ice.ctx_audio, self->ice.ctx_video);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tsip_dialog_invite_ice_set_media_type(tsip_dialog_invite_t * self, tmedia_type_t _media_type)
|
int tsip_dialog_invite_ice_set_media_type(tsip_dialog_invite_t * self, tmedia_type_t _media_type)
|
||||||
|
@ -548,7 +550,7 @@ static int tsip_dialog_invite_ice_callback(const tnet_ice_event_t *e)
|
||||||
{
|
{
|
||||||
if(dialog->ice.last_action_id != tsk_fsm_state_none){
|
if(dialog->ice.last_action_id != tsk_fsm_state_none){
|
||||||
if(tsip_dialog_invite_ice_got_local_candidates(dialog)){
|
if(tsip_dialog_invite_ice_got_local_candidates(dialog)){
|
||||||
tsip_dialog_fsm_act(TSIP_DIALOG(dialog), dialog->ice.last_action_id, dialog->ice.last_message, dialog->ice.last_action);
|
ret = tsip_dialog_fsm_act(TSIP_DIALOG(dialog), dialog->ice.last_action_id, dialog->ice.last_message, dialog->ice.last_action);
|
||||||
dialog->ice.last_action_id = tsk_fsm_state_none;
|
dialog->ice.last_action_id = tsk_fsm_state_none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,13 +562,20 @@ static int tsip_dialog_invite_ice_callback(const tnet_ice_event_t *e)
|
||||||
// fatal errors which discard ICE process
|
// fatal errors which discard ICE process
|
||||||
case tnet_ice_event_type_gathering_host_candidates_failed:
|
case tnet_ice_event_type_gathering_host_candidates_failed:
|
||||||
case tnet_ice_event_type_gathering_reflexive_candidates_failed:
|
case tnet_ice_event_type_gathering_reflexive_candidates_failed:
|
||||||
|
case tnet_ice_event_type_gathering_relay_candidates_failed:
|
||||||
{
|
{
|
||||||
if(dialog->ice.last_action_id != tsk_fsm_state_none){
|
if (dialog->ice.last_action_id != tsk_fsm_state_none) {
|
||||||
tsip_dialog_fsm_act(TSIP_DIALOG(dialog), dialog->ice.last_action_id, dialog->ice.last_message, dialog->ice.last_action);
|
ret = tsip_dialog_fsm_act(TSIP_DIALOG(dialog), dialog->ice.last_action_id, dialog->ice.last_message, dialog->ice.last_action);
|
||||||
dialog->ice.last_action_id = tsk_fsm_state_none;
|
dialog->ice.last_action_id = tsk_fsm_state_none;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// TURN session disconnected while we're in call
|
||||||
|
case tnet_ice_event_type_turn_connection_broken:
|
||||||
|
{
|
||||||
|
ret = tsip_dialog_fsm_act_2(TSIP_DIALOG(dialog), _fsm_action_oBYE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -439,12 +439,6 @@ static int __tsip_stack_set(tsip_stack_t *self, va_list* app)
|
||||||
self->natt.stun.enabled = va_arg(*app, tsk_bool_t);
|
self->natt.stun.enabled = va_arg(*app, tsk_bool_t);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tsip_pname_icestun_enabled:
|
|
||||||
{ /* (tsk_bool_t)ENABLED_BOOL */
|
|
||||||
self->natt.ice.stun_enabled = va_arg(*app, tsk_bool_t);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* === User Data === */
|
/* === User Data === */
|
||||||
case tsip_pname_userdata:
|
case tsip_pname_userdata:
|
||||||
{ /* (const void*)DATA_PTR */
|
{ /* (const void*)DATA_PTR */
|
||||||
|
@ -558,12 +552,13 @@ tsip_stack_handle_t* tsip_stack_create(tsip_stack_callback_f callback, const cha
|
||||||
const char *server_ip, *usr_name, *usr_pwd;
|
const char *server_ip, *usr_name, *usr_pwd;
|
||||||
uint16_t server_port;
|
uint16_t server_port;
|
||||||
stack->natt.stun.enabled = tmedia_defaults_get_stun_enabled();
|
stack->natt.stun.enabled = tmedia_defaults_get_stun_enabled();
|
||||||
stack->natt.ice.stun_enabled = tmedia_defaults_get_icestun_enabled();
|
if(tmedia_defaults_get_stun_server(&server_ip, &server_port) == 0){
|
||||||
if(tmedia_defaults_get_stun_server(&server_ip, &server_port, &usr_name, &usr_pwd) == 0){
|
|
||||||
tsk_strupdate(&stack->natt.stun.ip, server_ip);
|
tsk_strupdate(&stack->natt.stun.ip, server_ip);
|
||||||
|
stack->natt.stun.port = server_port;
|
||||||
|
}
|
||||||
|
if(tmedia_defaults_get_stun_cred(&usr_name, &usr_pwd) == 0){
|
||||||
tsk_strupdate(&stack->natt.stun.login, usr_name);
|
tsk_strupdate(&stack->natt.stun.login, usr_name);
|
||||||
tsk_strupdate(&stack->natt.stun.pwd, usr_pwd);
|
tsk_strupdate(&stack->natt.stun.pwd, usr_pwd);
|
||||||
stack->natt.stun.port = server_port;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -754,7 +749,7 @@ int tsip_stack_start(tsip_stack_handle_t *self)
|
||||||
if(stack->natt.stun.enabled && !tsk_strnullORempty(stack->natt.stun.ip)){
|
if(stack->natt.stun.enabled && !tsk_strnullORempty(stack->natt.stun.ip)){
|
||||||
if(stack->natt.stun.port == 0){
|
if(stack->natt.stun.port == 0){
|
||||||
/* FIXME: for now only UDP(IPv4/IPv6) is supported */
|
/* FIXME: for now only UDP(IPv4/IPv6) is supported */
|
||||||
stack->natt.stun.port = TNET_STUN_TCP_UDP_DEFAULT_PORT;
|
stack->natt.stun.port = kStunPortDefaultTcpUdp;
|
||||||
}
|
}
|
||||||
TSK_DEBUG_INFO("STUN server = %s:%u", stack->natt.stun.ip, stack->natt.stun.port);
|
TSK_DEBUG_INFO("STUN server = %s:%u", stack->natt.stun.ip, stack->natt.stun.port);
|
||||||
stack->natt.ctx = tnet_nat_context_create(TNET_SOCKET_TYPE_IS_IPV6(tx_values[stack->network.transport_idx_default])? tnet_socket_type_udp_ipv6: tnet_socket_type_udp_ipv4,
|
stack->natt.ctx = tnet_nat_context_create(TNET_SOCKET_TYPE_IS_IPV6(tx_values[stack->network.transport_idx_default])? tnet_socket_type_udp_ipv6: tnet_socket_type_udp_ipv4,
|
||||||
|
|
|
@ -288,6 +288,8 @@ int __tsip_ssession_set(tsip_ssession_t *self, va_list *app)
|
||||||
break;
|
break;
|
||||||
case mstype_set_100rel: self->media.enable_100rel = va_arg(*app, tsk_bool_t); break;
|
case mstype_set_100rel: self->media.enable_100rel = va_arg(*app, tsk_bool_t); break;
|
||||||
case mstype_set_ice: self->media.enable_ice = va_arg(*app, tsk_bool_t); break;
|
case mstype_set_ice: self->media.enable_ice = va_arg(*app, tsk_bool_t); break;
|
||||||
|
case mstype_set_ice_stun: self->media.enable_icestun = va_arg(*app, tsk_bool_t); break;
|
||||||
|
case mstype_set_ice_turn: self->media.enable_iceturn = va_arg(*app, tsk_bool_t); break;
|
||||||
case mstype_set_rtcp: self->media.enable_rtcp = va_arg(*app, tsk_bool_t); break;
|
case mstype_set_rtcp: self->media.enable_rtcp = va_arg(*app, tsk_bool_t); break;
|
||||||
case mstype_set_rtcpmux: self->media.enable_rtcpmux = va_arg(*app, tsk_bool_t); break;
|
case mstype_set_rtcpmux: self->media.enable_rtcpmux = va_arg(*app, tsk_bool_t); break;
|
||||||
case mstype_set_qos:
|
case mstype_set_qos:
|
||||||
|
@ -350,6 +352,22 @@ int __tsip_ssession_set(tsip_ssession_t *self, va_list *app)
|
||||||
self->media.msrp.callback = va_arg(*app, tmedia_session_msrp_cb_f);
|
self->media.msrp.callback = va_arg(*app, tmedia_session_msrp_cb_f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case mstype_set_stun_server:
|
||||||
|
{ /* (const char*)HOSTNAME, (uint16_t)PORT */
|
||||||
|
const char* HOSTNAME = va_arg(*app, const char*);
|
||||||
|
uint16_t PORT = tsk_va_arg_u16(*app);
|
||||||
|
tsk_strupdate(&self->media.stun.hostname, HOSTNAME);
|
||||||
|
self->media.stun.port = PORT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case mstype_set_stun_cred:
|
||||||
|
{ /* (const char*)USERNAME, (const char*)PASSWORD */
|
||||||
|
const char* USERNAME = va_arg(*app, const char*);
|
||||||
|
const char* PASSWORD = va_arg(*app, const char*);
|
||||||
|
tsk_strupdate(&self->media.stun.username, USERNAME);
|
||||||
|
tsk_strupdate(&self->media.stun.password, PASSWORD);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:{
|
default:{
|
||||||
/* va_list will be unsafe => exit */
|
/* va_list will be unsafe => exit */
|
||||||
TSK_DEBUG_ERROR("%d NOT a valid MEDIA pname", mscurr);
|
TSK_DEBUG_ERROR("%d NOT a valid MEDIA pname", mscurr);
|
||||||
|
@ -644,7 +662,7 @@ static tsk_object_t* tsip_ssession_ctor(tsk_object_t * self, va_list * app)
|
||||||
// default parentid: not parent -> no pending transfer
|
// default parentid: not parent -> no pending transfer
|
||||||
ss->id_parent = TSIP_SSESSION_INVALID_ID;
|
ss->id_parent = TSIP_SSESSION_INVALID_ID;
|
||||||
// default SigComp compId (will be updated by session_set())
|
// default SigComp compId (will be updated by session_set())
|
||||||
if(ss->stack->sigcomp.handle){
|
if (ss->stack->sigcomp.handle) {
|
||||||
ss->sigcomp_id = tsk_strdup(tsip_sigcomp_handler_fixme_getcompid(ss->stack->sigcomp.handle));
|
ss->sigcomp_id = tsk_strdup(tsip_sigcomp_handler_fixme_getcompid(ss->stack->sigcomp.handle));
|
||||||
}
|
}
|
||||||
// default media values
|
// default media values
|
||||||
|
@ -653,6 +671,8 @@ static tsk_object_t* tsip_ssession_ctor(tsk_object_t * self, va_list * app)
|
||||||
ss->media.avpf_mode = tmedia_defaults_get_avpf_mode();
|
ss->media.avpf_mode = tmedia_defaults_get_avpf_mode();
|
||||||
ss->media.enable_100rel = tmedia_defaults_get_100rel_enabled();
|
ss->media.enable_100rel = tmedia_defaults_get_100rel_enabled();
|
||||||
ss->media.enable_ice = tmedia_defaults_get_ice_enabled();
|
ss->media.enable_ice = tmedia_defaults_get_ice_enabled();
|
||||||
|
ss->media.enable_icestun = tmedia_defaults_get_icestun_enabled();
|
||||||
|
ss->media.enable_iceturn = tmedia_defaults_get_iceturn_enabled();
|
||||||
ss->media.enable_rtcp = tmedia_defaults_get_rtcp_enabled();
|
ss->media.enable_rtcp = tmedia_defaults_get_rtcp_enabled();
|
||||||
ss->media.enable_rtcpmux = tmedia_defaults_get_rtcpmux_enabled();
|
ss->media.enable_rtcpmux = tmedia_defaults_get_rtcpmux_enabled();
|
||||||
ss->media.type = tmedia_none;
|
ss->media.type = tmedia_none;
|
||||||
|
@ -663,6 +683,18 @@ static tsk_object_t* tsip_ssession_ctor(tsk_object_t * self, va_list * app)
|
||||||
ss->media.codecs = tmedia_codec_id_all;
|
ss->media.codecs = tmedia_codec_id_all;
|
||||||
ss->media.bypass_encoding = tmedia_defaults_get_bypass_encoding();
|
ss->media.bypass_encoding = tmedia_defaults_get_bypass_encoding();
|
||||||
ss->media.bypass_decoding = tmedia_defaults_get_bypass_decoding();
|
ss->media.bypass_decoding = tmedia_defaults_get_bypass_decoding();
|
||||||
|
{
|
||||||
|
const char *stun_hostname, *stun_username, *stun_password;
|
||||||
|
uint16_t stun_port;
|
||||||
|
if(tmedia_defaults_get_stun_server(&stun_hostname, &stun_port) == 0){
|
||||||
|
ss->media.stun.hostname = tsk_strdup(stun_hostname);
|
||||||
|
ss->media.stun.port = stun_port;
|
||||||
|
}
|
||||||
|
if(tmedia_defaults_get_stun_cred(&stun_username, &stun_password) == 0){
|
||||||
|
ss->media.stun.username = tsk_strdup(stun_username);
|
||||||
|
ss->media.stun.password = tsk_strdup(stun_password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* add the session to the stack */
|
/* add the session to the stack */
|
||||||
if(ss->stack){
|
if(ss->stack){
|
||||||
|
@ -699,6 +731,9 @@ static tsk_object_t* tsip_ssession_dtor(tsk_object_t * self)
|
||||||
// Media
|
// Media
|
||||||
//=======
|
//=======
|
||||||
TSK_FREE(ss->media.timers.refresher);
|
TSK_FREE(ss->media.timers.refresher);
|
||||||
|
TSK_FREE(ss->media.stun.username);
|
||||||
|
TSK_FREE(ss->media.stun.password);
|
||||||
|
TSK_FREE(ss->media.stun.hostname);
|
||||||
|
|
||||||
//=======
|
//=======
|
||||||
// WebSocket
|
// WebSocket
|
||||||
|
|
Loading…
Reference in New Issue