mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out 2 changesets (bug 949703) for mochitest-e10s-3 orange
Backed out changeset 6f5a7adab265 (bug 949703) Backed out changeset 7933aeabf6bd (bug 949703)
This commit is contained in:
parent
fb79739dd4
commit
03358bb7b2
@ -1,4 +1,4 @@
|
||||
/* -*- mode: c++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
@ -60,7 +60,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "runnable_utils.h"
|
||||
|
||||
// nICEr includes
|
||||
extern "C" {
|
||||
@ -75,7 +74,6 @@ extern "C" {
|
||||
#include "nr_crypto.h"
|
||||
#include "nr_socket.h"
|
||||
#include "nr_socket_local.h"
|
||||
#include "nr_proxy_tunnel.h"
|
||||
#include "stun_client_ctx.h"
|
||||
#include "stun_reg.h"
|
||||
#include "stun_server_ctx.h"
|
||||
@ -200,6 +198,9 @@ static nr_ice_crypto_vtbl nr_ice_crypto_nss_vtbl = {
|
||||
nr_crypto_nss_md5
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
nsresult NrIceStunServer::ToNicerStunStruct(nr_ice_stun_server *server,
|
||||
const std::string &transport) const {
|
||||
int r;
|
||||
@ -626,48 +627,7 @@ nsresult NrIceCtx::SetResolver(nr_resolver *resolver) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NrIceCtx::SetProxyServer(const NrIceProxyServer& proxy_server) {
|
||||
int r,_status;
|
||||
nr_proxy_tunnel_config *config = nullptr;
|
||||
nr_socket_wrapper_factory *wrapper = nullptr;
|
||||
|
||||
if ((r = nr_proxy_tunnel_config_create(&config))) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
if ((r = nr_proxy_tunnel_config_set_proxy(config,
|
||||
proxy_server.host().c_str(),
|
||||
proxy_server.port()))) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
if ((r = nr_proxy_tunnel_config_set_resolver(config, ctx_->resolver))) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
if ((r = nr_socket_wrapper_factory_proxy_tunnel_create(config, &wrapper))) {
|
||||
MOZ_MTLOG(PR_LOG_ERROR, "Couldn't create proxy tunnel wrapper.");
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
// nr_ice_ctx will own the wrapper after this call
|
||||
if ((r = nr_ice_ctx_set_turn_tcp_socket_wrapper(ctx_, wrapper))) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't set proxy for '" << name_ << "': " << r);
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
nr_proxy_tunnel_config_destroy(&config);
|
||||
if (_status) {
|
||||
nr_socket_wrapper_factory_destroy(&wrapper);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NrIceCtx::StartGathering() {
|
||||
ASSERT_ON_THREAD(sts_target_);
|
||||
MOZ_ASSERT(ctx_->state == ICE_CTX_INIT);
|
||||
if (ctx_->state != ICE_CTX_INIT) {
|
||||
MOZ_MTLOG(ML_ERROR, "ICE ctx in the wrong state for gathering: '"
|
||||
@ -676,7 +636,8 @@ nsresult NrIceCtx::StartGathering() {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
int r = nr_ice_initialize(ctx_, &NrIceCtx::initialized_cb, this);
|
||||
int r = nr_ice_initialize(ctx_, &NrIceCtx::initialized_cb,
|
||||
this);
|
||||
|
||||
if (r && r != R_WOULDBLOCK) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't gather ICE candidates for '"
|
||||
|
@ -76,7 +76,6 @@ typedef struct nr_ice_cand_pair_ nr_ice_cand_pair;
|
||||
typedef struct nr_ice_stun_server_ nr_ice_stun_server;
|
||||
typedef struct nr_ice_turn_server_ nr_ice_turn_server;
|
||||
typedef struct nr_resolver_ nr_resolver;
|
||||
typedef struct nr_proxy_tunnel_config_ nr_proxy_tunnel_config;
|
||||
|
||||
typedef void* NR_SOCKET;
|
||||
|
||||
@ -172,33 +171,6 @@ class NrIceTurnServer : public NrIceStunServer {
|
||||
std::string transport_;
|
||||
};
|
||||
|
||||
class NrIceProxyServer {
|
||||
public:
|
||||
NrIceProxyServer() :
|
||||
host_(), port_(0) {
|
||||
}
|
||||
|
||||
NrIceProxyServer(const std::string& host, uint16_t port) :
|
||||
host_(host), port_(port) {
|
||||
}
|
||||
|
||||
NrIceProxyServer &operator=(const NrIceProxyServer &that) {
|
||||
if (this != &that) {
|
||||
host_ = that.host_;
|
||||
port_ = that.port_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::string& host() const { return host_; }
|
||||
uint16_t port() const { return port_; }
|
||||
|
||||
private:
|
||||
std::string host_;
|
||||
uint16_t port_;
|
||||
};
|
||||
|
||||
|
||||
class NrIceCtx {
|
||||
public:
|
||||
enum ConnectionState { ICE_CTX_INIT,
|
||||
@ -282,10 +254,6 @@ class NrIceCtx {
|
||||
// StartGathering.
|
||||
nsresult SetResolver(nr_resolver *resolver);
|
||||
|
||||
// Provide the proxy address. Must be called before
|
||||
// StartGathering.
|
||||
nsresult SetProxyServer(const NrIceProxyServer& proxy_server);
|
||||
|
||||
// Start ICE gathering
|
||||
nsresult StartGathering();
|
||||
|
||||
|
@ -24,7 +24,6 @@ extern "C" {
|
||||
|
||||
#include "databuffer.h"
|
||||
#include "mtransport_test_utils.h"
|
||||
#include "dummysocket.h"
|
||||
|
||||
#include "nr_socket_prsock.h"
|
||||
|
||||
@ -43,6 +42,173 @@ static uint8_t kStunMessage[] = {
|
||||
};
|
||||
static size_t kStunMessageLen = sizeof(kStunMessage);
|
||||
|
||||
class DummySocket : public NrSocketBase {
|
||||
public:
|
||||
DummySocket()
|
||||
: writable_(UINT_MAX),
|
||||
write_buffer_(nullptr),
|
||||
readable_(UINT_MAX),
|
||||
read_buffer_(nullptr),
|
||||
cb_(nullptr),
|
||||
cb_arg_(nullptr),
|
||||
self_(nullptr) {}
|
||||
|
||||
// the nr_socket APIs
|
||||
virtual int create(nr_transport_addr *addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int sendto(const void *msg, size_t len,
|
||||
int flags, nr_transport_addr *to) {
|
||||
MOZ_CRASH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int recvfrom(void * buf, size_t maxlen,
|
||||
size_t *len, int flags,
|
||||
nr_transport_addr *from) {
|
||||
MOZ_CRASH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int getaddr(nr_transport_addr *addrp) {
|
||||
MOZ_CRASH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void close() {
|
||||
}
|
||||
|
||||
virtual int connect(nr_transport_addr *addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int write(const void *msg, size_t len, size_t *written) {
|
||||
// Shouldn't be anything here.
|
||||
EXPECT_EQ(nullptr, write_buffer_.get());
|
||||
|
||||
size_t to_write = std::min(len, writable_);
|
||||
|
||||
if (to_write) {
|
||||
write_buffer_ = new DataBuffer(
|
||||
static_cast<const uint8_t *>(msg), to_write);
|
||||
*written = to_write;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int read(void* buf, size_t maxlen, size_t *len) {
|
||||
if (!read_buffer_.get()) {
|
||||
return R_WOULDBLOCK;
|
||||
}
|
||||
|
||||
size_t to_read = std::min(read_buffer_->len(),
|
||||
std::min(maxlen, readable_));
|
||||
|
||||
memcpy(buf, read_buffer_->data(), to_read);
|
||||
*len = to_read;
|
||||
|
||||
if (to_read < read_buffer_->len()) {
|
||||
read_buffer_ = new DataBuffer(read_buffer_->data() + to_read,
|
||||
read_buffer_->len() - to_read);
|
||||
} else {
|
||||
read_buffer_ = nullptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implementations of the async_event APIs.
|
||||
// These are no-ops because we handle scheduling manually
|
||||
// for test purposes.
|
||||
virtual int async_wait(int how, NR_async_cb cb, void *cb_arg,
|
||||
char *function, int line) {
|
||||
EXPECT_EQ(nullptr, cb_);
|
||||
cb_ = cb;
|
||||
cb_arg_ = cb_arg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int cancel(int how) {
|
||||
cb_ = nullptr;
|
||||
cb_arg_ = nullptr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Read/Manipulate the current state.
|
||||
void CheckWriteBuffer(uint8_t *data, size_t len) {
|
||||
if (!len) {
|
||||
EXPECT_EQ(nullptr, write_buffer_.get());
|
||||
} else {
|
||||
EXPECT_NE(nullptr, write_buffer_.get());
|
||||
ASSERT_EQ(len, write_buffer_->len());
|
||||
ASSERT_EQ(0, memcmp(data, write_buffer_->data(), len));
|
||||
}
|
||||
}
|
||||
|
||||
void ClearWriteBuffer() {
|
||||
write_buffer_ = nullptr;
|
||||
}
|
||||
|
||||
void SetWritable(size_t val) {
|
||||
writable_ = val;
|
||||
}
|
||||
|
||||
void FireWritableCb() {
|
||||
NR_async_cb cb = cb_;
|
||||
void *cb_arg = cb_arg_;
|
||||
|
||||
cb_ = nullptr;
|
||||
cb_arg_ = nullptr;
|
||||
|
||||
cb(this, NR_ASYNC_WAIT_WRITE, cb_arg);
|
||||
}
|
||||
|
||||
void SetReadBuffer(uint8_t *data, size_t len) {
|
||||
EXPECT_EQ(nullptr, write_buffer_.get());
|
||||
read_buffer_ = new DataBuffer(data, len);
|
||||
}
|
||||
|
||||
void ClearReadBuffer() {
|
||||
read_buffer_ = nullptr;
|
||||
}
|
||||
|
||||
void SetReadable(size_t val) {
|
||||
readable_ = val;
|
||||
}
|
||||
|
||||
nr_socket *get_nr_socket() {
|
||||
if (!self_) {
|
||||
int r = nr_socket_create_int(this, vtbl(), &self_);
|
||||
AddRef();
|
||||
if (r)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return self_;
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DummySocket);
|
||||
|
||||
private:
|
||||
~DummySocket() {}
|
||||
|
||||
DISALLOW_COPY_ASSIGN(DummySocket);
|
||||
|
||||
size_t writable_; // Amount we allow someone to write.
|
||||
ScopedDeletePtr<DataBuffer> write_buffer_;
|
||||
size_t readable_; // Amount we allow someone to read.
|
||||
ScopedDeletePtr<DataBuffer> read_buffer_;
|
||||
|
||||
NR_async_cb cb_;
|
||||
void *cb_arg_;
|
||||
nr_socket *self_;
|
||||
};
|
||||
|
||||
class BufferedStunSocketTest : public ::testing::Test {
|
||||
public:
|
||||
BufferedStunSocketTest()
|
||||
|
@ -1,224 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Original authors: ekr@rtfm.com; ryan@tokbox.com
|
||||
|
||||
#ifndef MTRANSPORT_DUMMY_SOCKET_H_
|
||||
#define MTRANSPORT_DUMMY_SOCKET_H_
|
||||
|
||||
#include "nr_socket_prsock.h"
|
||||
|
||||
extern "C" {
|
||||
#include "transport_addr.h"
|
||||
}
|
||||
|
||||
#include "databuffer.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#define GTEST_HAS_RTTI 0
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest_utils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
static UniquePtr<DataBuffer> merge(UniquePtr<DataBuffer> a, UniquePtr<DataBuffer> b) {
|
||||
if (a && a->len() && b && b->len()) {
|
||||
UniquePtr<DataBuffer> merged(new DataBuffer());
|
||||
merged->Allocate(a->len() + b->len());
|
||||
|
||||
memcpy(merged->data(), a->data(), a->len());
|
||||
memcpy(merged->data() + a->len(), b->data(), b->len());
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
if (a && a->len()) {
|
||||
return a;
|
||||
}
|
||||
|
||||
if (b && b->len()) {
|
||||
return b;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
class DummySocket : public NrSocketBase {
|
||||
public:
|
||||
DummySocket()
|
||||
: writable_(UINT_MAX),
|
||||
write_buffer_(nullptr),
|
||||
readable_(UINT_MAX),
|
||||
read_buffer_(nullptr),
|
||||
cb_(nullptr),
|
||||
cb_arg_(nullptr),
|
||||
self_(nullptr) {}
|
||||
|
||||
// the nr_socket APIs
|
||||
virtual int create(nr_transport_addr *addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int sendto(const void *msg, size_t len,
|
||||
int flags, nr_transport_addr *to) {
|
||||
MOZ_CRASH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int recvfrom(void * buf, size_t maxlen,
|
||||
size_t *len, int flags,
|
||||
nr_transport_addr *from) {
|
||||
MOZ_CRASH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int getaddr(nr_transport_addr *addrp) {
|
||||
MOZ_CRASH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void close() {
|
||||
}
|
||||
|
||||
virtual int connect(nr_transport_addr *addr) {
|
||||
nr_transport_addr_copy(&connect_addr_, addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int write(const void *msg, size_t len, size_t *written) {
|
||||
size_t to_write = std::min(len, writable_);
|
||||
|
||||
if (to_write) {
|
||||
UniquePtr<DataBuffer> msgbuf(new DataBuffer(static_cast<const uint8_t *>(msg), to_write));
|
||||
write_buffer_ = merge(Move(write_buffer_), Move(msgbuf));
|
||||
}
|
||||
|
||||
*written = to_write;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int read(void* buf, size_t maxlen, size_t *len) {
|
||||
if (!read_buffer_.get()) {
|
||||
return R_WOULDBLOCK;
|
||||
}
|
||||
|
||||
size_t to_read = std::min(read_buffer_->len(),
|
||||
std::min(maxlen, readable_));
|
||||
|
||||
memcpy(buf, read_buffer_->data(), to_read);
|
||||
*len = to_read;
|
||||
|
||||
if (to_read < read_buffer_->len()) {
|
||||
read_buffer_.reset(new DataBuffer(read_buffer_->data() + to_read,
|
||||
read_buffer_->len() - to_read));
|
||||
} else {
|
||||
read_buffer_.reset();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implementations of the async_event APIs.
|
||||
// These are no-ops because we handle scheduling manually
|
||||
// for test purposes.
|
||||
virtual int async_wait(int how, NR_async_cb cb, void *cb_arg,
|
||||
char *function, int line) {
|
||||
EXPECT_EQ(nullptr, cb_);
|
||||
cb_ = cb;
|
||||
cb_arg_ = cb_arg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int cancel(int how) {
|
||||
cb_ = nullptr;
|
||||
cb_arg_ = nullptr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Read/Manipulate the current state.
|
||||
void CheckWriteBuffer(const uint8_t *data, size_t len) {
|
||||
if (!len) {
|
||||
EXPECT_EQ(nullptr, write_buffer_.get());
|
||||
} else {
|
||||
EXPECT_NE(nullptr, write_buffer_.get());
|
||||
ASSERT_EQ(len, write_buffer_->len());
|
||||
ASSERT_EQ(0, memcmp(data, write_buffer_->data(), len));
|
||||
}
|
||||
}
|
||||
|
||||
void ClearWriteBuffer() {
|
||||
write_buffer_.reset();
|
||||
}
|
||||
|
||||
void SetWritable(size_t val) {
|
||||
writable_ = val;
|
||||
}
|
||||
|
||||
void FireWritableCb() {
|
||||
NR_async_cb cb = cb_;
|
||||
void *cb_arg = cb_arg_;
|
||||
|
||||
cb_ = nullptr;
|
||||
cb_arg_ = nullptr;
|
||||
|
||||
cb(this, NR_ASYNC_WAIT_WRITE, cb_arg);
|
||||
}
|
||||
|
||||
void SetReadBuffer(const uint8_t *data, size_t len) {
|
||||
EXPECT_EQ(nullptr, write_buffer_.get());
|
||||
read_buffer_.reset(new DataBuffer(data, len));
|
||||
}
|
||||
|
||||
void ClearReadBuffer() {
|
||||
read_buffer_.reset();
|
||||
}
|
||||
|
||||
void SetReadable(size_t val) {
|
||||
readable_ = val;
|
||||
}
|
||||
|
||||
nr_socket *get_nr_socket() {
|
||||
if (!self_) {
|
||||
int r = nr_socket_create_int(this, vtbl(), &self_);
|
||||
AddRef();
|
||||
if (r)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return self_;
|
||||
}
|
||||
|
||||
nr_transport_addr *get_connect_addr() {
|
||||
return &connect_addr_;
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DummySocket);
|
||||
|
||||
private:
|
||||
~DummySocket() {}
|
||||
|
||||
DISALLOW_COPY_ASSIGN(DummySocket);
|
||||
|
||||
size_t writable_; // Amount we allow someone to write.
|
||||
UniquePtr<DataBuffer> write_buffer_;
|
||||
size_t readable_; // Amount we allow someone to read.
|
||||
UniquePtr<DataBuffer> read_buffer_;
|
||||
|
||||
NR_async_cb cb_;
|
||||
void *cb_arg_;
|
||||
nr_socket *self_;
|
||||
|
||||
nr_transport_addr connect_addr_;
|
||||
};
|
||||
|
||||
} //namespace mozilla
|
||||
|
||||
#endif
|
||||
|
@ -9,7 +9,6 @@ if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
|
||||
'buffered_stun_socket_unittest',
|
||||
'ice_unittest',
|
||||
'nrappkit_unittest',
|
||||
'proxy_tunnel_socket_unittest',
|
||||
'rlogringbuffer_unittest',
|
||||
'runnable_utils_unittest',
|
||||
'simpletokenbucket_unittest',
|
||||
|
@ -1,322 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Original authors: ekr@rtfm.com; ryan@tokbox.com
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "nspr.h"
|
||||
#include "nss.h"
|
||||
#include "ssl.h"
|
||||
|
||||
#include "mozilla/Scoped.h"
|
||||
|
||||
extern "C" {
|
||||
#include "nr_api.h"
|
||||
#include "nr_socket.h"
|
||||
#include "nr_proxy_tunnel.h"
|
||||
#include "transport_addr.h"
|
||||
#include "stun.h"
|
||||
}
|
||||
|
||||
#include "databuffer.h"
|
||||
#include "mtransport_test_utils.h"
|
||||
#include "dummysocket.h"
|
||||
|
||||
#include "nr_socket_prsock.h"
|
||||
#include "nriceresolverfake.h"
|
||||
|
||||
#define GTEST_HAS_RTTI 0
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest_utils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
MtransportTestUtils *test_utils;
|
||||
|
||||
const std::string kRemoteAddr = "192.0.2.133";
|
||||
const uint16_t kRemotePort = 3333;
|
||||
|
||||
const std::string kProxyHost = "example.com";
|
||||
const std::string kProxyAddr = "192.0.2.134";
|
||||
const uint16_t kProxyPort = 9999;
|
||||
|
||||
const std::string kHelloMessage = "HELLO";
|
||||
const std::string kGarbageMessage = "xxxxxxxxxx";
|
||||
|
||||
std::string connect_message(const std::string &host, uint16_t port, const std::string &tail = "") {
|
||||
std::stringstream ss;
|
||||
ss << "CONNECT " << host << ":" << port << " HTTP/1.0\r\n\r\n" << tail;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string connect_response(int code, const std::string &tail = "") {
|
||||
std::stringstream ss;
|
||||
ss << "HTTP/1.0 " << code << "\r\n\r\n" << tail;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
class DummyResolver {
|
||||
public:
|
||||
DummyResolver() {
|
||||
vtbl_ = new nr_resolver_vtbl;
|
||||
vtbl_->destroy = &DummyResolver::destroy;
|
||||
vtbl_->resolve = &DummyResolver::resolve;
|
||||
vtbl_->cancel = &DummyResolver::cancel;
|
||||
nr_resolver_create_int((void *)this, vtbl_, &resolver_);
|
||||
}
|
||||
|
||||
~DummyResolver() {
|
||||
nr_resolver_destroy(&resolver_);
|
||||
delete vtbl_;
|
||||
}
|
||||
|
||||
static int destroy(void **objp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int resolve(void *obj,
|
||||
nr_resolver_resource *resource,
|
||||
int (*cb)(void *cb_arg, nr_transport_addr *addr),
|
||||
void *cb_arg,
|
||||
void **handle) {
|
||||
nr_transport_addr addr;
|
||||
|
||||
nr_ip4_str_port_to_transport_addr(
|
||||
(char *)kProxyAddr.c_str(), kProxyPort, IPPROTO_TCP, &addr);
|
||||
|
||||
cb(cb_arg, &addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cancel(void *obj, void *handle) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
nr_resolver *get_nr_resolver() {
|
||||
return resolver_;
|
||||
}
|
||||
|
||||
private:
|
||||
nr_resolver_vtbl *vtbl_;
|
||||
nr_resolver *resolver_;
|
||||
};
|
||||
|
||||
class ProxyTunnelSocketTest : public ::testing::Test {
|
||||
public:
|
||||
ProxyTunnelSocketTest()
|
||||
: socket_impl_(nullptr),
|
||||
nr_socket_(nullptr) {}
|
||||
|
||||
~ProxyTunnelSocketTest() {
|
||||
nr_socket_destroy(&nr_socket_);
|
||||
nr_proxy_tunnel_config_destroy(&config_);
|
||||
}
|
||||
|
||||
void SetUp() {
|
||||
nsRefPtr<DummySocket> dummy(new DummySocket());
|
||||
|
||||
nr_resolver_ = resolver_impl_.get_nr_resolver();
|
||||
|
||||
int r = nr_ip4_str_port_to_transport_addr(
|
||||
(char *)kRemoteAddr.c_str(), kRemotePort, IPPROTO_TCP, &remote_addr_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
r = nr_ip4_str_port_to_transport_addr(
|
||||
(char *)kProxyAddr.c_str(), kProxyPort, IPPROTO_TCP, &proxy_addr_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
nr_proxy_tunnel_config_create(&config_);
|
||||
nr_proxy_tunnel_config_set_resolver(config_, nr_resolver_);
|
||||
nr_proxy_tunnel_config_set_proxy(config_, kProxyAddr.c_str(), kProxyPort);
|
||||
|
||||
r = nr_socket_proxy_tunnel_create(
|
||||
config_,
|
||||
dummy->get_nr_socket(),
|
||||
&nr_socket_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
socket_impl_ = dummy.forget(); // Now owned by nr_socket_.
|
||||
}
|
||||
|
||||
nr_socket *socket() { return nr_socket_; }
|
||||
|
||||
protected:
|
||||
nsRefPtr<DummySocket> socket_impl_;
|
||||
DummyResolver resolver_impl_;
|
||||
nr_socket *nr_socket_;
|
||||
nr_resolver *nr_resolver_;
|
||||
nr_proxy_tunnel_config *config_;
|
||||
nr_transport_addr proxy_addr_;
|
||||
nr_transport_addr remote_addr_;
|
||||
};
|
||||
|
||||
|
||||
TEST_F(ProxyTunnelSocketTest, TestCreate) {
|
||||
}
|
||||
|
||||
TEST_F(ProxyTunnelSocketTest, TestConnectProxyAddress) {
|
||||
int r = nr_socket_connect(nr_socket_, &remote_addr_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
ASSERT_EQ(0, nr_transport_addr_cmp(socket_impl_->get_connect_addr(), &proxy_addr_,
|
||||
NR_TRANSPORT_ADDR_CMP_MODE_ALL));
|
||||
}
|
||||
|
||||
TEST_F(ProxyTunnelSocketTest, TestConnectProxyRequest) {
|
||||
int r = nr_socket_connect(nr_socket_, &remote_addr_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
size_t written = 0;
|
||||
r = nr_socket_write(nr_socket_, kHelloMessage.c_str(), kHelloMessage.size(), &written, 0);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
std::string msg = connect_message(kRemoteAddr, kRemotePort, kHelloMessage);
|
||||
socket_impl_->CheckWriteBuffer(reinterpret_cast<const uint8_t *>(msg.c_str()), msg.size());
|
||||
}
|
||||
|
||||
TEST_F(ProxyTunnelSocketTest, TestConnectProxyHostRequest) {
|
||||
int r = nr_socket_destroy(&nr_socket_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
nsRefPtr<DummySocket> dummy(new DummySocket());
|
||||
|
||||
nr_proxy_tunnel_config_set_proxy(config_, kProxyHost.c_str(), kProxyPort);
|
||||
|
||||
r = nr_socket_proxy_tunnel_create(
|
||||
config_,
|
||||
dummy->get_nr_socket(),
|
||||
&nr_socket_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
socket_impl_ = dummy.forget(); // Now owned by nr_socket_.
|
||||
|
||||
r = nr_socket_connect(nr_socket_, &remote_addr_);
|
||||
ASSERT_EQ(R_WOULDBLOCK, r);
|
||||
|
||||
size_t written = 0;
|
||||
r = nr_socket_write(nr_socket_, kHelloMessage.c_str(), kHelloMessage.size(), &written, 0);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
std::string msg = connect_message(kRemoteAddr, kRemotePort, kHelloMessage);
|
||||
socket_impl_->CheckWriteBuffer(reinterpret_cast<const uint8_t *>(msg.c_str()), msg.size());
|
||||
}
|
||||
|
||||
TEST_F(ProxyTunnelSocketTest, TestConnectProxyWrite) {
|
||||
int r = nr_socket_connect(nr_socket_, &remote_addr_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
size_t written = 0;
|
||||
r = nr_socket_write(nr_socket_, kHelloMessage.c_str(), kHelloMessage.size(), &written, 0);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
socket_impl_->ClearWriteBuffer();
|
||||
|
||||
r = nr_socket_write(nr_socket_, kHelloMessage.c_str(), kHelloMessage.size(), &written, 0);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
socket_impl_->CheckWriteBuffer(reinterpret_cast<const uint8_t *>(kHelloMessage.c_str()),
|
||||
kHelloMessage.size());
|
||||
}
|
||||
|
||||
TEST_F(ProxyTunnelSocketTest, TestConnectProxySuccessResponse) {
|
||||
int r = nr_socket_connect(nr_socket_, &remote_addr_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
std::string resp = connect_response(200, kHelloMessage);
|
||||
socket_impl_->SetReadBuffer(reinterpret_cast<const uint8_t *>(resp.c_str()), resp.size());
|
||||
|
||||
char buf[4096];
|
||||
size_t read = 0;
|
||||
r = nr_socket_read(nr_socket_, buf, sizeof(buf), &read, 0);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
ASSERT_EQ(kHelloMessage.size(), read);
|
||||
ASSERT_EQ(0, memcmp(buf, kHelloMessage.c_str(), kHelloMessage.size()));
|
||||
}
|
||||
|
||||
TEST_F(ProxyTunnelSocketTest, TestConnectProxyRead) {
|
||||
int r = nr_socket_connect(nr_socket_, &remote_addr_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
std::string resp = connect_response(200, kHelloMessage);
|
||||
socket_impl_->SetReadBuffer(reinterpret_cast<const uint8_t *>(resp.c_str()), resp.size());
|
||||
|
||||
char buf[4096];
|
||||
size_t read = 0;
|
||||
r = nr_socket_read(nr_socket_, buf, sizeof(buf), &read, 0);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
socket_impl_->ClearReadBuffer();
|
||||
socket_impl_->SetReadBuffer(reinterpret_cast<const uint8_t *>(kHelloMessage.c_str()),
|
||||
kHelloMessage.size());
|
||||
|
||||
r = nr_socket_read(nr_socket_, buf, sizeof(buf), &read, 0);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
ASSERT_EQ(kHelloMessage.size(), read);
|
||||
ASSERT_EQ(0, memcmp(buf, kHelloMessage.c_str(), kHelloMessage.size()));
|
||||
}
|
||||
|
||||
TEST_F(ProxyTunnelSocketTest, TestConnectProxyReadNone) {
|
||||
int r = nr_socket_connect(nr_socket_, &remote_addr_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
std::string resp = connect_response(200);
|
||||
socket_impl_->SetReadBuffer(reinterpret_cast<const uint8_t *>(resp.c_str()), resp.size());
|
||||
|
||||
char buf[4096];
|
||||
size_t read = 0;
|
||||
r = nr_socket_read(nr_socket_, buf, sizeof(buf), &read, 0);
|
||||
ASSERT_EQ(R_WOULDBLOCK, r);
|
||||
|
||||
socket_impl_->ClearReadBuffer();
|
||||
socket_impl_->SetReadBuffer(reinterpret_cast<const uint8_t *>(kHelloMessage.c_str()),
|
||||
kHelloMessage.size());
|
||||
|
||||
r = nr_socket_read(nr_socket_, buf, sizeof(buf), &read, 0);
|
||||
ASSERT_EQ(0, r);
|
||||
}
|
||||
|
||||
TEST_F(ProxyTunnelSocketTest, TestConnectProxyFailResponse) {
|
||||
int r = nr_socket_connect(nr_socket_, &remote_addr_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
std::string resp = connect_response(500, kHelloMessage);
|
||||
socket_impl_->SetReadBuffer(reinterpret_cast<const uint8_t *>(resp.c_str()), resp.size());
|
||||
|
||||
char buf[4096];
|
||||
size_t read = 0;
|
||||
r = nr_socket_read(nr_socket_, buf, sizeof(buf), &read, 0);
|
||||
ASSERT_NE(0, r);
|
||||
}
|
||||
|
||||
TEST_F(ProxyTunnelSocketTest, TestConnectProxyGarbageResponse) {
|
||||
int r = nr_socket_connect(nr_socket_, &remote_addr_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
socket_impl_->SetReadBuffer(reinterpret_cast<const uint8_t *>(kGarbageMessage.c_str()),
|
||||
kGarbageMessage.size());
|
||||
|
||||
char buf[4096];
|
||||
size_t read = 0;
|
||||
r = nr_socket_read(nr_socket_, buf, sizeof(buf), &read, 0);
|
||||
ASSERT_EQ(0ul, read);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
test_utils = new MtransportTestUtils();
|
||||
NSS_NoDB_Init(nullptr);
|
||||
NSS_SetDomesticPolicy();
|
||||
|
||||
// Start the tests
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
int rv = RUN_ALL_TESTS();
|
||||
|
||||
delete test_utils;
|
||||
return rv;
|
||||
}
|
14
media/mtransport/third_party/nICEr/nicer.gyp
vendored
14
media/mtransport/third_party/nICEr/nicer.gyp
vendored
@ -66,10 +66,6 @@
|
||||
# Net
|
||||
"./src/net/nr_resolver.c",
|
||||
"./src/net/nr_resolver.h",
|
||||
"./src/net/nr_socket_wrapper.c",
|
||||
"./src/net/nr_socket_wrapper.h",
|
||||
"./src/net/nr_proxy_tunnel.c",
|
||||
"./src/net/nr_proxy_tunnel.h",
|
||||
"./src/net/nr_socket.c",
|
||||
"./src/net/nr_socket.h",
|
||||
#"./src/net/nr_socket_local.c",
|
||||
@ -121,7 +117,7 @@
|
||||
|
||||
|
||||
],
|
||||
|
||||
|
||||
'defines' : [
|
||||
'SANITY_CHECKS',
|
||||
'USE_TURN',
|
||||
@ -140,7 +136,7 @@
|
||||
'R_DEFINED_INT8=int64_t',
|
||||
'R_DEFINED_UINT8=uint64_t',
|
||||
],
|
||||
|
||||
|
||||
'conditions' : [
|
||||
## Mac and BSDs
|
||||
[ 'OS == "mac"', {
|
||||
@ -176,11 +172,11 @@
|
||||
'include_dirs': [
|
||||
'../nrappkit/src/port/darwin/include'
|
||||
],
|
||||
|
||||
|
||||
'sources': [
|
||||
],
|
||||
}],
|
||||
|
||||
|
||||
## Win
|
||||
[ 'OS == "win"', {
|
||||
'defines' : [
|
||||
@ -224,7 +220,7 @@
|
||||
'include_dirs': [
|
||||
'../nrappkit/src/port/linux/include'
|
||||
],
|
||||
|
||||
|
||||
'sources': [
|
||||
],
|
||||
}],
|
||||
|
@ -44,7 +44,6 @@ static char *RCSSTRING __UNUSED__="$Id: ice_component.c,v 1.2 2008/04/28 17:59:0
|
||||
#include "stun.h"
|
||||
#include "nr_socket_local.h"
|
||||
#include "nr_socket_turn.h"
|
||||
#include "nr_socket_wrapper.h"
|
||||
#include "nr_socket_buffered_stun.h"
|
||||
#include "ice_reg.h"
|
||||
|
||||
@ -291,8 +290,6 @@ static int nr_ice_component_initialize_tcp(struct nr_ice_ctx_ *ctx,nr_ice_compon
|
||||
char label[256];
|
||||
int r,_status;
|
||||
|
||||
r_log(LOG_ICE,LOG_DEBUG,"nr_ice_component_initialize_tcp");
|
||||
|
||||
/* Create a new relayed candidate for each addr/TURN server pair */
|
||||
for(i=0;i<addr_ct;i++){
|
||||
char suppress;
|
||||
@ -327,15 +324,6 @@ static int nr_ice_component_initialize_tcp(struct nr_ice_ctx_ *ctx,nr_ice_compon
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): couldn't create socket for address %s",ctx->label,addr.as_string);
|
||||
continue;
|
||||
}
|
||||
|
||||
r_log(LOG_ICE,LOG_DEBUG,"nr_ice_component_initialize_tcp create");
|
||||
|
||||
if (ctx->turn_tcp_socket_wrapper) {
|
||||
/* Wrap it */
|
||||
if((r=nr_socket_wrapper_factory_wrap(ctx->turn_tcp_socket_wrapper, sock, &sock)))
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
/* Wrap it */
|
||||
if((r=nr_socket_buffered_stun_create(sock, NR_STUN_MAX_MESSAGE_SIZE, &buffered_sock)))
|
||||
ABORT(r);
|
||||
|
@ -214,21 +214,6 @@ int nr_ice_ctx_set_interface_prioritizer(nr_ice_ctx *ctx, nr_interface_prioritiz
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_ctx_set_turn_tcp_socket_wrapper(nr_ice_ctx *ctx, nr_socket_wrapper_factory *wrapper)
|
||||
{
|
||||
int _status;
|
||||
|
||||
if (ctx->turn_tcp_socket_wrapper) {
|
||||
ABORT(R_ALREADY);
|
||||
}
|
||||
|
||||
ctx->turn_tcp_socket_wrapper = wrapper;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
#ifdef USE_TURN
|
||||
int nr_ice_fetch_turn_servers(int ct, nr_ice_turn_server **out)
|
||||
{
|
||||
@ -437,7 +422,6 @@ static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
|
||||
|
||||
nr_resolver_destroy(&ctx->resolver);
|
||||
nr_interface_prioritizer_destroy(&ctx->interface_prioritizer);
|
||||
nr_socket_wrapper_factory_destroy(&ctx->turn_tcp_socket_wrapper);
|
||||
|
||||
RFREE(ctx);
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ extern "C" {
|
||||
#include "nr_socket.h"
|
||||
#include "nr_resolver.h"
|
||||
#include "nr_interface_prioritizer.h"
|
||||
#include "nr_socket_wrapper.h"
|
||||
#include "stun_client_ctx.h"
|
||||
#include "stun_server_ctx.h"
|
||||
#include "turn_client_ctx.h"
|
||||
@ -133,7 +132,6 @@ struct nr_ice_ctx_ {
|
||||
|
||||
nr_resolver *resolver; /* The resolver to use */
|
||||
nr_interface_prioritizer *interface_prioritizer; /* Priority decision logic */
|
||||
nr_socket_wrapper_factory *turn_tcp_socket_wrapper; /* The TURN TCP socket wrapper to use */
|
||||
|
||||
nr_ice_foundation_head foundations;
|
||||
|
||||
@ -175,7 +173,6 @@ int nr_ice_ctx_set_stun_servers(nr_ice_ctx *ctx,nr_ice_stun_server *servers, int
|
||||
int nr_ice_ctx_set_turn_servers(nr_ice_ctx *ctx,nr_ice_turn_server *servers, int ct);
|
||||
int nr_ice_ctx_set_resolver(nr_ice_ctx *ctx, nr_resolver *resolver);
|
||||
int nr_ice_ctx_set_interface_prioritizer(nr_ice_ctx *ctx, nr_interface_prioritizer *prioritizer);
|
||||
int nr_ice_ctx_set_turn_tcp_socket_wrapper(nr_ice_ctx *ctx, nr_socket_wrapper_factory *wrapper);
|
||||
int nr_ice_ctx_set_trickle_cb(nr_ice_ctx *ctx, nr_ice_trickle_candidate_cb cb, void *cb_arg);
|
||||
|
||||
#define NR_ICE_MAX_ATTRIBUTE_SIZE 256
|
||||
|
@ -1,595 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2007, Adobe Systems, Incorporated
|
||||
Copyright (c) 2013, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Adobe Systems, Network Resonance, Mozilla nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <nr_api.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "nr_proxy_tunnel.h"
|
||||
|
||||
#define MAX_HTTP_CONNECT_ADDR_SIZE 256
|
||||
#define MAX_HTTP_CONNECT_BUFFER_SIZE 1024
|
||||
#define ENDLN "\r\n\r\n"
|
||||
|
||||
typedef struct nr_socket_proxy_tunnel_ {
|
||||
nr_proxy_tunnel_config *config;
|
||||
nr_socket *inner;
|
||||
nr_transport_addr remote_addr;
|
||||
int connect_requested;
|
||||
int connect_answered;
|
||||
int connect_failed;
|
||||
char buffer[MAX_HTTP_CONNECT_BUFFER_SIZE];
|
||||
size_t buffered_bytes;
|
||||
void *resolver_handle;
|
||||
} nr_socket_proxy_tunnel;
|
||||
|
||||
typedef struct nr_socket_wrapper_factory_proxy_tunnel_ {
|
||||
nr_proxy_tunnel_config *config;
|
||||
} nr_socket_wrapper_factory_proxy_tunnel;
|
||||
|
||||
static int nr_socket_proxy_tunnel_destroy(void **objpp);
|
||||
static int nr_socket_proxy_tunnel_getfd(void *obj, NR_SOCKET *fd);
|
||||
static int nr_socket_proxy_tunnel_getaddr(void *obj, nr_transport_addr *addrp);
|
||||
static int nr_socket_proxy_tunnel_connect(void *sock, nr_transport_addr *addr);
|
||||
static int nr_socket_proxy_tunnel_write(void *obj, const void *msg, size_t len, size_t *written);
|
||||
static int nr_socket_proxy_tunnel_read(void *obj, void * restrict buf, size_t maxlen, size_t *len);
|
||||
static int nr_socket_proxy_tunnel_close(void *obj);
|
||||
|
||||
int nr_proxy_tunnel_config_copy(nr_proxy_tunnel_config *config, nr_proxy_tunnel_config **copypp);
|
||||
|
||||
int nr_socket_wrapper_factory_proxy_tunnel_wrap(void *obj,
|
||||
nr_socket *inner,
|
||||
nr_socket **socketpp);
|
||||
|
||||
int nr_socket_wrapper_factory_proxy_tunnel_destroy(void **objpp);
|
||||
|
||||
static nr_socket_vtbl nr_socket_proxy_tunnel_vtbl={
|
||||
1,
|
||||
nr_socket_proxy_tunnel_destroy,
|
||||
0,
|
||||
0,
|
||||
nr_socket_proxy_tunnel_getfd,
|
||||
nr_socket_proxy_tunnel_getaddr,
|
||||
nr_socket_proxy_tunnel_connect,
|
||||
nr_socket_proxy_tunnel_write,
|
||||
nr_socket_proxy_tunnel_read,
|
||||
nr_socket_proxy_tunnel_close
|
||||
};
|
||||
|
||||
static int send_http_connect(nr_socket_proxy_tunnel *sock)
|
||||
{
|
||||
int r, _status;
|
||||
int port;
|
||||
int printed;
|
||||
char addr[MAX_HTTP_CONNECT_ADDR_SIZE];
|
||||
char mesg[MAX_HTTP_CONNECT_ADDR_SIZE + 64];
|
||||
size_t bytes_sent;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"send_http_connect");
|
||||
|
||||
if ((r=nr_transport_addr_get_port(&sock->remote_addr, &port))) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
if ((r=nr_transport_addr_get_addrstring(&sock->remote_addr, addr, sizeof(addr)))) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
printed = snprintf(mesg, sizeof(mesg), "CONNECT %s:%d HTTP/1.0%s", addr, port, ENDLN);
|
||||
if (printed < 0 || printed >= (int)sizeof(mesg)) {
|
||||
ABORT(R_FAILED);
|
||||
}
|
||||
|
||||
if ((r=nr_socket_write(sock->inner, mesg, strlen(mesg), &bytes_sent, 0))) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
if (bytes_sent < strlen(mesg)) {
|
||||
/* TODO(bug 1116583): buffering and wait for */
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"send_http_connect should be buffering %lu", (unsigned long)bytes_sent);
|
||||
ABORT(R_IO_ERROR);
|
||||
}
|
||||
|
||||
sock->connect_requested = 1;
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
static char *find_http_terminator(char *response, size_t len)
|
||||
{
|
||||
char *term = response;
|
||||
char *end = response + len;
|
||||
int N = strlen(ENDLN);
|
||||
|
||||
for (; term = memchr(term, '\r', end - term); ++term) {
|
||||
if (end - term >= N && memcmp(term, ENDLN, N) == 0) {
|
||||
return term;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int parse_http_response(char *begin, char *end, unsigned int *status)
|
||||
{
|
||||
size_t len = end - begin;
|
||||
char response[MAX_HTTP_CONNECT_BUFFER_SIZE + 1];
|
||||
|
||||
// len should *never* be greater than nr_socket_proxy_tunnel::buffered_bytes.
|
||||
// Which in turn should never be greater nr_socket_proxy_tunnel::buffer size.
|
||||
assert(len <= MAX_HTTP_CONNECT_BUFFER_SIZE);
|
||||
|
||||
memcpy(response, begin, len);
|
||||
response[len] = '\0';
|
||||
|
||||
// http://www.rfc-editor.org/rfc/rfc7230.txt
|
||||
// status-line = HTTP-version SP status-code SP reason-phrase CRLF
|
||||
// HTTP-version = HTTP-name "/" DIGIT "." DIGIT
|
||||
// HTTP-name = "HTTP" ; "HTTP", case-sensitive
|
||||
// status-code = 3DIGIT
|
||||
|
||||
if (sscanf(response, "HTTP/%*u.%*u %u", status) != 1) {
|
||||
r_log(LOG_GENERIC,LOG_WARNING,"parse_http_response failed to find status (%s)", response);
|
||||
return R_BAD_DATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nr_socket_proxy_tunnel_destroy(void **objpp)
|
||||
{
|
||||
nr_socket_proxy_tunnel *sock;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_proxy_tunnel_destroy");
|
||||
|
||||
if (!objpp || !*objpp)
|
||||
return 0;
|
||||
|
||||
sock = (nr_socket_proxy_tunnel *)*objpp;
|
||||
*objpp = 0;
|
||||
|
||||
if (sock->resolver_handle) {
|
||||
nr_resolver_cancel(sock->config->resolver, sock->resolver_handle);
|
||||
}
|
||||
|
||||
nr_proxy_tunnel_config_destroy(&sock->config);
|
||||
nr_socket_destroy(&sock->inner);
|
||||
RFREE(sock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nr_socket_proxy_tunnel_getfd(void *obj, NR_SOCKET *fd)
|
||||
{
|
||||
nr_socket_proxy_tunnel *sock = (nr_socket_proxy_tunnel *)obj;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_proxy_tunnel_getfd");
|
||||
|
||||
return nr_socket_getfd(sock->inner, fd);
|
||||
}
|
||||
|
||||
static int nr_socket_proxy_tunnel_getaddr(void *obj, nr_transport_addr *addrp)
|
||||
{
|
||||
nr_socket_proxy_tunnel *sock = (nr_socket_proxy_tunnel *)obj;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_proxy_tunnel_getaddr");
|
||||
|
||||
return nr_socket_getaddr(sock->inner, addrp);
|
||||
}
|
||||
|
||||
static int nr_socket_proxy_tunnel_resolved_cb(void *obj, nr_transport_addr *proxy_addr)
|
||||
{
|
||||
int r, _status;
|
||||
nr_socket_proxy_tunnel *sock = (nr_socket_proxy_tunnel*)obj;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_proxy_tunnel_resolved_cb");
|
||||
|
||||
/* Mark the socket resolver as completed */
|
||||
sock->resolver_handle = 0;
|
||||
|
||||
if (proxy_addr) {
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"Resolved proxy address %s -> %s",
|
||||
sock->config->proxy_host, proxy_addr->as_string);
|
||||
}
|
||||
else {
|
||||
r_log(LOG_GENERIC,LOG_WARNING,"Failed to resolve proxy %s",
|
||||
sock->config->proxy_host);
|
||||
ABORT(R_NOT_FOUND);
|
||||
}
|
||||
|
||||
if ((r=nr_socket_connect(sock->inner, proxy_addr))) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_socket_proxy_tunnel_connect(void *obj, nr_transport_addr *addr)
|
||||
{
|
||||
int r, _status;
|
||||
int has_addr;
|
||||
nr_socket_proxy_tunnel *sock = (nr_socket_proxy_tunnel*)obj;
|
||||
nr_proxy_tunnel_config *config = sock->config;
|
||||
nr_transport_addr proxy_addr;
|
||||
nr_resolver_resource resource;
|
||||
|
||||
if ((r=nr_transport_addr_copy(&sock->remote_addr, addr))) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
assert(config->proxy_host);
|
||||
|
||||
/* Check if the proxy_host is already an IP address */
|
||||
has_addr = !nr_ip4_str_port_to_transport_addr(config->proxy_host,
|
||||
config->proxy_port, IPPROTO_TCP, &proxy_addr);
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_proxy_tunnel_connect: %s", config->proxy_host);
|
||||
|
||||
if (!has_addr && !config->resolver) {
|
||||
r_log(LOG_GENERIC,LOG_ERR,"nr_socket_proxy_tunnel_connect name resolver not configured");
|
||||
ABORT(R_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (!has_addr) {
|
||||
resource.domain_name=config->proxy_host;
|
||||
resource.port=config->proxy_port;
|
||||
resource.stun_turn=NR_RESOLVE_PROTOCOL_TURN;
|
||||
resource.transport_protocol=IPPROTO_TCP;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_proxy_tunnel_connect: nr_resolver_resolve");
|
||||
if ((r=nr_resolver_resolve(config->resolver, &resource,
|
||||
nr_socket_proxy_tunnel_resolved_cb, (void *)sock, &sock->resolver_handle))) {
|
||||
r_log(LOG_GENERIC,LOG_ERR,"Could not invoke DNS resolver");
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
ABORT(R_WOULDBLOCK);
|
||||
}
|
||||
|
||||
if ((r=nr_socket_connect(sock->inner, &proxy_addr))) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_socket_proxy_tunnel_write(void *obj, const void *msg, size_t len,
|
||||
size_t *written)
|
||||
{
|
||||
int r, _status;
|
||||
nr_socket_proxy_tunnel *sock = (nr_socket_proxy_tunnel*)obj;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_proxy_tunnel_write");
|
||||
|
||||
if (!sock->connect_requested) {
|
||||
if ((r=send_http_connect(sock))) {
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO (bug 1117984): we cannot assume it's safe to write until we receive a response. */
|
||||
if ((r=nr_socket_write(sock->inner, msg, len, written, 0))) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_socket_proxy_tunnel_read(void *obj, void * restrict buf, size_t maxlen,
|
||||
size_t *len)
|
||||
{
|
||||
int r, _status;
|
||||
char *ptr, *http_term;
|
||||
size_t bytes_read, available_buffer_len, maxlen_int;
|
||||
size_t pending;
|
||||
nr_socket_proxy_tunnel *sock = (nr_socket_proxy_tunnel*)obj;
|
||||
unsigned int http_status;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_proxy_tunnel_read");
|
||||
|
||||
*len = 0;
|
||||
|
||||
if (sock->connect_failed) {
|
||||
return R_FAILED;
|
||||
}
|
||||
|
||||
if (sock->connect_answered) {
|
||||
return nr_socket_read(sock->inner, buf, maxlen, len, 0);
|
||||
}
|
||||
|
||||
if (sock->buffered_bytes >= sizeof(sock->buffer)) {
|
||||
r_log(LOG_GENERIC,LOG_ERR,"buffer filled waiting for CONNECT response");
|
||||
assert(sock->buffered_bytes == sizeof(sock->buffer));
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
|
||||
/* Do not read more than maxlen bytes */
|
||||
available_buffer_len = sizeof(sock->buffer) - sock->buffered_bytes;
|
||||
maxlen_int = maxlen < available_buffer_len ? maxlen : available_buffer_len;
|
||||
if ((r=nr_socket_read(sock->inner, sock->buffer + sock->buffered_bytes,
|
||||
maxlen_int, &bytes_read, 0))) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
sock->buffered_bytes += bytes_read;
|
||||
|
||||
if (http_term = find_http_terminator(sock->buffer, sock->buffered_bytes)) {
|
||||
sock->connect_answered = 1;
|
||||
|
||||
if ((r = parse_http_response(sock->buffer, http_term, &http_status))) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
/* TODO (bug 1115934): Handle authentication challenges. */
|
||||
if (http_status < 200 || http_status >= 300) {
|
||||
r_log(LOG_GENERIC,LOG_ERR,"nr_socket_proxy_tunnel_read unable to connect %u",
|
||||
http_status);
|
||||
ABORT(R_FAILED);
|
||||
}
|
||||
|
||||
ptr = http_term + strlen(ENDLN);
|
||||
pending = sock->buffered_bytes - (ptr - sock->buffer);
|
||||
|
||||
if (pending == 0) {
|
||||
ABORT(R_WOULDBLOCK);
|
||||
}
|
||||
|
||||
assert(pending <= maxlen);
|
||||
*len = pending;
|
||||
|
||||
memcpy(buf, ptr, *len);
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if (_status && _status != R_WOULDBLOCK) {
|
||||
sock->connect_failed = 1;
|
||||
}
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_socket_proxy_tunnel_close(void *obj)
|
||||
{
|
||||
nr_socket_proxy_tunnel *sock = (nr_socket_proxy_tunnel*)obj;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_proxy_tunnel_close");
|
||||
|
||||
if (sock->resolver_handle) {
|
||||
nr_resolver_cancel(sock->config->resolver, sock->resolver_handle);
|
||||
sock->resolver_handle = 0;
|
||||
}
|
||||
|
||||
return nr_socket_close(sock->inner);
|
||||
}
|
||||
|
||||
int nr_proxy_tunnel_config_create(nr_proxy_tunnel_config **configpp)
|
||||
{
|
||||
int _status;
|
||||
nr_proxy_tunnel_config *configp=0;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_proxy_tunnel_config_create");
|
||||
|
||||
if (!(configp=RCALLOC(sizeof(nr_proxy_tunnel_config))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
*configpp=configp;
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_proxy_tunnel_config_destroy(nr_proxy_tunnel_config **configpp)
|
||||
{
|
||||
nr_proxy_tunnel_config *configp;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_proxy_tunnel_config_destroy");
|
||||
|
||||
if (!configpp || !*configpp)
|
||||
return 0;
|
||||
|
||||
configp = *configpp;
|
||||
*configpp = 0;
|
||||
|
||||
RFREE(configp->proxy_host);
|
||||
RFREE(configp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_proxy_tunnel_config_set_proxy(nr_proxy_tunnel_config *config,
|
||||
const char *host, UINT2 port)
|
||||
{
|
||||
char *hostdup;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_proxy_tunnel_config_set_proxy %s %d", host, port);
|
||||
|
||||
if (!host) {
|
||||
return R_BAD_ARGS;
|
||||
}
|
||||
|
||||
if (!(hostdup = r_strdup(host))) {
|
||||
return R_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (config->proxy_host) {
|
||||
RFREE(config->proxy_host);
|
||||
}
|
||||
|
||||
config->proxy_host = hostdup;
|
||||
config->proxy_port = port;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_proxy_tunnel_config_set_resolver(nr_proxy_tunnel_config *config,
|
||||
nr_resolver *resolver)
|
||||
{
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_proxy_tunnel_config_set_resolver");
|
||||
|
||||
config->resolver = resolver;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_proxy_tunnel_config_copy(nr_proxy_tunnel_config *config, nr_proxy_tunnel_config **copypp)
|
||||
{
|
||||
int r,_status;
|
||||
nr_proxy_tunnel_config *copy = 0;
|
||||
|
||||
if ((r=nr_proxy_tunnel_config_create(©)))
|
||||
ABORT(r);
|
||||
|
||||
if ((r=nr_proxy_tunnel_config_set_proxy(copy, config->proxy_host, config->proxy_port)))
|
||||
ABORT(r);
|
||||
|
||||
if ((r=nr_proxy_tunnel_config_set_resolver(copy, config->resolver)))
|
||||
ABORT(r);
|
||||
|
||||
*copypp = copy;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if (_status) {
|
||||
nr_proxy_tunnel_config_destroy(©);
|
||||
}
|
||||
return(_status);
|
||||
}
|
||||
|
||||
|
||||
int nr_socket_proxy_tunnel_create(nr_proxy_tunnel_config *config,
|
||||
nr_socket *inner,
|
||||
nr_socket **socketpp)
|
||||
{
|
||||
int r, _status;
|
||||
nr_socket_proxy_tunnel *sock=0;
|
||||
void *sockv;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_proxy_tunnel_create");
|
||||
|
||||
if (!config) {
|
||||
ABORT(R_BAD_ARGS);
|
||||
}
|
||||
|
||||
if (!(sock=RCALLOC(sizeof(nr_socket_proxy_tunnel)))) {
|
||||
ABORT(R_NO_MEMORY);
|
||||
}
|
||||
|
||||
sock->inner = inner;
|
||||
|
||||
if ((r=nr_proxy_tunnel_config_copy(config, &sock->config)))
|
||||
ABORT(r);
|
||||
|
||||
if ((r=nr_socket_create_int(sock, &nr_socket_proxy_tunnel_vtbl, socketpp))) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_proxy_tunnel_created");
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if (_status) {
|
||||
sockv = sock;
|
||||
nr_socket_proxy_tunnel_destroy(&sockv);
|
||||
}
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_socket_wrapper_factory_proxy_tunnel_wrap(void *obj,
|
||||
nr_socket *inner,
|
||||
nr_socket **socketpp)
|
||||
{
|
||||
nr_socket_wrapper_factory_proxy_tunnel *wrapper = (nr_socket_wrapper_factory_proxy_tunnel *)obj;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_wrapper_factory_proxy_tunnel_wrap");
|
||||
|
||||
return nr_socket_proxy_tunnel_create(wrapper->config, inner, socketpp);
|
||||
}
|
||||
|
||||
|
||||
int nr_socket_wrapper_factory_proxy_tunnel_destroy(void **objpp) {
|
||||
nr_socket_wrapper_factory_proxy_tunnel *wrapper;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_wrapper_factory_proxy_tunnel_destroy");
|
||||
|
||||
if (!objpp || !*objpp)
|
||||
return 0;
|
||||
|
||||
wrapper = (nr_socket_wrapper_factory_proxy_tunnel *)*objpp;
|
||||
*objpp = 0;
|
||||
|
||||
nr_proxy_tunnel_config_destroy(&wrapper->config);
|
||||
RFREE(wrapper);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static nr_socket_wrapper_factory_vtbl proxy_tunnel_wrapper_vtbl = {
|
||||
nr_socket_wrapper_factory_proxy_tunnel_wrap,
|
||||
nr_socket_wrapper_factory_proxy_tunnel_destroy
|
||||
};
|
||||
|
||||
int nr_socket_wrapper_factory_proxy_tunnel_create(nr_proxy_tunnel_config *config,
|
||||
nr_socket_wrapper_factory **factory) {
|
||||
int r,_status;
|
||||
nr_socket_wrapper_factory_proxy_tunnel *wrapper=0;
|
||||
void *wrapperv;
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_wrapper_factory_proxy_tunnel_create");
|
||||
|
||||
if (!(wrapper=RCALLOC(sizeof(nr_socket_wrapper_factory_proxy_tunnel))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
if ((r=nr_proxy_tunnel_config_copy(config, &wrapper->config)))
|
||||
ABORT(r);
|
||||
|
||||
if ((r=nr_socket_wrapper_factory_create_int(wrapper, &proxy_tunnel_wrapper_vtbl, factory)))
|
||||
ABORT(r);
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if (_status) {
|
||||
wrapperv = wrapper;
|
||||
nr_socket_wrapper_factory_proxy_tunnel_destroy(&wrapperv);
|
||||
}
|
||||
return(_status);
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2007, Adobe Systems, Incorporated
|
||||
Copyright (c) 2013, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Adobe Systems, Network Resonance, Mozilla nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _nr_proxy_tunnel_h
|
||||
#define _nr_proxy_tunnel_h
|
||||
|
||||
#include "nr_socket.h"
|
||||
#include "nr_resolver.h"
|
||||
#include "nr_socket_wrapper.h"
|
||||
|
||||
typedef struct nr_proxy_tunnel_config_ {
|
||||
nr_resolver *resolver;
|
||||
char *proxy_host;
|
||||
UINT2 proxy_port;
|
||||
} nr_proxy_tunnel_config;
|
||||
|
||||
int nr_proxy_tunnel_config_create(nr_proxy_tunnel_config **config);
|
||||
|
||||
int nr_proxy_tunnel_config_destroy(nr_proxy_tunnel_config **config);
|
||||
|
||||
int nr_proxy_tunnel_config_set_proxy(nr_proxy_tunnel_config *config,
|
||||
const char* host, UINT2 port);
|
||||
|
||||
int nr_proxy_tunnel_config_set_resolver(nr_proxy_tunnel_config *config,
|
||||
nr_resolver *resolver);
|
||||
|
||||
int nr_socket_proxy_tunnel_create(nr_proxy_tunnel_config *config,
|
||||
nr_socket *inner,
|
||||
nr_socket **socketpp);
|
||||
|
||||
int nr_socket_wrapper_factory_proxy_tunnel_create(nr_proxy_tunnel_config *config,
|
||||
nr_socket_wrapper_factory **factory);
|
||||
|
||||
#endif
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2007, Adobe Systems, Incorporated
|
||||
Copyright (c) 2013, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Adobe Systems, Network Resonance, Mozilla nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <nr_api.h>
|
||||
#include "nr_socket_wrapper.h"
|
||||
|
||||
int nr_socket_wrapper_factory_create_int(void *obj, nr_socket_wrapper_factory_vtbl *vtbl,
|
||||
nr_socket_wrapper_factory **wrapperp)
|
||||
{
|
||||
int _status;
|
||||
nr_socket_wrapper_factory *wrapper=0;
|
||||
|
||||
if (!(wrapper=RCALLOC(sizeof(nr_socket_wrapper_factory))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
wrapper->obj=obj;
|
||||
wrapper->vtbl=vtbl;
|
||||
|
||||
*wrapperp=wrapper;
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_socket_wrapper_factory_wrap(nr_socket_wrapper_factory *wrapper,
|
||||
nr_socket *inner,
|
||||
nr_socket **socketp)
|
||||
{
|
||||
return wrapper->vtbl->wrap(wrapper->obj, inner, socketp);
|
||||
}
|
||||
|
||||
int nr_socket_wrapper_factory_destroy(nr_socket_wrapper_factory **wrapperp)
|
||||
{
|
||||
nr_socket_wrapper_factory *wrapper;
|
||||
|
||||
if (!wrapperp || !*wrapperp)
|
||||
return 0;
|
||||
|
||||
wrapper = *wrapperp;
|
||||
*wrapperp = 0;
|
||||
|
||||
assert(wrapper->vtbl);
|
||||
if (wrapper->vtbl)
|
||||
wrapper->vtbl->destroy(&wrapper->obj);
|
||||
|
||||
RFREE(wrapper);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2007, Adobe Systems, Incorporated
|
||||
Copyright (c) 2013, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Adobe Systems, Network Resonance, Mozilla nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _nr_socket_wrapper_h
|
||||
#define _nr_socket_wrapper_h
|
||||
|
||||
#include "nr_socket.h"
|
||||
|
||||
typedef struct nr_socket_wrapper_factory_vtbl_ {
|
||||
int (*wrap)(void *obj,
|
||||
nr_socket *socket,
|
||||
nr_socket **socketp);
|
||||
int (*destroy)(void **obj);
|
||||
} nr_socket_wrapper_factory_vtbl;
|
||||
|
||||
typedef struct nr_socket_wrapper_factory_ {
|
||||
void *obj;
|
||||
nr_socket_wrapper_factory_vtbl *vtbl;
|
||||
} nr_socket_wrapper_factory;
|
||||
|
||||
|
||||
int nr_socket_wrapper_factory_create_int(void *obj, nr_socket_wrapper_factory_vtbl *vtbl,
|
||||
nr_socket_wrapper_factory **wrapperp);
|
||||
|
||||
|
||||
int nr_socket_wrapper_factory_wrap(nr_socket_wrapper_factory *wrapper, nr_socket *inner,
|
||||
nr_socket **socketp);
|
||||
|
||||
int nr_socket_wrapper_factory_destroy(nr_socket_wrapper_factory **wrapperp);
|
||||
|
||||
#endif
|
@ -23,12 +23,6 @@
|
||||
#include "signaling/src/jsep/JsepSession.h"
|
||||
#include "signaling/src/jsep/JsepTransport.h"
|
||||
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsICancelable.h"
|
||||
#include "nsIProxyInfo.h"
|
||||
#include "nsIProtocolProxyService.h"
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
#include "MediaStreamList.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
@ -204,48 +198,6 @@ PeerConnectionImpl* PeerConnectionImpl::CreatePeerConnection()
|
||||
return pc;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP PeerConnectionMedia::ProtocolProxyQueryHandler::
|
||||
OnProxyAvailable(nsICancelable *request, nsIURI *uri, nsIProxyInfo *proxyinfo,
|
||||
nsresult result) {
|
||||
CSFLogInfo(logTag, "%s: Proxy Available: %d", __FUNCTION__, (int)result);
|
||||
|
||||
if (NS_SUCCEEDED(result) && proxyinfo) {
|
||||
nsresult rv;
|
||||
nsCString httpsProxyHost;
|
||||
int32_t httpsProxyPort;
|
||||
|
||||
rv = proxyinfo->GetHost(httpsProxyHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "%s: Failed to get proxy server host", __FUNCTION__);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = proxyinfo->GetPort(&httpsProxyPort);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "%s: Failed to get proxy server port", __FUNCTION__);
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (pcm_->mIceCtx.get()) {
|
||||
assert(httpsProxyPort >= 0 && httpsProxyPort < (1 << 16));
|
||||
pcm_->mProxyServer = NrIceProxyServer(httpsProxyHost.get(),
|
||||
static_cast<uint16_t>(httpsProxyPort));
|
||||
} else {
|
||||
CSFLogError(logTag, "%s: Failed to set proxy server (ICE ctx unavailable)",
|
||||
__FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
if (result != NS_ERROR_ABORT) {
|
||||
// NS_ERROR_ABORT means that the PeerConnectionMedia is no longer waiting
|
||||
pcm_->mProxyResolveCompleted = true;
|
||||
pcm_->GatherIfReady();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(PeerConnectionMedia::ProtocolProxyQueryHandler, nsIProtocolProxyCallback)
|
||||
|
||||
PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent)
|
||||
: mParent(parent),
|
||||
@ -256,37 +208,7 @@ PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent)
|
||||
mDNSResolver(new mozilla::NrIceResolver()),
|
||||
mUuidGen(MakeUnique<PCUuidGenerator>()),
|
||||
mMainThread(mParent->GetMainThread()),
|
||||
mSTSThread(mParent->GetSTSThread()),
|
||||
mTransportsUpdated(false),
|
||||
mProxyResolveCompleted(false) {
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIProtocolProxyService> pps =
|
||||
do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "%s: Failed to get proxy service: %d", __FUNCTION__, (int)rv);
|
||||
return;
|
||||
}
|
||||
|
||||
// We use the following URL to find the "default" proxy address for all HTTPS
|
||||
// connections. We will only attempt one HTTP(S) CONNECT per peer connection.
|
||||
// "example.com" is guaranteed to be unallocated and should return the best default.
|
||||
nsCOMPtr<nsIURI> fakeHttpsLocation;
|
||||
rv = NS_NewURI(getter_AddRefs(fakeHttpsLocation), "https://example.com");
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "%s: Failed to set URI: %d", __FUNCTION__, (int)rv);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<ProtocolProxyQueryHandler> handler = new ProtocolProxyQueryHandler(this);
|
||||
rv = pps->AsyncResolve(fakeHttpsLocation,
|
||||
nsIProtocolProxyService::RESOLVE_PREFER_HTTPS_PROXY |
|
||||
nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL,
|
||||
handler, getter_AddRefs(mProxyRequest));
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "%s: Failed to resolve protocol proxy: %d", __FUNCTION__, (int)rv);
|
||||
return;
|
||||
}
|
||||
mSTSThread(mParent->GetSTSThread()) {
|
||||
}
|
||||
|
||||
nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_servers,
|
||||
@ -381,8 +303,12 @@ PeerConnectionMedia::UpdateTransports(const mozilla::JsepSession& session) {
|
||||
|
||||
// TODO(bug 1017888): Need to deal properly with renegotatiation.
|
||||
// For now just start gathering.
|
||||
mTransportsUpdated = true;
|
||||
GatherIfReady();
|
||||
RUN_ON_THREAD(GetSTSThread(),
|
||||
WrapRunnable(
|
||||
RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::EnsureIceGathering_s),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
}
|
||||
|
||||
nsresult PeerConnectionMedia::UpdateMediaPipelines(
|
||||
@ -537,23 +463,9 @@ PeerConnectionMedia::AddIceCandidate_s(const std::string& aCandidate,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::GatherIfReady() {
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
|
||||
if (mTransportsUpdated && mProxyResolveCompleted) {
|
||||
RUN_ON_THREAD(GetSTSThread(),
|
||||
WrapRunnable(
|
||||
RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::EnsureIceGathering_s),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::EnsureIceGathering_s() {
|
||||
if (mIceCtx->gathering_state() == NrIceCtx::ICE_CTX_GATHER_INIT) {
|
||||
mIceCtx->SetProxyServer(mProxyServer);
|
||||
mIceCtx->StartGathering();
|
||||
}
|
||||
}
|
||||
@ -732,10 +644,6 @@ PeerConnectionMedia::SelfDestruct()
|
||||
mRemoteSourceStreams[i]->DetachMedia_m();
|
||||
}
|
||||
|
||||
// Make sure we don't try to start gathering if our http proxy lookup hasn't
|
||||
// finished yet.
|
||||
mProxyResolveCompleted = false;
|
||||
|
||||
// Shutdown the transport (async)
|
||||
RUN_ON_THREAD(mSTSThread, WrapRunnable(
|
||||
this, &PeerConnectionMedia::ShutdownMediaTransport_s),
|
||||
@ -750,11 +658,6 @@ PeerConnectionMedia::SelfDestruct_m()
|
||||
CSFLogDebug(logTag, "%s: ", __FUNCTION__);
|
||||
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
|
||||
if (mProxyRequest) {
|
||||
mProxyRequest->Cancel(NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
mLocalSourceStreams.Clear();
|
||||
mRemoteSourceStreams.Clear();
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIProtocolProxyCallback.h"
|
||||
|
||||
#ifdef USE_FAKE_MEDIA_STREAMS
|
||||
#include "FakeMediaStreams.h"
|
||||
@ -435,19 +434,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
SignalEndOfLocalCandidates;
|
||||
|
||||
private:
|
||||
class ProtocolProxyQueryHandler : public nsIProtocolProxyCallback {
|
||||
public:
|
||||
explicit ProtocolProxyQueryHandler(PeerConnectionMedia *pcm) :
|
||||
pcm_(pcm) {}
|
||||
|
||||
NS_IMETHODIMP OnProxyAvailable(nsICancelable *request, nsIURI *uri, nsIProxyInfo *proxyinfo, nsresult result) MOZ_OVERRIDE;
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
private:
|
||||
PeerConnectionMedia *pcm_;
|
||||
virtual ~ProtocolProxyQueryHandler() {}
|
||||
};
|
||||
|
||||
// Shutdown media transport. Must be called on STS thread.
|
||||
void ShutdownMediaTransport_s();
|
||||
|
||||
@ -461,7 +447,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
const std::string& aUfrag,
|
||||
const std::string& aPassword,
|
||||
const std::vector<std::string>& aCandidateList);
|
||||
void GatherIfReady();
|
||||
void EnsureIceGathering_s();
|
||||
void StartIceChecks_s(bool aIsControlling,
|
||||
bool aIsIceLite,
|
||||
@ -535,18 +520,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
// The STS thread.
|
||||
nsCOMPtr<nsIEventTarget> mSTSThread;
|
||||
|
||||
// Used to track when transports are updated and are ready to start gathering
|
||||
bool mTransportsUpdated;
|
||||
|
||||
// Used to cancel any ongoing proxy request.
|
||||
nsCOMPtr<nsICancelable> mProxyRequest;
|
||||
|
||||
// Used to track the state of the request.
|
||||
bool mProxyResolveCompleted;
|
||||
|
||||
// Used to store the result of the request.
|
||||
NrIceProxyServer mProxyServer;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PeerConnectionMedia)
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user