michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=2 et sw=2 tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: michael@0: // Original author: ekr@rtfm.com michael@0: michael@0: // Some of this code is cut-and-pasted from nICEr. Copyright is: michael@0: michael@0: /* michael@0: Copyright (c) 2007, Adobe Systems, Incorporated michael@0: All rights reserved. michael@0: michael@0: Redistribution and use in source and binary forms, with or without michael@0: modification, are permitted provided that the following conditions are michael@0: met: michael@0: michael@0: * Redistributions of source code must retain the above copyright michael@0: notice, this list of conditions and the following disclaimer. michael@0: michael@0: * Redistributions in binary form must reproduce the above copyright michael@0: notice, this list of conditions and the following disclaimer in the michael@0: documentation and/or other materials provided with the distribution. michael@0: michael@0: * Neither the name of Adobe Systems, Network Resonance nor the names of its michael@0: contributors may be used to endorse or promote products derived from michael@0: this software without specific prior written permission. michael@0: michael@0: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR michael@0: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT michael@0: OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@0: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@0: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, michael@0: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY michael@0: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE michael@0: OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: */ michael@0: michael@0: #include "nspr.h" michael@0: #include "prnetdb.h" michael@0: michael@0: #include "mozilla/Assertions.h" michael@0: michael@0: extern "C" { michael@0: #include "nr_api.h" michael@0: #include "async_timer.h" michael@0: #include "nr_resolver.h" michael@0: #include "transport_addr.h" michael@0: } michael@0: michael@0: #include "nriceresolverfake.h" michael@0: #include "nr_socket_prsock.h" michael@0: michael@0: namespace mozilla { michael@0: michael@0: NrIceResolverFake::NrIceResolverFake() : michael@0: vtbl_(new nr_resolver_vtbl), addrs_(), delay_ms_(100), michael@0: allocated_resolvers_(0) { michael@0: vtbl_->destroy = &NrIceResolverFake::destroy; michael@0: vtbl_->resolve = &NrIceResolverFake::resolve; michael@0: vtbl_->cancel = &NrIceResolverFake::cancel; michael@0: } michael@0: michael@0: NrIceResolverFake::~NrIceResolverFake() { michael@0: MOZ_ASSERT(allocated_resolvers_ == 0); michael@0: delete vtbl_; michael@0: } michael@0: michael@0: michael@0: nr_resolver *NrIceResolverFake::AllocateResolver() { michael@0: nr_resolver *resolver; michael@0: michael@0: int r = nr_resolver_create_int((void *)this, michael@0: vtbl_, &resolver); michael@0: MOZ_ASSERT(!r); michael@0: if(r) michael@0: return nullptr; michael@0: michael@0: ++allocated_resolvers_; michael@0: michael@0: return resolver; michael@0: } michael@0: michael@0: void NrIceResolverFake::DestroyResolver() { michael@0: --allocated_resolvers_; michael@0: } michael@0: michael@0: int NrIceResolverFake::destroy(void **objp) { michael@0: if (!objp || !*objp) michael@0: return 0; michael@0: michael@0: NrIceResolverFake *fake = static_cast(*objp); michael@0: *objp = 0; michael@0: michael@0: fake->DestroyResolver(); michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: int NrIceResolverFake::resolve(void *obj, michael@0: nr_resolver_resource *resource, michael@0: int (*cb)(void *cb_arg, michael@0: nr_transport_addr *addr), michael@0: void *cb_arg, michael@0: void **handle) { michael@0: int r,_status; michael@0: michael@0: MOZ_ASSERT(obj); michael@0: NrIceResolverFake *fake = static_cast(obj); michael@0: michael@0: MOZ_ASSERT(fake->allocated_resolvers_ > 0); michael@0: michael@0: PendingResolution *pending = michael@0: new PendingResolution(fake, michael@0: resource->domain_name, michael@0: resource->port ? resource->port : 3478, michael@0: resource->transport_protocol ? michael@0: resource->transport_protocol : michael@0: IPPROTO_UDP, michael@0: cb, cb_arg); michael@0: michael@0: if ((r=NR_ASYNC_TIMER_SET(fake->delay_ms_,NrIceResolverFake::resolve_cb, michael@0: (void *)pending, &pending->timer_handle_))) { michael@0: delete pending; michael@0: ABORT(r); michael@0: } michael@0: *handle = pending; michael@0: michael@0: _status=0; michael@0: abort: michael@0: return(_status); michael@0: } michael@0: michael@0: void NrIceResolverFake::resolve_cb(NR_SOCKET s, int how, void *cb_arg) { michael@0: MOZ_ASSERT(cb_arg); michael@0: PendingResolution *pending = static_cast(cb_arg); michael@0: michael@0: const PRNetAddr *addr=pending->resolver_->Resolve(pending->hostname_); michael@0: michael@0: if (addr) { michael@0: nr_transport_addr transport_addr; michael@0: michael@0: int r = nr_praddr_to_transport_addr(addr, &transport_addr, michael@0: pending->transport_, 0); michael@0: MOZ_ASSERT(!r); michael@0: if (r) michael@0: goto abort; michael@0: michael@0: r=nr_transport_addr_set_port(&transport_addr, pending->port_); michael@0: MOZ_ASSERT(!r); michael@0: if (r) michael@0: goto abort; michael@0: michael@0: /* Fill in the address string */ michael@0: r=nr_transport_addr_fmt_addr_string(&transport_addr); michael@0: MOZ_ASSERT(!r); michael@0: if (r) michael@0: goto abort; michael@0: michael@0: pending->cb_(pending->cb_arg_, &transport_addr); michael@0: delete pending; michael@0: return; michael@0: } michael@0: michael@0: abort: michael@0: // Resolution failed. michael@0: pending->cb_(pending->cb_arg_, nullptr); michael@0: michael@0: delete pending; michael@0: } michael@0: michael@0: int NrIceResolverFake::cancel(void *obj, void *handle) { michael@0: MOZ_ASSERT(obj); michael@0: MOZ_ASSERT(static_cast(obj)->allocated_resolvers_ > 0); michael@0: michael@0: PendingResolution *pending = static_cast(handle); michael@0: michael@0: NR_async_timer_cancel(pending->timer_handle_); michael@0: delete pending; michael@0: michael@0: return(0); michael@0: } michael@0: michael@0: michael@0: } // End of namespace mozilla