diff --git a/media/mtransport/nricectx.cpp b/media/mtransport/nricectx.cpp index 43324c2be8c0..5b1d6b1f5d82 100644 --- a/media/mtransport/nricectx.cpp +++ b/media/mtransport/nricectx.cpp @@ -345,6 +345,9 @@ NrIceCtx::CreateStream(const std::string& name, int components) { return stream; } +void NrIceCtx::destroy_peer_ctx() { + nr_ice_peer_ctx_destroy(&peer_); +} nsresult NrIceCtx::StartGathering() { this->AddRef(); @@ -486,6 +489,7 @@ void NrIceCtx::SetState(State state) { } // close namespace + extern "C" { int nr_bin2hex(UCHAR *in,int len,UCHAR *out); } diff --git a/media/mtransport/nricectx.h b/media/mtransport/nricectx.h index 2bcd5ffe6754..479dc40b551b 100644 --- a/media/mtransport/nricectx.h +++ b/media/mtransport/nricectx.h @@ -92,6 +92,9 @@ class NrIceCtx { nr_ice_ctx *ctx() { return ctx_; } nr_ice_peer_ctx *peer() { return peer_; } + // Testing only. + void destroy_peer_ctx(); + // Create a media stream RefPtr CreateStream(const std::string& name, int components); diff --git a/media/mtransport/test/ice_unittest.cpp b/media/mtransport/test/ice_unittest.cpp index e024b655ffff..9116ba3f794c 100644 --- a/media/mtransport/test/ice_unittest.cpp +++ b/media/mtransport/test/ice_unittest.cpp @@ -97,7 +97,7 @@ class IceTestPeer : public sigslot::has_slots<> { size_t sent() { return sent_; } // Start connecting to another peer - void Connect(IceTestPeer *remote, TrickleMode trickle_mode) { + void Connect(IceTestPeer *remote, TrickleMode trickle_mode, bool start = true) { nsresult res; test_utils->sts_target()->Dispatch( @@ -128,11 +128,13 @@ class IceTestPeer : public sigslot::has_slots<> { } } - // Now start checks - test_utils->sts_target()->Dispatch( + if (start) { + // Now start checks + test_utils->sts_target()->Dispatch( WrapRunnableRet(ice_ctx_, &NrIceCtx::StartChecks, &res), NS_DISPATCH_SYNC); - ASSERT_TRUE(NS_SUCCEEDED(res)); + ASSERT_TRUE(NS_SUCCEEDED(res)); + } if (trickle_mode == TRICKLE_DEFERRED) { // If we are in trickle deferred mode, now trickle in the candidates @@ -153,6 +155,20 @@ class IceTestPeer : public sigslot::has_slots<> { } } + void Close() { + ice_ctx_->destroy_peer_ctx(); + } + + void StartChecks() { + nsresult res; + + // Now start checks + test_utils->sts_target()->Dispatch( + WrapRunnableRet(ice_ctx_, &NrIceCtx::StartChecks, &res), + NS_DISPATCH_SYNC); + ASSERT_TRUE(NS_SUCCEEDED(res)); + } + // Handle events void GatheringComplete(NrIceCtx *ctx) { gathering_complete_ = true; @@ -246,6 +262,22 @@ class IceTest : public ::testing::Test { ASSERT_TRUE_WAIT(p1_->ice_complete() && p2_->ice_complete(), 5000); } + void CloseP1() { + p1_->Close(); + } + + void ConnectThenDelete() { + p1_->Connect(p2_, TRICKLE_NONE, true); + p2_->Connect(p1_, TRICKLE_NONE, false); + test_utils->sts_target()->Dispatch(WrapRunnable(this, + &IceTest::CloseP1), + NS_DISPATCH_SYNC); + p2_->StartChecks(); + + // Wait to see if we crash + PR_Sleep(PR_MillisecondsToInterval(5000)); + } + void SendReceive() { // p1_->Send(2); p1_->SendPacket(0, 1, reinterpret_cast("TEST"), 4); @@ -301,6 +333,12 @@ TEST_F(IceTest, TestSendReceive) { SendReceive(); } +TEST_F(IceTest, TestConnectShutdownOneSide) { + AddStream("first", 1); + ASSERT_TRUE(Gather(true)); + ConnectThenDelete(); +} + int main(int argc, char **argv) { diff --git a/media/mtransport/test/nrappkit_unittest.cpp b/media/mtransport/test/nrappkit_unittest.cpp index 77ddb39f35a3..55f459a001b7 100644 --- a/media/mtransport/test/nrappkit_unittest.cpp +++ b/media/mtransport/test/nrappkit_unittest.cpp @@ -62,6 +62,23 @@ class TimerTest : public ::testing::Test { return NR_async_timer_cancel(handle_); } + int Schedule() { + int ret; + + test_utils->sts_target()->Dispatch( + WrapRunnableRet(this, &TimerTest::Schedule_w, &ret), + NS_DISPATCH_SYNC); + + return ret; + } + + int Schedule_w() { + NR_ASYNC_SCHEDULE(cb, this); + + return 0; + } + + static void cb(NR_SOCKET r, int how, void *arg) { std::cerr << "Timer fired " << std::endl; @@ -88,6 +105,11 @@ TEST_F(TimerTest, CancelTimer) { ASSERT_FALSE(fired_); } +TEST_F(TimerTest, ScheduleTest) { + Schedule(); + ASSERT_TRUE_WAIT(fired_, 1000); +} + int main(int argc, char **argv) { test_utils = new MtransportTestUtils(); diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_component.c b/media/mtransport/third_party/nICEr/src/ice/ice_component.c index fc6ada391e80..075bd5073c59 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_component.c +++ b/media/mtransport/third_party/nICEr/src/ice/ice_component.c @@ -80,6 +80,15 @@ int nr_ice_component_destroy(nr_ice_component **componentp) component=*componentp; *componentp=0; + /* Detach ourselves from the sockets */ + if (component->local_component){ + nr_ice_socket *isock=STAILQ_FIRST(&component->local_component->sockets); + while(isock){ + nr_stun_server_remove_client(isock->stun_server, component); + isock=STAILQ_NEXT(isock, entry); + } + } + STAILQ_FOREACH_SAFE(s1, &component->sockets, entry, s2){ STAILQ_REMOVE(&component->sockets,s1,nr_ice_socket_,entry); nr_ice_socket_destroy(&s1); diff --git a/media/mtransport/third_party/nICEr/src/stun/stun_server_ctx.c b/media/mtransport/third_party/nICEr/src/stun/stun_server_ctx.c index a9c6a48da5a9..81904b767879 100644 --- a/media/mtransport/third_party/nICEr/src/stun/stun_server_ctx.c +++ b/media/mtransport/third_party/nICEr/src/stun/stun_server_ctx.c @@ -121,6 +121,25 @@ int nr_stun_server_add_client(nr_stun_server_ctx *ctx, char *client_label, char return(_status); } +int nr_stun_server_remove_client(nr_stun_server_ctx *ctx, void *cb_arg) + { + nr_stun_server_client *clnt1,*clnt2; + int found = 0; + + STAILQ_FOREACH_SAFE(clnt1, &ctx->clients, entry, clnt2) { + if(clnt1->cb_arg == cb_arg) { + STAILQ_REMOVE(&ctx->clients, clnt1, nr_stun_server_client_, entry); + nr_stun_server_destroy_client(clnt1); + found++; + } + } + + if (!found) + ERETURN(R_NOT_FOUND); + + return 0; + } + static int nr_stun_server_get_password(void *arg, nr_stun_message *msg, Data **password) { int _status; diff --git a/media/mtransport/third_party/nICEr/src/stun/stun_server_ctx.h b/media/mtransport/third_party/nICEr/src/stun/stun_server_ctx.h index ec3882eb928f..abb59376b528 100644 --- a/media/mtransport/third_party/nICEr/src/stun/stun_server_ctx.h +++ b/media/mtransport/third_party/nICEr/src/stun/stun_server_ctx.h @@ -70,6 +70,7 @@ struct nr_stun_server_ctx_ { int nr_stun_server_ctx_create(char *label, nr_socket *sock, nr_stun_server_ctx **ctxp); int nr_stun_server_ctx_destroy(nr_stun_server_ctx **ctxp); int nr_stun_server_add_client(nr_stun_server_ctx *ctx, char *client_label, char *user, Data *pass, int (*stun_server_cb)(void *cb_arg, nr_stun_server_ctx *ctx,nr_socket *sock,nr_stun_server_request *req, int *error), void *cb_arg); +int nr_stun_server_remove_client(nr_stun_server_ctx *ctx, void *cb_arg); int nr_stun_server_process_request(nr_stun_server_ctx *ctx, nr_socket *sock, char *msg, int len, nr_transport_addr *peer_addr, int auth_rule); int nr_stun_get_message_client(nr_stun_server_ctx *ctx, nr_stun_message *req, nr_stun_server_client **clnt);