зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
7caef754ab
Коммит
eedd56c941
|
@ -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: */
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* 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,
|
* 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 "nsComponentManagerUtils.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "ScopedNSSTypes.h"
|
#include "ScopedNSSTypes.h"
|
||||||
#include "runnable_utils.h"
|
|
||||||
|
|
||||||
// nICEr includes
|
// nICEr includes
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -75,7 +74,6 @@ extern "C" {
|
||||||
#include "nr_crypto.h"
|
#include "nr_crypto.h"
|
||||||
#include "nr_socket.h"
|
#include "nr_socket.h"
|
||||||
#include "nr_socket_local.h"
|
#include "nr_socket_local.h"
|
||||||
#include "nr_proxy_tunnel.h"
|
|
||||||
#include "stun_client_ctx.h"
|
#include "stun_client_ctx.h"
|
||||||
#include "stun_reg.h"
|
#include "stun_reg.h"
|
||||||
#include "stun_server_ctx.h"
|
#include "stun_server_ctx.h"
|
||||||
|
@ -200,6 +198,9 @@ static nr_ice_crypto_vtbl nr_ice_crypto_nss_vtbl = {
|
||||||
nr_crypto_nss_md5
|
nr_crypto_nss_md5
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nsresult NrIceStunServer::ToNicerStunStruct(nr_ice_stun_server *server,
|
nsresult NrIceStunServer::ToNicerStunStruct(nr_ice_stun_server *server,
|
||||||
const std::string &transport) const {
|
const std::string &transport) const {
|
||||||
int r;
|
int r;
|
||||||
|
@ -626,48 +627,7 @@ nsresult NrIceCtx::SetResolver(nr_resolver *resolver) {
|
||||||
return NS_OK;
|
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() {
|
nsresult NrIceCtx::StartGathering() {
|
||||||
ASSERT_ON_THREAD(sts_target_);
|
|
||||||
MOZ_ASSERT(ctx_->state == ICE_CTX_INIT);
|
MOZ_ASSERT(ctx_->state == ICE_CTX_INIT);
|
||||||
if (ctx_->state != ICE_CTX_INIT) {
|
if (ctx_->state != ICE_CTX_INIT) {
|
||||||
MOZ_MTLOG(ML_ERROR, "ICE ctx in the wrong state for gathering: '"
|
MOZ_MTLOG(ML_ERROR, "ICE ctx in the wrong state for gathering: '"
|
||||||
|
@ -676,7 +636,8 @@ nsresult NrIceCtx::StartGathering() {
|
||||||
return NS_ERROR_FAILURE;
|
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) {
|
if (r && r != R_WOULDBLOCK) {
|
||||||
MOZ_MTLOG(ML_ERROR, "Couldn't gather ICE candidates for '"
|
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_stun_server_ nr_ice_stun_server;
|
||||||
typedef struct nr_ice_turn_server_ nr_ice_turn_server;
|
typedef struct nr_ice_turn_server_ nr_ice_turn_server;
|
||||||
typedef struct nr_resolver_ nr_resolver;
|
typedef struct nr_resolver_ nr_resolver;
|
||||||
typedef struct nr_proxy_tunnel_config_ nr_proxy_tunnel_config;
|
|
||||||
|
|
||||||
typedef void* NR_SOCKET;
|
typedef void* NR_SOCKET;
|
||||||
|
|
||||||
|
@ -172,33 +171,6 @@ class NrIceTurnServer : public NrIceStunServer {
|
||||||
std::string transport_;
|
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 {
|
class NrIceCtx {
|
||||||
public:
|
public:
|
||||||
enum ConnectionState { ICE_CTX_INIT,
|
enum ConnectionState { ICE_CTX_INIT,
|
||||||
|
@ -282,10 +254,6 @@ class NrIceCtx {
|
||||||
// StartGathering.
|
// StartGathering.
|
||||||
nsresult SetResolver(nr_resolver *resolver);
|
nsresult SetResolver(nr_resolver *resolver);
|
||||||
|
|
||||||
// Provide the proxy address. Must be called before
|
|
||||||
// StartGathering.
|
|
||||||
nsresult SetProxyServer(const NrIceProxyServer& proxy_server);
|
|
||||||
|
|
||||||
// Start ICE gathering
|
// Start ICE gathering
|
||||||
nsresult StartGathering();
|
nsresult StartGathering();
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ extern "C" {
|
||||||
|
|
||||||
#include "databuffer.h"
|
#include "databuffer.h"
|
||||||
#include "mtransport_test_utils.h"
|
#include "mtransport_test_utils.h"
|
||||||
#include "dummysocket.h"
|
|
||||||
|
|
||||||
#include "nr_socket_prsock.h"
|
#include "nr_socket_prsock.h"
|
||||||
|
|
||||||
|
@ -43,6 +42,173 @@ static uint8_t kStunMessage[] = {
|
||||||
};
|
};
|
||||||
static size_t kStunMessageLen = sizeof(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 {
|
class BufferedStunSocketTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
BufferedStunSocketTest()
|
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',
|
'buffered_stun_socket_unittest',
|
||||||
'ice_unittest',
|
'ice_unittest',
|
||||||
'nrappkit_unittest',
|
'nrappkit_unittest',
|
||||||
'proxy_tunnel_socket_unittest',
|
|
||||||
'rlogringbuffer_unittest',
|
'rlogringbuffer_unittest',
|
||||||
'runnable_utils_unittest',
|
'runnable_utils_unittest',
|
||||||
'simpletokenbucket_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;
|
|
||||||
}
|
|
|
@ -66,10 +66,6 @@
|
||||||
# Net
|
# Net
|
||||||
"./src/net/nr_resolver.c",
|
"./src/net/nr_resolver.c",
|
||||||
"./src/net/nr_resolver.h",
|
"./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.c",
|
||||||
"./src/net/nr_socket.h",
|
"./src/net/nr_socket.h",
|
||||||
#"./src/net/nr_socket_local.c",
|
#"./src/net/nr_socket_local.c",
|
||||||
|
@ -121,7 +117,7 @@
|
||||||
|
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
'defines' : [
|
'defines' : [
|
||||||
'SANITY_CHECKS',
|
'SANITY_CHECKS',
|
||||||
'USE_TURN',
|
'USE_TURN',
|
||||||
|
@ -140,7 +136,7 @@
|
||||||
'R_DEFINED_INT8=int64_t',
|
'R_DEFINED_INT8=int64_t',
|
||||||
'R_DEFINED_UINT8=uint64_t',
|
'R_DEFINED_UINT8=uint64_t',
|
||||||
],
|
],
|
||||||
|
|
||||||
'conditions' : [
|
'conditions' : [
|
||||||
## Mac and BSDs
|
## Mac and BSDs
|
||||||
[ 'OS == "mac"', {
|
[ 'OS == "mac"', {
|
||||||
|
@ -176,11 +172,11 @@
|
||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
'../nrappkit/src/port/darwin/include'
|
'../nrappkit/src/port/darwin/include'
|
||||||
],
|
],
|
||||||
|
|
||||||
'sources': [
|
'sources': [
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
|
|
||||||
## Win
|
## Win
|
||||||
[ 'OS == "win"', {
|
[ 'OS == "win"', {
|
||||||
'defines' : [
|
'defines' : [
|
||||||
|
@ -224,7 +220,7 @@
|
||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
'../nrappkit/src/port/linux/include'
|
'../nrappkit/src/port/linux/include'
|
||||||
],
|
],
|
||||||
|
|
||||||
'sources': [
|
'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 "stun.h"
|
||||||
#include "nr_socket_local.h"
|
#include "nr_socket_local.h"
|
||||||
#include "nr_socket_turn.h"
|
#include "nr_socket_turn.h"
|
||||||
#include "nr_socket_wrapper.h"
|
|
||||||
#include "nr_socket_buffered_stun.h"
|
#include "nr_socket_buffered_stun.h"
|
||||||
#include "ice_reg.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];
|
char label[256];
|
||||||
int r,_status;
|
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 */
|
/* Create a new relayed candidate for each addr/TURN server pair */
|
||||||
for(i=0;i<addr_ct;i++){
|
for(i=0;i<addr_ct;i++){
|
||||||
char suppress;
|
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);
|
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): couldn't create socket for address %s",ctx->label,addr.as_string);
|
||||||
continue;
|
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 */
|
/* Wrap it */
|
||||||
if((r=nr_socket_buffered_stun_create(sock, NR_STUN_MAX_MESSAGE_SIZE, &buffered_sock)))
|
if((r=nr_socket_buffered_stun_create(sock, NR_STUN_MAX_MESSAGE_SIZE, &buffered_sock)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
|
@ -214,21 +214,6 @@ int nr_ice_ctx_set_interface_prioritizer(nr_ice_ctx *ctx, nr_interface_prioritiz
|
||||||
return(_status);
|
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
|
#ifdef USE_TURN
|
||||||
int nr_ice_fetch_turn_servers(int ct, nr_ice_turn_server **out)
|
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_resolver_destroy(&ctx->resolver);
|
||||||
nr_interface_prioritizer_destroy(&ctx->interface_prioritizer);
|
nr_interface_prioritizer_destroy(&ctx->interface_prioritizer);
|
||||||
nr_socket_wrapper_factory_destroy(&ctx->turn_tcp_socket_wrapper);
|
|
||||||
|
|
||||||
RFREE(ctx);
|
RFREE(ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,6 @@ extern "C" {
|
||||||
#include "nr_socket.h"
|
#include "nr_socket.h"
|
||||||
#include "nr_resolver.h"
|
#include "nr_resolver.h"
|
||||||
#include "nr_interface_prioritizer.h"
|
#include "nr_interface_prioritizer.h"
|
||||||
#include "nr_socket_wrapper.h"
|
|
||||||
#include "stun_client_ctx.h"
|
#include "stun_client_ctx.h"
|
||||||
#include "stun_server_ctx.h"
|
#include "stun_server_ctx.h"
|
||||||
#include "turn_client_ctx.h"
|
#include "turn_client_ctx.h"
|
||||||
|
@ -133,7 +132,6 @@ struct nr_ice_ctx_ {
|
||||||
|
|
||||||
nr_resolver *resolver; /* The resolver to use */
|
nr_resolver *resolver; /* The resolver to use */
|
||||||
nr_interface_prioritizer *interface_prioritizer; /* Priority decision logic */
|
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;
|
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_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_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_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);
|
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
|
#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/JsepSession.h"
|
||||||
#include "signaling/src/jsep/JsepTransport.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
|
#ifdef MOZILLA_INTERNAL_API
|
||||||
#include "MediaStreamList.h"
|
#include "MediaStreamList.h"
|
||||||
#include "nsIScriptGlobalObject.h"
|
#include "nsIScriptGlobalObject.h"
|
||||||
|
@ -204,48 +198,6 @@ PeerConnectionImpl* PeerConnectionImpl::CreatePeerConnection()
|
||||||
return pc;
|
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)
|
PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent)
|
||||||
: mParent(parent),
|
: mParent(parent),
|
||||||
|
@ -256,37 +208,7 @@ PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent)
|
||||||
mDNSResolver(new mozilla::NrIceResolver()),
|
mDNSResolver(new mozilla::NrIceResolver()),
|
||||||
mUuidGen(MakeUnique<PCUuidGenerator>()),
|
mUuidGen(MakeUnique<PCUuidGenerator>()),
|
||||||
mMainThread(mParent->GetMainThread()),
|
mMainThread(mParent->GetMainThread()),
|
||||||
mSTSThread(mParent->GetSTSThread()),
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_servers,
|
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.
|
// TODO(bug 1017888): Need to deal properly with renegotatiation.
|
||||||
// For now just start gathering.
|
// For now just start gathering.
|
||||||
mTransportsUpdated = true;
|
RUN_ON_THREAD(GetSTSThread(),
|
||||||
GatherIfReady();
|
WrapRunnable(
|
||||||
|
RefPtr<PeerConnectionMedia>(this),
|
||||||
|
&PeerConnectionMedia::EnsureIceGathering_s),
|
||||||
|
NS_DISPATCH_NORMAL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult PeerConnectionMedia::UpdateMediaPipelines(
|
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
|
void
|
||||||
PeerConnectionMedia::EnsureIceGathering_s() {
|
PeerConnectionMedia::EnsureIceGathering_s() {
|
||||||
if (mIceCtx->gathering_state() == NrIceCtx::ICE_CTX_GATHER_INIT) {
|
if (mIceCtx->gathering_state() == NrIceCtx::ICE_CTX_GATHER_INIT) {
|
||||||
mIceCtx->SetProxyServer(mProxyServer);
|
|
||||||
mIceCtx->StartGathering();
|
mIceCtx->StartGathering();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -732,10 +644,6 @@ PeerConnectionMedia::SelfDestruct()
|
||||||
mRemoteSourceStreams[i]->DetachMedia_m();
|
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)
|
// Shutdown the transport (async)
|
||||||
RUN_ON_THREAD(mSTSThread, WrapRunnable(
|
RUN_ON_THREAD(mSTSThread, WrapRunnable(
|
||||||
this, &PeerConnectionMedia::ShutdownMediaTransport_s),
|
this, &PeerConnectionMedia::ShutdownMediaTransport_s),
|
||||||
|
@ -750,11 +658,6 @@ PeerConnectionMedia::SelfDestruct_m()
|
||||||
CSFLogDebug(logTag, "%s: ", __FUNCTION__);
|
CSFLogDebug(logTag, "%s: ", __FUNCTION__);
|
||||||
|
|
||||||
ASSERT_ON_THREAD(mMainThread);
|
ASSERT_ON_THREAD(mMainThread);
|
||||||
|
|
||||||
if (mProxyRequest) {
|
|
||||||
mProxyRequest->Cancel(NS_ERROR_ABORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
mLocalSourceStreams.Clear();
|
mLocalSourceStreams.Clear();
|
||||||
mRemoteSourceStreams.Clear();
|
mRemoteSourceStreams.Clear();
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
#include "nsIProtocolProxyCallback.h"
|
|
||||||
|
|
||||||
#ifdef USE_FAKE_MEDIA_STREAMS
|
#ifdef USE_FAKE_MEDIA_STREAMS
|
||||||
#include "FakeMediaStreams.h"
|
#include "FakeMediaStreams.h"
|
||||||
|
@ -435,19 +434,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||||
SignalEndOfLocalCandidates;
|
SignalEndOfLocalCandidates;
|
||||||
|
|
||||||
private:
|
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.
|
// Shutdown media transport. Must be called on STS thread.
|
||||||
void ShutdownMediaTransport_s();
|
void ShutdownMediaTransport_s();
|
||||||
|
|
||||||
|
@ -461,7 +447,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||||
const std::string& aUfrag,
|
const std::string& aUfrag,
|
||||||
const std::string& aPassword,
|
const std::string& aPassword,
|
||||||
const std::vector<std::string>& aCandidateList);
|
const std::vector<std::string>& aCandidateList);
|
||||||
void GatherIfReady();
|
|
||||||
void EnsureIceGathering_s();
|
void EnsureIceGathering_s();
|
||||||
void StartIceChecks_s(bool aIsControlling,
|
void StartIceChecks_s(bool aIsControlling,
|
||||||
bool aIsIceLite,
|
bool aIsIceLite,
|
||||||
|
@ -535,18 +520,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||||
// The STS thread.
|
// The STS thread.
|
||||||
nsCOMPtr<nsIEventTarget> mSTSThread;
|
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)
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PeerConnectionMedia)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче