diff --git a/CMakeLists.txt b/CMakeLists.txt
index 806c66571..868b4670d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,6 +2,7 @@ if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Android")
# CMAKE_ANDROID_STANDALONE_TOOLCHAIN (and likely other cross compilation
# android variables) was only introduced in v3.7
cmake_minimum_required (VERSION 3.7)
+ add_definitions(-DANDROID) # for i2pd
else()
cmake_minimum_required (VERSION 3.5)
endif()
@@ -39,23 +40,10 @@ add_definitions(-DBOOST_COROUTINE_NO_DEPRECATION_WARNING)
# https://www.boost.org/doc/libs/1_67_0/doc/html/boost_asio/using.html#boost_asio.using.optional_separate_compilation
add_definitions(-DBOOST_ASIO_SEPARATE_COMPILATION)
-################################################################################
-
-set(GOROOT "${CMAKE_BINARY_DIR}/golang")
-externalproject_add(golang
- URL https://dl.google.com/go/go1.11.2.linux-amd64.tar.gz
- URL_MD5 5630231012b6d02b821af51f04c2776c
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ""
- INSTALL_COMMAND ""
- SOURCE_DIR ${GOROOT}
-)
-
################################################################################
option(ASIO_IPFS_WITH_EXAMPLE_BINARIES "" OFF)
add_subdirectory(./modules/asio-ipfs)
-add_subdirectory(./modules/obfs4proxy)
add_subdirectory(./src/ouiservice/i2p)
################################################################################
@@ -162,12 +150,8 @@ file(GLOB client_sources
"./src/ouiservice.cpp"
"./src/ssl/ca_certificate.cpp"
"./src/ssl/dummy_certificate.cpp"
- "./src/ouiservice/pt-obfs2.cpp"
- "./src/ouiservice/pt-obfs3.cpp"
- "./src/ouiservice/pt-obfs4.cpp"
"./src/ouiservice/tcp.cpp"
"./src/ouiservice/tls.cpp"
- "./src/ouiservice/pluggable-transports/*.cpp"
"./src/logger.cpp"
"./src/cache/*.cpp"
"./src/bittorrent/*.cpp"
@@ -214,12 +198,8 @@ if (WITH_INJECTOR)
"./src/connect_to_host.cpp"
"./src/cache_control.cpp"
"./src/ouiservice.cpp"
- "./src/ouiservice/pt-obfs2.cpp"
- "./src/ouiservice/pt-obfs3.cpp"
- "./src/ouiservice/pt-obfs4.cpp"
"./src/ouiservice/tcp.cpp"
"./src/ouiservice/tls.cpp"
- "./src/ouiservice/pluggable-transports/*.cpp"
"./src/ssl/ca_certificate.cpp"
"./src/logger.cpp"
"./src/cache/*.cpp"
diff --git a/android/browser/src/main/AndroidManifest.xml b/android/browser/src/main/AndroidManifest.xml
index 1869033a9..65149bfd9 100644
--- a/android/browser/src/main/AndroidManifest.xml
+++ b/android/browser/src/main/AndroidManifest.xml
@@ -26,4 +26,6 @@
+
+
diff --git a/android/ouinet/build.gradle b/android/ouinet/build.gradle
index 53cd54d0c..dc914a118 100644
--- a/android/ouinet/build.gradle
+++ b/android/ouinet/build.gradle
@@ -23,9 +23,7 @@ android {
sourceSets {
main {
jniLibs.srcDirs = ["$libdir"]
- assets.srcDirs = ["$assetsdir"]
}
-
}
buildTypes {
release {
diff --git a/android/ouinet/src/main/cpp/native-lib.cpp b/android/ouinet/src/main/cpp/native-lib.cpp
index ac6867feb..587d20c86 100644
--- a/android/ouinet/src/main/cpp/native-lib.cpp
+++ b/android/ouinet/src/main/cpp/native-lib.cpp
@@ -15,7 +15,6 @@
#include
#include
-#include
#include
#include "debug.h"
@@ -36,40 +35,13 @@ ouinet::asio::io_service g_ios;
thread g_client_thread;
bool g_crypto_initialized = false;
-void start_client_thread(const vector& args, const vector& extra_path)
+void start_client_thread(const vector& args)
{
if (g_crypto_initialized) {
ouinet::util::crypto_init();
g_crypto_initialized = true;
}
- char* old_path_c = getenv("PATH");
- if (old_path_c) {
- std::string old_path(old_path_c);
- std::set old_path_entries;
- size_t index = 0;
- while (true) {
- size_t pos = old_path.find(':', index);
- if (pos == std::string::npos) {
- old_path_entries.insert(old_path.substr(index));
- break;
- } else {
- old_path_entries.insert(old_path.substr(index, pos - index));
- index = pos;
- }
- }
-
- std::string new_path;
- for (size_t i = 0; i < extra_path.size(); i++) {
- if (!old_path_entries.count(extra_path[i])) {
- new_path += extra_path[i];
- new_path += ":";
- }
- }
- new_path += old_path;
- setenv("PATH", new_path.c_str(), 1);
- }
-
if (g_client_thread.get_id() != thread::id()) return;
g_client_thread = thread([=] {
@@ -112,10 +84,10 @@ JNIEXPORT void JNICALL
Java_ie_equalit_ouinet_Ouinet_nStartClient(
JNIEnv* env,
jobject /* this */,
- jobjectArray jargs,
- jobjectArray jpath)
+ jobjectArray jargs)
{
size_t argn = env->GetArrayLength(jargs);
+
vector args;
args.reserve(argn);
@@ -126,19 +98,7 @@ Java_ie_equalit_ouinet_Ouinet_nStartClient(
env->ReleaseStringUTFChars(jstr, arg);
}
-
- size_t pathn = env->GetArrayLength(jpath);
- vector path;
- path.reserve(pathn);
-
- for (size_t i = 0; i < pathn; ++i) {
- jstring jstr = (jstring) env->GetObjectArrayElement(jpath, i);
- const char* dir = env->GetStringUTFChars(jstr, 0);
- path.push_back(dir);
- env->ReleaseStringUTFChars(jstr, dir);
- }
-
- start_client_thread(args, path);
+ start_client_thread(args);
}
extern "C"
diff --git a/android/ouinet/src/main/java/ie/equalit/ouinet/Ouinet.java b/android/ouinet/src/main/java/ie/equalit/ouinet/Ouinet.java
index f46f1e3e5..ad1c4047c 100644
--- a/android/ouinet/src/main/java/ie/equalit/ouinet/Ouinet.java
+++ b/android/ouinet/src/main/java/ie/equalit/ouinet/Ouinet.java
@@ -23,7 +23,7 @@ public class Ouinet {
System.setProperty("https.proxyHost", "127.0.0.1");
System.setProperty("https.proxyPort", "8080");
}
- private static final String TAG = "Ouinet";
+
private Context _ctx;
private WifiManager.MulticastLock _lock = null;
@@ -41,9 +41,7 @@ public static class Config {
public Ouinet(Context ctx, Config conf) {
_ctx = ctx;
- List args = new ArrayList();
- List path = new ArrayList();
-
+ Vector args = new Vector();
new File(dir()).mkdirs();
@@ -52,13 +50,14 @@ public Ouinet(Context ctx, Config conf) {
// repository and fails if this conf file isn't there.
new File(dir() + "/ouinet-client.conf").createNewFile();
} catch (IOException e) {
- Log.d(TAG, "Exception thrown while creating ouinet config file: ", e);
+ Log.d("Ouinet",
+ "Exception thrown while creating ouinet config file: " + e);
}
- args.add("ouinet-client"); // App name
- args.add("--repo=" + dir());
- args.add("--listen-on-tcp=127.0.0.1:8080");
- args.add("--front-end-ep=0.0.0.0:8081");
+ args.addElement("ouinet-client"); // App name
+ args.addElement("--repo=" + dir());
+ args.addElement("--listen-on-tcp=127.0.0.1:8080");
+ args.addElement("--front-end-ep=0.0.0.0:8081");
maybeAdd(args, "--injector-ep", conf.injector_endpoint);
maybeAdd(args, "--injector-credentials", conf.injector_credentials);
@@ -77,7 +76,7 @@ public Ouinet(Context ctx, Config conf) {
String asset = conf.tls_ca_cert_store_path.substring(assetPrefix.length());
ca_cert_path = dir() + "/assets/" + asset;
- if (copyAssetToFile(asset, ca_cert_path)) {
+ if (copyAssetToFile(ctx, asset, ca_cert_path)) {
maybeAdd(args, "--tls-ca-cert-store-path", ca_cert_path);
}
}
@@ -90,21 +89,15 @@ public Ouinet(Context ctx, Config conf) {
if (conf.injector_tls_cert != null) {
String cert_path = dir() + "/injector-tls-cert.pem";
writeToFile(cert_path, conf.injector_tls_cert.getBytes());
- args.add("--injector-tls-cert-file=" + cert_path);
+ args.addElement("--injector-tls-cert-file=" + cert_path);
}
} catch (IOException e) {
- Log.d(TAG, "Exception thrown while creating injector's cert file: ", e);
- }
-
- String objfs4proxy_path = dir() + "/objfs4proxy";
- if (copyExecutableToFile("obfs4proxy", objfs4proxy_path)) {
- Log.d(TAG, "objfs4proxy copied to " + objfs4proxy_path);
- path.add(dir());
- } else {
- Log.d(TAG, "objfs4proxy not copied");
+ Log.d("Ouinet",
+ "Exception thrown while creating injector's cert file: " + e);
+ e.printStackTrace();
}
- nStartClient(args.toArray(new String[0]), path.toArray(new String[0]));
+ nStartClient(listToArray(args));
}
public String pathToCARootCert()
@@ -112,35 +105,24 @@ public String pathToCARootCert()
return nPathToCARootCert();
}
- public boolean copyAssetToFile(String asset, String path)
+ public boolean copyAssetToFile(Context ctx, String asset, String path)
{
try {
- java.io.InputStream stream = _ctx.getAssets().open(asset);
+ java.io.InputStream stream = ctx.getAssets().open(asset);
int size = stream.available();
byte[] buffer = new byte[size];
stream.read(buffer);
stream.close();
writeToFile(path, buffer);
} catch (IOException e) {
- Log.d(TAG, "Failed to write asset \"" + asset + "\" to file \"" + path + "\"", e);
+ Log.d("Ouinet", "Failed to write asset \"" + asset + "\" to file \"" + path + "\"");
+ e.printStackTrace();
return false;
}
return true;
}
- public boolean copyExecutableToFile(String asset, String path) {
- if (!copyAssetToFile(asset, path)) {
- return false;
- }
- File executable = new File(path);
- if (!executable.setExecutable(true)) {
- Log.d(TAG, "Failed to set executable for file: " + path);
- return false;
- }
- return true;
- }
-
// If this succeeds, we should be able to do UDP multicasts
// from inside ouinet (currently know to be needed by IPFS' mDNS
// but that's not essential for WAN).
@@ -188,9 +170,16 @@ public void setCredentialsFor(String injector, String credentials) {
}
//----------------------------------------------------------------
- private void maybeAdd(List args, String key, String value) {
+ private String[] listToArray(List list) {
+ String[] ret = new String[list.size()];
+ int i = 0;
+ for (String s : list) { ret[i] = s; i += 1; }
+ return ret;
+ }
+
+ private void maybeAdd(Vector args, String key, String value) {
if (value == null || value.isEmpty()) return;
- args.add(key + "=" + value);
+ args.addElement(key + "=" + value);
}
private void writeToFile(String path, byte[] bytes) throws IOException {
@@ -217,7 +206,7 @@ private String dir() {
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
- private native void nStartClient(String[] args, String[] path);
+ private native void nStartClient(String[] args);
private native void nStopClient();
private native void nSetInjectorEP(String endpoint);
diff --git a/modules/asio-ipfs b/modules/asio-ipfs
index cffde1f77..1fcf2855e 160000
--- a/modules/asio-ipfs
+++ b/modules/asio-ipfs
@@ -1 +1 @@
-Subproject commit cffde1f77da95be90808e6260c34fa400802a8d1
+Subproject commit 1fcf2855ee7ca9e6cb48150d4624c2989b8bb1f1
diff --git a/modules/obfs4proxy/CMakeLists.txt b/modules/obfs4proxy/CMakeLists.txt
deleted file mode 100644
index f070b96e5..000000000
--- a/modules/obfs4proxy/CMakeLists.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-cmake_minimum_required (VERSION 3.5)
-
-include(ExternalProject)
-
-################################################################################
-project(obfs4proxy)
-
-# Convert system name into GOOS.
-if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
- set(GOOS "linux")
-elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Android")
- set(GOOS "android")
-else()
- message(FATAL_ERROR "unsupported system name ${CMAKE_SYSTEM_NAME}")
-endif()
-
-# Convert system processor into GOARCH (and maybe GOARM).
-if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
- set(GOARCH "amd64")
-elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64")
- set(GOARCH "arm64")
-elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7-a")
- set(GOARCH "arm")
- set(GOARM "7")
-elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "^arm.*")
- set(GOARCH "arm")
- set(GOARM "6")
-else()
- message(FATAL_ERROR "unsupported system processor ${CMAKE_SYSTEM_PROCESSOR}")
-endif()
-
-# Build target tag with the Android API version if relevant.
-if("${CMAKE_SYSTEM_NAME}" STREQUAL "Android")
- set(TARGET "${CMAKE_SYSTEM_NAME}${CMAKE_SYSTEM_VERSION}--${CMAKE_SYSTEM_PROCESSOR}")
-else()
- set(TARGET "${CMAKE_SYSTEM_NAME}--${CMAKE_SYSTEM_PROCESSOR}")
-endif()
-
-set(GOPATH "${CMAKE_CURRENT_BINARY_DIR}/go-workspace")
-
-#
-# Using CGO_ENABLED causes go to use the external linker shipped by the
-# android ndk. This is almost certainly the wrong way to do it, but it
-# seems to work for now.
-#
-externalproject_add(obfs4proxy
- URL https://github.com/Yawning/obfs4/archive/obfs4proxy-0.0.9.tar.gz
- URL_MD5 5ec7e4d96bf57fa0b269083076aacd02
- DEPENDS golang
- CONFIGURE_COMMAND ""
- BUILD_IN_SOURCE 1
- BUILD_COMMAND mkdir -p ${GOPATH}
- && export PATH=${GOROOT}/bin:$ENV{PATH}
- && export GOPATH=${GOPATH}
- && export GOOS=${GOOS}
- && export GOARCH=${GOARCH}
- && export GOARM=${GOARM}
- && export CC=${CMAKE_C_COMPILER}
- && export CGO_ENABLED=1
- && go build -o ${CMAKE_CURRENT_BINARY_DIR}/obfs4proxy ./obfs4proxy
- INSTALL_COMMAND ""
-)
diff --git a/scripts/build-android.sh b/scripts/build-android.sh
index e268d3d5c..261f9a98c 100755
--- a/scripts/build-android.sh
+++ b/scripts/build-android.sh
@@ -1,7 +1,6 @@
#!/bin/bash
set -e
-set -x
DIR=`pwd`
SCRIPT_DIR=$(dirname -- "$(readlink -f -- "$BASH_SOURCE")")
@@ -128,22 +127,6 @@ function add_library {
done
}
-######################################################################
-# This variable shall contain paths to generated binaries which
-# must all be included in the final Android package.
-OUT_BINARIES=()
-
-function add_binary {
- local binaries=("$@") binaries
- for binary in "${binaries[@]}"; do
- if [ ! -f "$binary" ]; then
- echo "Cannot add binary \"$binary\": File doesn't exist"
- exit 1
- fi
- OUT_BINARIES+=("$binary")
- done
-}
-
######################################################################
MODES=
ALLOWED_MODES="build emu abiclean"
@@ -299,9 +282,9 @@ function maybe_install_ndk_toolchain {
function maybe_install_gradle {
GRADLE_REQUIRED_MAJOR_VERSION=4
GRADLE_REQUIRED_MINOR_VERSION=6
-
+
NEED_GRADLE=false
-
+
if ! which gradle 1> /dev/null 2>&1; then
NEED_GRADLE=true
else
@@ -421,7 +404,6 @@ add_library $DIR/build-ouinet/libclient.so
add_library $DIR/build-ouinet/modules/asio-ipfs/ipfs_bindings/libipfs_bindings.so
add_library $DIR/build-ouinet/gcrypt/src/gcrypt/src/.libs/libgcrypt.so
add_library $DIR/build-ouinet/gpg_error/out/lib/libgpg-error.so
-add_binary $DIR/build-ouinet/modules/obfs4proxy/obfs4proxy
}
######################################################################
@@ -436,18 +418,6 @@ for lib in "${OUT_LIBS[@]}"; do
done
}
-######################################################################
-function copy_binaries {
-local binary_dst_dir="${DIR}"/build-android/builddir/assets/
-rm -rf "${binary_dst_dir}"
-mkdir -p "${binary_dst_dir}"
-local binary
-for binary in "${OUT_BINARIES[@]}"; do
- echo "Copying $binary to $binary_dst_dir"
- cp $binary $binary_dst_dir/
-done
-}
-
######################################################################
# Unpolished code to build the debug APK
function build_ouinet_apk {
@@ -459,8 +429,7 @@ gradle --no-daemon build \
-Pboost_includedir=${BOOST_INCLUDEDIR} \
-Pandroid_abi=${ABI} \
-Pouinet_clientlib_path="${DIR}"/build-android/builddir/deps/${ABI}/libclient.so \
- -Plibdir="${DIR}"/build-android/builddir/deps \
- -Passetsdir="${DIR}"/build-android/builddir/assets
+ -Plibdir="${DIR}"/build-android/builddir/deps
echo "---------------------------------"
echo "Your Android package is ready at:"
@@ -538,7 +507,6 @@ if check_mode build; then
# TODO: miniupnp
build_ouinet_libs
copy_jni_libs
- copy_binaries
build_ouinet_apk
fi
diff --git a/src/client.cpp b/src/client.cpp
index 7aa5e2aca..bf915bdd5 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -45,9 +45,6 @@
#include "ouiservice.h"
#include "ouiservice/i2p.h"
-#include "ouiservice/pt-obfs2.h"
-#include "ouiservice/pt-obfs3.h"
-#include "ouiservice/pt-obfs4.h"
#include "ouiservice/tcp.h"
#include "ouiservice/tls.h"
@@ -1402,55 +1399,28 @@ void Client::State::setup_injector(asio::yield_context yield)
cout << "Setting up injector: " << *injector_ep << endl;
- std::unique_ptr client;
-
- if (injector_ep->type == Endpoint::I2pEndpoint) {
+ if (is_i2p_endpoint(*injector_ep)) {
+ std::string ep = boost::get(*injector_ep).pubkey;
auto i2p_service = make_shared((_config.repo_root()/"i2p").string(), _ios);
- auto i2p_client = i2p_service->build_client(injector_ep->endpoint_string);
-
- /*
- if (!i2p_client->verify_endpoint()) {
- return or_throw(yield, asio::error::invalid_argument);
- }
- */
- client = std::move(i2p_client);
- } else if (injector_ep->type == Endpoint::TcpEndpoint) {
- auto tcp_client = make_unique(_ios, injector_ep->endpoint_string);
+ std::unique_ptr i2p_client = i2p_service->build_client(ep);
- if (!tcp_client->verify_endpoint()) {
- return or_throw(yield, asio::error::invalid_argument);
- }
- client = std::move(tcp_client);
- } else if (injector_ep->type == Endpoint::Obfs2Endpoint) {
- auto obfs2_client = make_unique(_ios, injector_ep->endpoint_string, _config.repo_root()/"obfs2-client");
+ _injector->add(std::move(i2p_client));
+ } else {
+ tcp::endpoint tcp_endpoint
+ = boost::get(*injector_ep);
- if (!obfs2_client->verify_endpoint()) {
- return or_throw(yield, asio::error::invalid_argument);
- }
- client = std::move(obfs2_client);
- } else if (injector_ep->type == Endpoint::Obfs3Endpoint) {
- auto obfs3_client = make_unique(_ios, injector_ep->endpoint_string, _config.repo_root()/"obfs3-client");
+ auto tcp_client
+ = make_unique(_ios, tcp_endpoint);
- if (!obfs3_client->verify_endpoint()) {
- return or_throw(yield, asio::error::invalid_argument);
- }
- client = std::move(obfs3_client);
- } else if (injector_ep->type == Endpoint::Obfs4Endpoint) {
- auto obfs4_client = make_unique(_ios, injector_ep->endpoint_string, _config.repo_root()/"obfs4-client");
+ bool enable_injector_tls = !_config.tls_injector_cert_path().empty();
- if (!obfs4_client->verify_endpoint()) {
- return or_throw(yield, asio::error::invalid_argument);
+ if (!enable_injector_tls) {
+ _injector->add(std::move(tcp_client));
+ } else {
+ auto tls_client
+ = make_unique(move(tcp_client), inj_ctx);
+ _injector->add(std::move(tls_client));
}
- client = std::move(obfs4_client);
- }
-
- bool enable_injector_tls = !_config.tls_injector_cert_path().empty();
- if (!enable_injector_tls) {
- _injector->add(std::move(client));
- } else {
- auto tls_client
- = make_unique(move(client), inj_ctx);
- _injector->add(std::move(tls_client));
}
_injector->start(yield);
@@ -1478,14 +1448,10 @@ void Client::State::set_injector(string injector_ep_str)
_config.set_injector_endpoint(*injector_ep);
- asio::spawn(_ios, [self = shared_from_this(), injector_ep_str] (auto yield) {
+ asio::spawn(_ios, [self = shared_from_this()] (auto yield) {
if (self->was_stopped()) return;
sys::error_code ec;
self->setup_injector(yield[ec]);
-
- if (ec == asio::error::invalid_argument) {
- cerr << "Failed to parse endpoint \"" << injector_ep_str << "\"" << endl;
- }
});
}
diff --git a/src/client_front_end.h b/src/client_front_end.h
index 3c6dc04fd..00fc2bbc9 100644
--- a/src/client_front_end.h
+++ b/src/client_front_end.h
@@ -6,6 +6,7 @@
#include
#include
#include "namespaces.h"
+#include "endpoint.h"
#include "ssl/ca_certificate.h"
namespace ouinet { class CacheClient; }
diff --git a/src/endpoint.cpp b/src/endpoint.cpp
index ec826c2ce..db5a9929f 100644
--- a/src/endpoint.cpp
+++ b/src/endpoint.cpp
@@ -2,58 +2,40 @@
namespace ouinet {
-boost::optional parse_endpoint(beast::string_view endpoint)
-{
- size_t pos = endpoint.find(':');
- if (pos == std::string::npos) {
- return boost::none;
- }
- beast::string_view type = endpoint.substr(0, pos);
- Endpoint output;
- output.endpoint_string = endpoint.substr(pos + 1).to_string();
-
- if (type == "tcp") {
- output.type = Endpoint::TcpEndpoint;
- } else if (type == "i2p") {
- output.type = Endpoint::I2pEndpoint;
#ifdef USE_GNUNET
- } else if (type == "gnunet") {
- output.type = Endpoint::GnunetEndpoint;
+std::ostream& operator<<(std::ostream& os, const GnunetEndpoint& ep)
+{
+ return os << ep.host << ":" << ep.port;
+}
#endif
- } else if (type == "obfs2") {
- output.type = Endpoint::Obfs2Endpoint;
- } else if (type == "obfs3") {
- output.type = Endpoint::Obfs3Endpoint;
- } else if (type == "obfs4") {
- output.type = Endpoint::Obfs4Endpoint;
- } else {
- return boost::none;
- }
- return output;
+
+std::ostream& operator<<(std::ostream& os, const I2PEndpoint& ep)
+{
+ return os << ep.pubkey;
}
std::ostream& operator<<(std::ostream& os, const Endpoint& ep)
{
- if (ep.type == Endpoint::TcpEndpoint) {
- os << "tcp";
- } else if (ep.type == Endpoint::I2pEndpoint) {
- os << "i2p";
+ struct Visitor {
+ std::ostream& os;
+
+ void operator()(const asio::ip::tcp::endpoint& ep) {
+ os << ep;
+ }
+
#ifdef USE_GNUNET
- } else if (ep.type == Endpoint::GnunetEndpoint) {
- os << "i2p";
+ void operator()(const GnunetEndpoint& ep) {
+ os << ep;
+ }
#endif
- } else if (ep.type == Endpoint::Obfs2Endpoint) {
- os << "obfs2";
- } else if (ep.type == Endpoint::Obfs3Endpoint) {
- os << "obfs3";
- } else if (ep.type == Endpoint::Obfs4Endpoint) {
- os << "obfs4";
- } else {
- assert(false);
- }
-
- os << ":";
- os << ep.endpoint_string;
+
+ void operator()(const I2PEndpoint& ep) {
+ os << ep;
+ }
+ };
+
+ Visitor visitor{os};
+ boost::apply_visitor(visitor, ep);
return os;
}
diff --git a/src/endpoint.h b/src/endpoint.h
index dc0eee57a..a8e1bd999 100644
--- a/src/endpoint.h
+++ b/src/endpoint.h
@@ -7,28 +7,57 @@
namespace ouinet {
-struct Endpoint {
- enum Type {
- TcpEndpoint,
- I2pEndpoint,
-#ifdef USE_GNUNET
- GnunetEndpoint,
-#endif
- Obfs2Endpoint,
- Obfs3Endpoint,
- Obfs4Endpoint
+struct I2PEndpoint {
+ std::string pubkey;
+
+ bool operator==(const I2PEndpoint& other) const {
+ return pubkey == other.pubkey;
+ }
+};
+
+using Endpoint = boost::variant< asio::ip::tcp::endpoint
+ , I2PEndpoint>;
+
+inline
+boost::optional parse_endpoint(beast::string_view endpoint)
+{
+ using std::string;
+ using beast::string_view;
+ using asio::ip::tcp;
+
+ auto as_tcp_endpoint = []( string_view host
+ , string_view port
+ ) -> boost::optional {
+ sys::error_code ec;
+ auto ip = asio::ip::address::from_string(host.to_string(), ec);
+ if (ec) return boost::none;
+ return tcp::endpoint(ip, strtol(port.data(), 0, 10));
};
- Type type;
- std::string endpoint_string;
+ sys::error_code ec;
+
+ string_view host;
+ string_view port;
- bool operator==(const Endpoint& other) const {
- return type == other.type && endpoint_string == other.endpoint_string;
+ std::tie(host, port) = split_string_pair(endpoint, ':');
+
+ if (port.empty()) {
+ return Endpoint{I2PEndpoint{endpoint.to_string()}};
}
-};
-boost::optional parse_endpoint(beast::string_view endpoint);
+ if (auto ep = as_tcp_endpoint(host, port)) {
+ return Endpoint{*ep};
+ }
+
+ return boost::none;
+}
+
+inline
+bool is_i2p_endpoint(const Endpoint& ep) {
+ return boost::get(&ep) ? true : false;
+}
+std::ostream& operator<<(std::ostream& os, const I2PEndpoint&);
std::ostream& operator<<(std::ostream& os, const Endpoint&);
} // ouinet namespace
diff --git a/src/injector.cpp b/src/injector.cpp
index 90745307f..3eebc3587 100644
--- a/src/injector.cpp
+++ b/src/injector.cpp
@@ -34,9 +34,6 @@
#include "ouiservice.h"
#include "ouiservice/i2p.h"
-#include "ouiservice/pt-obfs2.h"
-#include "ouiservice/pt-obfs3.h"
-#include "ouiservice/pt-obfs4.h"
#include "ouiservice/tcp.h"
#include "ouiservice/tls.h"
#include "ssl/ca_certificate.h"
@@ -779,45 +776,6 @@ int main(int argc, const char* argv[])
proxy_server.add(make_unique(move(base), ssl_context));
}
- if (config.obfs2_endpoint()) {
- tcp::endpoint endpoint = *config.obfs2_endpoint();
- cout << "obfs2 Address: " << util::str(endpoint) << endl;
- util::create_state_file( config.repo_root()/"endpoint-obfs2"
- , util::str(endpoint));
-
- proxy_server.add(make_unique(ios, endpoint, config.repo_root()/"obfs2-server"));
- }
-
- if (config.obfs3_endpoint()) {
- tcp::endpoint endpoint = *config.obfs3_endpoint();
- cout << "obfs3 Address: " << util::str(endpoint) << endl;
- util::create_state_file( config.repo_root()/"endpoint-obfs3"
- , util::str(endpoint));
-
- proxy_server.add(make_unique(ios, endpoint, config.repo_root()/"obfs3-server"));
- }
-
- if (config.obfs4_endpoint()) {
- tcp::endpoint endpoint = *config.obfs4_endpoint();
-
- util::create_state_file( config.repo_root()/"endpoint-obfs4"
- , util::str(endpoint));
-
- unique_ptr server =
- make_unique(ios, endpoint, config.repo_root()/"obfs4-server");
- asio::spawn(ios, [
- obfs4 = server.get(),
- endpoint
- ] (asio::yield_context yield) {
- sys::error_code ec;
- obfs4->wait_for_running(yield[ec]);
- if (!ec) {
- cout << "obfs4 Address: " << util::str(endpoint) << "," << obfs4->connection_arguments() << endl;
- }
- });
- proxy_server.add(std::move(server));
- }
-
if (config.listen_on_i2p()) {
auto i2p_service = make_shared((config.repo_root()/"i2p").string(), ios);
std::unique_ptr i2p_server = i2p_service->build_server("i2p-private-key");
diff --git a/src/injector_config.h b/src/injector_config.h
index 75cb4fdd9..732f82612 100644
--- a/src/injector_config.h
+++ b/src/injector_config.h
@@ -34,15 +34,6 @@ class InjectorConfig {
boost::optional tls_endpoint() const
{ return _tls_endpoint; }
- boost::optional obfs2_endpoint() const
- { return _obfs2_endpoint; }
-
- boost::optional obfs3_endpoint() const
- { return _obfs3_endpoint; }
-
- boost::optional obfs4_endpoint() const
- { return _obfs4_endpoint; }
-
static boost::program_options::options_description
options_description();
@@ -67,9 +58,6 @@ class InjectorConfig {
bool _listen_on_i2p = false;
boost::optional _tcp_endpoint;
boost::optional _tls_endpoint;
- boost::optional _obfs2_endpoint;
- boost::optional _obfs3_endpoint;
- boost::optional _obfs4_endpoint;
boost::filesystem::path OUINET_CONF_FILE = "ouinet-injector.conf";
std::string _credentials;
util::Ed25519PrivateKey _index_bep44_private_key;
@@ -98,9 +86,6 @@ InjectorConfig::options_description()
// Transport options
("listen-on-tcp", po::value(), "IP:PORT endpoint on which we'll listen (cleartext)")
("listen-on-tls", po::value(), "IP:PORT endpoint on which we'll listen (encrypted)")
- ("listen-on-obfs2", po::value(), "IP:PORT endpoint on which we'll listen using the obfs2 pluggable transport")
- ("listen-on-obfs3", po::value(), "IP:PORT endpoint on which we'll listen using the obfs3 pluggable transport")
- ("listen-on-obfs4", po::value(), "IP:PORT endpoint on which we'll listen using the obfs4 pluggable transport")
("listen-on-i2p",
po::value(),
"Whether we should be listening on I2P (true/false)")
@@ -199,18 +184,6 @@ InjectorConfig::InjectorConfig(int argc, const char**argv)
_tls_endpoint = util::parse_tcp_endpoint(vm["listen-on-tls"].as());
}
- if (vm.count("listen-on-obfs2")) {
- _obfs2_endpoint = util::parse_tcp_endpoint(vm["listen-on-obfs2"].as());
- }
-
- if (vm.count("listen-on-obfs3")) {
- _obfs3_endpoint = util::parse_tcp_endpoint(vm["listen-on-obfs3"].as());
- }
-
- if (vm.count("listen-on-obfs4")) {
- _obfs4_endpoint = util::parse_tcp_endpoint(vm["listen-on-obfs4"].as());
- }
-
setup_index_bep44_private_key( vm.count("index-bep44-private-key")
? vm["index-bep44-private-key"].as()
: string());
diff --git a/src/ouiservice/pluggable-transports/client-process.cpp b/src/ouiservice/pluggable-transports/client-process.cpp
deleted file mode 100644
index 0d9a4e3e9..000000000
--- a/src/ouiservice/pluggable-transports/client-process.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-#include "client-process.h"
-#include "util.h"
-
-namespace ouinet {
-namespace ouiservice {
-namespace pt {
-
-ClientProcess::ClientProcess(
- asio::io_service& ios,
- std::string command,
- std::vector command_line_arguments,
- std::string transport_name,
- boost::optional state_directory
-):
- DispatcherProcess(ios, command, command_line_arguments, state_directory),
- _transport_name(transport_name),
- _transport_initialized(false)
-{
-}
-
-void ClientProcess::start(asio::yield_context yield, Signal& cancel_signal)
-{
- std::map environment;
- environment["TOR_PT_CLIENT_TRANSPORTS"] = _transport_name;
-
- start_process(environment, yield, cancel_signal);
-}
-
-void ClientProcess::stop()
-{
- stop_process();
-}
-
-void ClientProcess::process_output_line(
- std::string command,
- std::vector args,
- sys::error_code& ec,
- bool& initialized
-) {
- if (command == "PROXY") {
- ec = asio::error::fault;
- } else if (command == "PROXY-ERROR") {
- ec = asio::error::fault;
- } else if (command == "CMETHOD") {
- if (args.size() < 3) {
- ec = asio::error::fault;
- return;
- }
- if (args[0] != _transport_name) {
- return;
- }
- if (args[1] == "socks5") {
- _connection_method = Socks5Connection;
- } else if (args[1] == "transparent-TCP") {
- _connection_method = TransparentConnection;
- } else {
- ec = asio::error::fault;
- return;
- }
- boost::optional endpoint = parse_endpoint(args[2]);
- if (!endpoint) {
- ec = asio::error::fault;
- return;
- }
- _endpoint = *endpoint;
- _transport_initialized = true;
- } else if (command == "CMETHOD-ERROR") {
- ec = asio::error::fault;
- } else if (command == "CMETHODS") {
- if (args.size() != 1 || args[0] != "DONE") {
- ec = asio::error::fault;
- return;
- }
- if (_transport_initialized) {
- initialized = true;
- } else {
- ec = asio::error::operation_not_supported;
- }
- } else {
- DispatcherProcess::process_output_line(command, args, ec, initialized);
- }
-}
-
-} // pt namespace
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pluggable-transports/client-process.h b/src/ouiservice/pluggable-transports/client-process.h
deleted file mode 100644
index 197cd9f91..000000000
--- a/src/ouiservice/pluggable-transports/client-process.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#pragma once
-
-#include
-
-#include "dispatcher-process.h"
-
-namespace ouinet {
-namespace ouiservice {
-namespace pt {
-
-class ClientProcess : public DispatcherProcess
-{
- public:
- enum ConnectionMethod {
- Socks5Connection,
- TransparentConnection
- };
-
- public:
- ClientProcess(
- asio::io_service& ios,
- std::string command,
- std::vector command_line_arguments,
- std::string transport_name,
- boost::optional state_directory
- );
-
- void start(asio::yield_context yield, Signal& cancel_signal);
- void stop();
-
- asio::ip::tcp::endpoint endpoint() const { return _endpoint; }
- ConnectionMethod connection_method() const { return _connection_method; }
-
- protected:
- void process_output_line(
- std::string command,
- std::vector args,
- sys::error_code& ec,
- bool& initialized
- ) override;
-
- protected:
- std::string _transport_name;
-
- bool _transport_initialized;
- asio::ip::tcp::endpoint _endpoint;
- ConnectionMethod _connection_method;
-};
-
-} // pt namespace
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pluggable-transports/dispatcher-process.cpp b/src/ouiservice/pluggable-transports/dispatcher-process.cpp
deleted file mode 100644
index 7658d2530..000000000
--- a/src/ouiservice/pluggable-transports/dispatcher-process.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-#include "dispatcher-process.h"
-#include "../../or_throw.h"
-#include "../../util/condition_variable.h"
-
-#include
-#include
-#include
-
-namespace ouinet {
-namespace ouiservice {
-namespace pt {
-
-static void parse_output_line(std::string line, std::string& command, std::vector& args)
-{
- size_t pos = line.find(' ');
- if (pos == std::string::npos) {
- command = line;
- return;
- } else {
- command = line.substr(0, pos);
- line = line.substr(pos + 1);
- }
-
- while (!line.empty()) {
- while (line[0] == ' ') {
- line.erase(line.begin());
- }
- if (line.empty()) {
- break;
- }
- pos = line.find(' ');
- if (pos == std::string::npos) {
- args.push_back(line);
- break;
- } else {
- args.push_back(line.substr(0, pos));
- line = line.substr(pos + 1);
- }
- }
-}
-
-DispatcherProcess::DispatcherProcess(
- asio::io_service& ios,
- std::string command,
- std::vector command_line_arguments,
- boost::optional state_directory
-):
- _ios(ios),
- _command(command),
- _command_line_arguments(command_line_arguments),
- _state_directory(state_directory)
-{
-}
-
-DispatcherProcess::~DispatcherProcess()
-{
- stop_process();
-}
-
-void DispatcherProcess::start_process(
- std::map environment,
- asio::yield_context yield,
- Signal& cancel_signal
-) {
- assert(!_process);
-
- boost::process::environment env = boost::this_process::environment();
- std::vector to_remove;
- for (auto i : env) {
- if (i.get_name().substr(0, 7) == "TOR_PT_") {
- to_remove.push_back(i.get_name());
- }
- }
- for (auto i : to_remove) {
- env.erase(i);
- }
- env["TOR_PT_MANAGED_TRANSPORT_VER"] = "1";
- env["TOR_PT_EXIT_ON_STDIN_CLOSE"] = "1";
- if (_state_directory) {
- env["TOR_PT_STATE_LOCATION"] = *_state_directory;
- }
- for (auto i : environment) {
- env[i.first] = i.second;
- }
-
- _standard_input = std::make_unique(_ios);
- auto standard_output = std::make_unique(_ios);
- _process_exit = std::make_unique>();
-
- std::error_code error_code;
- _process = std::make_unique(
- _command,
- boost::process::args(_command_line_arguments),
- boost::process::env(env),
- boost::process::std_in < *_standard_input,
- boost::process::std_out > *standard_output,
- boost::process::std_err > boost::process::null,
- boost::process::error(error_code),
- boost::process::on_exit([
- signal = _process_exit.get()
- ] (int exit, const std::error_code& error_code) {
- (*signal)();
- }),
- _ios
- );
-
- if (error_code) {
- return or_throw(yield, boost::system::errc::make_error_code(
- static_cast(error_code.value())
- ));
- }
-
-
-
- /*
- * Start the output processing coroutine, and wait for it to signal
- * successful initialization.
- * Abort on:
- * - cancellation;
- * - object destruction;
- * - timeout.
- */
-
- struct InitializationStatus {
- ConditionVariable stop_condition;
- boost::optional ec;
- InitializationStatus(asio::io_service& ios):
- stop_condition(ios),
- ec(boost::none)
- {}
- };
- std::shared_ptr initialization =
- std::make_shared(_ios);
-
- asio::steady_timer timeout_timer(_ios);
- timeout_timer.expires_from_now(std::chrono::seconds(15));
- timeout_timer.async_wait([initialization] (const sys::error_code&) {
- if (!initialization->ec) {
- initialization->ec = asio::error::timed_out;
- }
- initialization->stop_condition.notify();
- });
-
- auto cancelled = cancel_signal.connect([&] {
- initialization->ec = asio::error::operation_aborted;
- timeout_timer.cancel();
- });
-
- auto stopped = _stop_signal.connect([&] {
- initialization->ec = asio::error::operation_aborted;
- timeout_timer.cancel();
- });
-
- asio::spawn(_ios, [
- this,
- standard_output = std::move(standard_output),
- initialization
- ] (asio::yield_context yield) {
- std::string output_buffer;
- /*
- * The output processing coroutine can finish initialization in three forms:
- * - successful initialization;
- * - error reported by process_output_line;
- * - EOF.
- *
- * The output processing coroutine keeps going until it encounters an EOF.
- * It is not aborted by the DispatcherProcess under any circumstance;
- * rather, the DispatcherProcess kills the process, which will EOF the
- * pipe as soon as pending output is processed. After completion,
- * either successful or not, further output is ignored.
- */
-
- /*
- * Reading from an async_pipe doesn't work well in boost 1.67. The
- * source and sink endpoints are standard boost::asio components, and
- * they don't cause problems, so using them works around the issue.
- */
- auto standard_output_source = std::move(*standard_output).source();
-
- while (true) {
- char buffer[4096];
- sys::error_code ec;
-
- size_t read = standard_output_source.async_read_some(
- asio::mutable_buffers_1(buffer, sizeof(buffer)),
- yield[ec]
- );
-
- if (ec || !read) {
- break;
- }
-
- if (initialization->ec) {
- continue;
- }
-
- output_buffer.append(buffer, buffer + read);
-
- size_t pos;
- while ((pos = output_buffer.find('\n')) != std::string::npos) {
- std::string line = output_buffer.substr(0, pos);
- output_buffer = output_buffer.substr(pos + 1);
-
- std::string command;
- std::vector args;
- parse_output_line(line, command, args);
-
- bool initialized = false;
- process_output_line(command, args, ec, initialized);
- if (ec || initialized) {
- assert(!initialization->ec);
- initialization->ec = ec;
- initialization->stop_condition.notify();
- output_buffer.clear();
- break;
- }
- }
- }
-
- standard_output_source.close();
-
- if (!initialization->ec) {
- initialization->ec = asio::error::broken_pipe;
- initialization->stop_condition.notify();
- }
- });
-
- initialization->stop_condition.wait(yield);
-
- assert(initialization->ec);
- sys::error_code ec = *initialization->ec;
- timeout_timer.cancel();
-
- /*
- * If stopped() has been called, the process has already been cleaned up,
- * and $this may be gone, so we abort before calling stop().
- */
- if (stopped) {
- return or_throw(yield, ec);
- }
-
- if (ec) {
- stop_process();
- return or_throw(yield, ec);
- }
-}
-
-void DispatcherProcess::stop_process()
-{
- if (!_process) {
- return;
- }
-
- auto process = std::move(_process);
- auto standard_input = std::move(_standard_input);
- auto process_exit = std::move(_process_exit);
- asio::io_service& ios = _ios;
- _stop_signal();
-
- asio::spawn(_ios, [
- &ios,
- process = std::move(process),
- standard_input = std::move(standard_input),
- process_exit = std::move(process_exit)
- ] (asio::yield_context yield) {
- standard_input->close();
-
- /*
- * Closing the standard input triggers the process to quit.
- * Wait for process exit or a timeout.
- */
- asio::steady_timer timeout_timer(ios);
- timeout_timer.expires_from_now(std::chrono::seconds(5));
-
- auto exited = process_exit->connect([&] {
- timeout_timer.cancel();
- });
-
- sys::error_code ec;
- timeout_timer.async_wait(yield[ec]);
-
- if (process->running()) {
- process->terminate();
- }
- });
-}
-
-void DispatcherProcess::process_output_line(
- std::string command,
- std::vector args,
- sys::error_code& ec,
- bool& initialized
-) {
- if (command == "VERSION-ERROR") {
- ec = asio::error::operation_not_supported;
- } else if (command == "ENV-ERROR") {
- ec = asio::error::operation_not_supported;
- }
-}
-
-} // pt namespace
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pluggable-transports/dispatcher-process.h b/src/ouiservice/pluggable-transports/dispatcher-process.h
deleted file mode 100644
index 7d7775650..000000000
--- a/src/ouiservice/pluggable-transports/dispatcher-process.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#pragma once
-
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-#include "../../namespaces.h"
-#include "../../util/signal.h"
-
-namespace ouinet {
-namespace ouiservice {
-namespace pt {
-
-class DispatcherProcess
-{
- public:
- DispatcherProcess(
- asio::io_service& ios,
- std::string command,
- std::vector command_line_arguments,
- boost::optional state_directory
- );
- ~DispatcherProcess();
-
- protected:
- void start_process(
- std::map environment,
- asio::yield_context yield,
- Signal& cancel_signal
- );
- void stop_process();
-
- virtual void process_output_line(
- std::string command,
- std::vector args,
- sys::error_code& ec,
- bool& initialized
- );
-
- protected:
- asio::io_service& _ios;
- std::string _command;
- std::vector _command_line_arguments;
- boost::optional _state_directory;
-
- std::unique_ptr _process;
- std::unique_ptr _standard_input;
- std::unique_ptr> _process_exit;
-
- Signal _stop_signal;
-};
-
-} // pt namespace
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pluggable-transports/pt-ouiservice.cpp b/src/ouiservice/pluggable-transports/pt-ouiservice.cpp
deleted file mode 100644
index bbcda1ceb..000000000
--- a/src/ouiservice/pluggable-transports/pt-ouiservice.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-#include "pt-ouiservice.h"
-#include "client-process.h"
-#include "server-process.h"
-#include "socks5-client.h"
-#include "../../or_throw.h"
-#include "../../util.h"
-
-namespace ouinet {
-namespace ouiservice {
-namespace pt {
-
-PtOuiServiceServer::PtOuiServiceServer(asio::io_service& ios):
- _ios(ios),
- _acceptor(ios),
- _start_listen_condition(ios)
-{}
-
-PtOuiServiceServer::~PtOuiServiceServer()
-{}
-
-void PtOuiServiceServer::start_listen(asio::yield_context yield)
-{
- sys::error_code ec;
-
- if (_server_process) {
- ec = asio::error::in_progress;
- _start_listen_condition.notify(ec);
- return or_throw(yield, ec);
- }
-
- asio::ip::tcp::endpoint tcp_endpoint(
- asio::ip::address_v4::loopback(),
- 0
- );
-
- _acceptor.open(tcp_endpoint.protocol(), ec);
- if (ec) {
- _start_listen_condition.notify(ec);
- return or_throw(yield, ec);
- }
-
- _acceptor.set_option(asio::socket_base::reuse_address(true));
-
- _acceptor.bind(tcp_endpoint, ec);
- if (ec) {
- _acceptor.close();
- _start_listen_condition.notify(ec);
- return or_throw(yield, ec);
- }
-
- _acceptor.listen(asio::socket_base::max_connections, ec);
- if (ec) {
- _acceptor.close();
- _start_listen_condition.notify(ec);
- return or_throw(yield, ec);
- }
-
- Signal cancel;
- _server_process = start_server_process(
- _ios,
- _acceptor.local_endpoint(),
- yield[ec],
- cancel
- );
-
- if (ec) {
- _acceptor.cancel();
- _acceptor.close();
- _server_process.reset();
- _start_listen_condition.notify(ec);
- return or_throw(yield, ec);
- }
-
- _start_listen_condition.notify(ec);
-}
-
-void PtOuiServiceServer::stop_listen()
-{
- if (_server_process) {
- _server_process.reset();
- _acceptor.cancel();
- _acceptor.close();
- }
-}
-
-GenericStream PtOuiServiceServer::accept(asio::yield_context yield)
-{
- sys::error_code ec;
-
- asio::ip::tcp::socket socket(_ios);
- _acceptor.async_accept(socket, yield[ec]);
-
- if (ec) {
- return or_throw(yield, ec);
- }
-
- static const auto tcp_shutter = [](asio::ip::tcp::socket& s) {
- sys::error_code ec;
- s.shutdown(asio::ip::tcp::socket::shutdown_both, ec);
- s.close(ec);
- };
-
- return GenericStream(std::move(socket), tcp_shutter);
-}
-
-void PtOuiServiceServer::wait_for_running(asio::yield_context yield)
-{
- _start_listen_condition.wait(yield);
-}
-
-std::string PtOuiServiceServer::connection_arguments() const
-{
- return _server_process->connection_arguments();
-}
-
-
-
-PtOuiServiceClient::PtOuiServiceClient(asio::io_service& ios):
- _ios(ios)
-{}
-
-PtOuiServiceClient::~PtOuiServiceClient()
-{}
-
-void PtOuiServiceClient::start(asio::yield_context yield)
-{
- if (_client_process) {
- return or_throw(yield, asio::error::in_progress);
- }
-
- sys::error_code ec;
- Signal cancel;
- _client_process = start_client_process(
- _ios,
- yield[ec],
- cancel
- );
- if (ec) {
- _client_process.reset();
- return or_throw(yield, ec);
- }
-}
-
-void PtOuiServiceClient::stop()
-{
- _client_process.reset();
-}
-
-OuiServiceImplementationClient::ConnectInfo PtOuiServiceClient::connect(
- asio::yield_context yield,
- Signal& cancel
-) {
- if (!_client_process) {
- return or_throw(yield, asio::error::not_connected);
- }
-
- sys::error_code ec;
- std::string remote_endpoint_string;
- asio::ip::tcp::socket socket = connect_through_transport(
- _ios,
- _client_process->endpoint(),
- remote_endpoint_string,
- yield[ec],
- cancel
- );
-
- if (ec) {
- return or_throw(yield, ec);
- }
-
- static const auto tcp_shutter = [](asio::ip::tcp::socket& s) {
- sys::error_code ec;
- s.shutdown(asio::ip::tcp::socket::shutdown_both, ec);
- s.close(ec);
- };
-
- return ConnectInfo{
- GenericStream(std::move(socket), tcp_shutter),
- remote_endpoint_string
- };
-}
-
-} // pt namespace
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pluggable-transports/pt-ouiservice.h b/src/ouiservice/pluggable-transports/pt-ouiservice.h
deleted file mode 100644
index 3c02fad7c..000000000
--- a/src/ouiservice/pluggable-transports/pt-ouiservice.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#pragma once
-
-#include
-#include "../../ouiservice.h"
-#include "../../util/condition_variable.h"
-
-namespace ouinet {
-namespace ouiservice {
-namespace pt {
-
-class ClientProcess;
-class ServerProcess;
-
-class PtOuiServiceServer : public OuiServiceImplementationServer
-{
- public:
- PtOuiServiceServer(asio::io_service& ios);
- ~PtOuiServiceServer();
-
- void start_listen(asio::yield_context yield) final;
- void stop_listen() final;
-
- GenericStream accept(asio::yield_context yield) final;
-
- /*
- * Wait for the next start_listen() call to complete.
- * Reports the same error condition as start_listen() itself.
- */
- void wait_for_running(asio::yield_context yield);
- std::string connection_arguments() const;
-
- protected:
- virtual std::unique_ptr start_server_process(
- asio::io_service& ios,
- asio::ip::tcp::endpoint destination_endpoint,
- asio::yield_context yield,
- Signal& cancel_signal
- ) = 0;
-
- private:
- asio::io_service& _ios;
-
- asio::ip::tcp::acceptor _acceptor;
- std::unique_ptr _server_process;
- ConditionVariable _start_listen_condition;
-};
-
-class PtOuiServiceClient : public OuiServiceImplementationClient
-{
- public:
- PtOuiServiceClient(asio::io_service& ios);
- ~PtOuiServiceClient();
-
- void start(asio::yield_context yield) final;
- void stop() final;
-
- OuiServiceImplementationClient::ConnectInfo connect(
- asio::yield_context yield,
- Signal& cancel
- ) final;
-
- protected:
- virtual std::unique_ptr start_client_process(
- asio::io_service& ios,
- asio::yield_context yield,
- Signal& cancel_signal
- ) = 0;
- virtual asio::ip::tcp::socket connect_through_transport(
- asio::io_service& ios,
- asio::ip::tcp::endpoint transport_endpoint,
- std::string& remote_endpoint_string,
- asio::yield_context yield,
- Signal& cancel_signal
- ) = 0;
-
- private:
- asio::io_service& _ios;
-
- std::unique_ptr _client_process;
-};
-
-} // pt namespace
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pluggable-transports/server-process.cpp b/src/ouiservice/pluggable-transports/server-process.cpp
deleted file mode 100644
index 2b741ec24..000000000
--- a/src/ouiservice/pluggable-transports/server-process.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-#include "server-process.h"
-#include "util.h"
-
-namespace ouinet {
-namespace ouiservice {
-namespace pt {
-
-ServerProcess::ServerProcess(
- asio::io_service& ios,
- std::string command,
- std::vector command_line_arguments,
- std::string transport_name,
- boost::optional bind_address,
- asio::ip::tcp::endpoint destination_address,
- std::map transport_options,
- boost::optional state_directory
-):
- DispatcherProcess(ios, command, command_line_arguments, state_directory),
- _transport_name(transport_name),
- _bind_address(bind_address),
- _destination_address(destination_address),
- _transport_options(transport_options),
- _transport_initialized(false)
-{
-}
-
-void ServerProcess::start(asio::yield_context yield, Signal& cancel_signal)
-{
- std::map environment;
- environment["TOR_PT_SERVER_TRANSPORTS"] = _transport_name;
- if (!_transport_options.empty()) {
- std::string transport_options;
- for (auto i : _transport_options) {
- if (!transport_options.empty()) {
- transport_options += ";";
- }
- transport_options += _transport_name;
- transport_options += ":";
- transport_options += string_escape(i.first, ":;=");
- transport_options += "=";
- transport_options += string_escape(i.second, ":;=");
- }
- environment["TOR_PT_SERVER_TRANSPORT_OPTIONS"] = transport_options;
- }
- if (_bind_address) {
- std::string bind_address;
- bind_address += _transport_name;
- bind_address += "-";
- bind_address += format_endpoint(*_bind_address);
- environment["TOR_PT_SERVER_BINDADDR"] = bind_address;
- }
- environment["TOR_PT_ORPORT"] = format_endpoint(_destination_address);
-
- start_process(environment, yield, cancel_signal);
-}
-
-void ServerProcess::stop()
-{
- stop_process();
-}
-
-void ServerProcess::process_output_line(
- std::string command,
- std::vector args,
- sys::error_code& ec,
- bool& initialized
-) {
- if (command == "SMETHOD") {
- if (args.size() < 2) {
- ec = asio::error::fault;
- return;
- }
- if (args[0] != _transport_name) {
- return;
- }
- boost::optional endpoint = parse_endpoint(args[1]);
- if (!endpoint) {
- ec = asio::error::fault;
- return;
- }
- _listening_endpoint = *endpoint;
-
- for (size_t i = 2; i < args.size(); i++) {
- std::string arg = args[i];
- if (arg.substr(0, 5) == "ARGS:") {
- _connection_arguments = arg.substr(5);
- }
- }
-
- _transport_initialized = true;
- } else if (command == "SMETHOD-ERROR") {
- ec = asio::error::fault;
- } else if (command == "SMETHODS") {
- if (args.size() != 1 || args[0] != "DONE") {
- ec = asio::error::fault;
- return;
- }
- if (_transport_initialized) {
- initialized = true;
- } else {
- ec = asio::error::operation_not_supported;
- }
- } else {
- DispatcherProcess::process_output_line(command, args, ec, initialized);
- }
-}
-
-} // pt namespace
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pluggable-transports/server-process.h b/src/ouiservice/pluggable-transports/server-process.h
deleted file mode 100644
index 8535a9b62..000000000
--- a/src/ouiservice/pluggable-transports/server-process.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#pragma once
-
-#include
-
-#include "dispatcher-process.h"
-
-namespace ouinet {
-namespace ouiservice {
-namespace pt {
-
-class ServerProcess : public DispatcherProcess
-{
- public:
- ServerProcess(
- asio::io_service& ios,
- std::string command,
- std::vector command_line_arguments,
- std::string transport_name,
- boost::optional bind_address,
- asio::ip::tcp::endpoint destination_address,
- std::map transport_options,
- boost::optional state_directory
- );
-
- void start(asio::yield_context yield, Signal& cancel_signal);
- void stop();
-
- asio::ip::tcp::endpoint listening_endpoint() const { return _listening_endpoint; }
- std::string connection_arguments() const { return _connection_arguments; }
-
- protected:
- void process_output_line(
- std::string command,
- std::vector args,
- sys::error_code& ec,
- bool& initialized
- ) override;
-
- protected:
- std::string _transport_name;
- boost::optional _bind_address;
- asio::ip::tcp::endpoint _destination_address;
- std::map _transport_options;
-
- bool _transport_initialized;
- asio::ip::tcp::endpoint _listening_endpoint;
- std::string _connection_arguments;
-};
-
-} // pt namespace
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pluggable-transports/socks5-client.cpp b/src/ouiservice/pluggable-transports/socks5-client.cpp
deleted file mode 100644
index 454daa96f..000000000
--- a/src/ouiservice/pluggable-transports/socks5-client.cpp
+++ /dev/null
@@ -1,305 +0,0 @@
-#include "socks5-client.h"
-#include "util.h"
-#include "../../or_throw.h"
-
-#include
-
-namespace ouinet {
-namespace ouiservice {
-namespace pt {
-
-/*
- * Communicate connection arguments via Json Parameter Block authentication.
- * This method is described in the PT specification; actual implementation
- * degree is unclear.
- */
-/*
-ruud:
-I can't find any complete documentation on this, and no code that uses it.
-Let's implement this once we find a use case for it.
-
-void connection_arguments_json(
- asio::ip::tcp::socket& socket,
- std::map& connection_arguments,
- asio::yield_context yield
-) {
-}
-*/
-
-/*
- * Communicate connection arguments encoded in username/password.
- * This encoding is not described in the specification, but widely implemented.
- */
-void connection_arguments_username(
- asio::ip::tcp::socket& socket,
- std::map& connection_arguments,
- asio::yield_context yield
-) {
- sys::error_code ec;
-
- std::string encoded_arguments;
- for (auto i : connection_arguments) {
- if (!encoded_arguments.empty()) {
- encoded_arguments += ";";
- }
- encoded_arguments += string_escape(i.first, ";=");
- encoded_arguments += "=";
- encoded_arguments += string_escape(i.second, ";=");
- }
-
- std::string packet;
- packet += '\x01'; // authentication scheme version
- packet += (char)(encoded_arguments.size()); // username size
- packet += encoded_arguments; // username
- packet += '\x01'; // password size
- packet += '\x00'; // password
-
- socket.async_send(
- asio::const_buffers_1(packet.data(), packet.size()),
- 0, yield[ec]
- );
- if (ec) {
- return or_throw(yield, ec);
- }
-
- char reply[2];
- size_t received = socket.async_receive(
- asio::mutable_buffers_1(reply, sizeof(reply)),
- 0, yield[ec]
- );
- if (ec) {
- return or_throw(yield, ec);
- }
-
- if (received != 2) {
- return or_throw(yield, asio::error::connection_reset);
- }
- // authentication scheme version
- if (reply[0] != '\x01') {
- return or_throw(yield, asio::error::access_denied);
- }
- // error code
- if (reply[1] != '\0') {
- return or_throw(yield, asio::error::access_denied);
- }
-}
-
-
-asio::ip::tcp::socket connect_socks5(
- asio::ip::tcp::endpoint proxy_endpoint,
- asio::ip::tcp::endpoint destination_endpoint,
- boost::optional> connection_arguments,
- asio::io_service& ios,
- asio::yield_context yield,
- Signal& cancel
-) {
- sys::error_code ec;
-
- asio::ip::tcp::socket socket(ios);
-
- auto cancel_slot = cancel.connect([&] {
- // tcp::socket::cancel() does not work properly on all platforms
- sys::error_code ec;
- socket.close(ec);
- });
-
- socket.async_connect(proxy_endpoint, yield[ec]);
- if (ec) {
- return or_throw(yield, ec, std::move(socket));
- }
-
-
-
- std::string negotiation_request;
- negotiation_request += '\x05'; // protocol version 5
- if (connection_arguments) {
- negotiation_request += '\x01'; // 1 authentication methods supported
- //negotiation_request += '\x09'; // Json Parameter Block authentication
- negotiation_request += '\x02'; // username/password authentication
- } else {
- negotiation_request += '\x01'; // 1 authentication methods supported
- negotiation_request += '\x00'; // null authentication
- }
-
- socket.async_send(
- asio::const_buffers_1(negotiation_request.data(), negotiation_request.size()),
- 0, yield[ec]
- );
- if (ec) {
- socket.close();
- return or_throw(yield, ec, std::move(socket));
- }
-
- size_t received;
-
- char negotiation_reply[2];
- received = socket.async_receive(
- asio::mutable_buffers_1(negotiation_reply, sizeof(negotiation_reply)),
- 0, yield[ec]
- );
- if (ec) {
- socket.close();
- return or_throw(yield, ec, std::move(socket));
- }
-
- if (received != sizeof(negotiation_reply)) {
- socket.close();
- return or_throw(yield, asio::error::connection_reset, std::move(socket));
- }
- // protocol version 5
- if (negotiation_reply[0] != '\x05') {
- socket.close();
- return or_throw(yield, asio::error::connection_refused, std::move(socket));
- }
-
- if (connection_arguments) {
- if (negotiation_reply[1] == '\x02') {
- // username/password authentication
- connection_arguments_username(socket, *connection_arguments, yield[ec]);
- if (ec) {
- socket.close();
- return or_throw(yield, ec, std::move(socket));
- }
- } else {
- socket.close();
- return or_throw(yield, asio::error::connection_refused, std::move(socket));
- }
- } else {
- if (negotiation_reply[1] != 0) {
- socket.close();
- return or_throw(yield, asio::error::connection_refused, std::move(socket));
- }
- }
-
-
-
- std::string connect_request;
- connect_request += '\x05'; // protocol version 5
- connect_request += '\x01'; // CONNECT
- connect_request += '\x00'; // reserved
- if (destination_endpoint.address().is_v4()) {
- connect_request += '\x01'; // ipv4 address
- auto address = destination_endpoint.address().to_v4().to_bytes();
- connect_request.append(address.begin(), address.end());
- } else {
- connect_request += '\x04'; // ipv6 address
- auto address = destination_endpoint.address().to_v6().to_bytes();
- connect_request.append(address.begin(), address.end());
- }
- connect_request += (destination_endpoint.port() >> 8) & 0xff;
- connect_request += (destination_endpoint.port() >> 0) & 0xff;
-
- socket.async_send(
- asio::const_buffers_1(connect_request.data(), connect_request.size()),
- 0, yield[ec]
- );
- if (ec) {
- socket.close();
- return or_throw(yield, ec, std::move(socket));
- }
-
- char connect_reply_start[4];
- received = socket.async_receive(
- asio::mutable_buffers_1(connect_reply_start, sizeof(connect_reply_start)),
- 0, yield[ec]
- );
- if (ec) {
- socket.close();
- return or_throw(yield, ec, std::move(socket));
- }
- if (received != sizeof(connect_reply_start)) {
- socket.close();
- return or_throw(yield, asio::error::connection_reset, std::move(socket));
- }
- // protocol version 5
- if (connect_reply_start[0] != '\x05') {
- socket.close();
- return or_throw(yield, asio::error::connection_refused, std::move(socket));
- }
- // error code
- if (connect_reply_start[1] != '\x00') {
- socket.close();
- if (connect_reply_start[1] == '\x02') {
- // connection not allowed by ruleset
- std::cout << "operation not permitted? echt?\n";
- ec = asio::error::no_permission;
- } else if (connect_reply_start[1] == '\x03') {
- // Network unreachable
- ec = asio::error::network_unreachable;
- } else if (connect_reply_start[1] == '\x04') {
- // Host unreachable
- ec = asio::error::host_unreachable;
- } else {
- ec = asio::error::connection_refused;
- }
- return or_throw(yield, ec, std::move(socket));
- }
- // reserved
- if (connect_reply_start[2] != '\x00') {
- socket.close();
- return or_throw(yield, asio::error::connection_refused, std::move(socket));
- }
- // address type
- if (connect_reply_start[3] == '\x01') {
- // ipv4
- char buffer[4];
- received = socket.async_receive(
- asio::mutable_buffers_1(buffer, sizeof(buffer)),
- 0, yield[ec]
- );
- if (ec || received != sizeof(buffer)) {
- socket.close();
- return or_throw(yield, asio::error::connection_refused, std::move(socket));
- }
- } else if (connect_reply_start[3] == '\x04') {
- // ipv6
- char buffer[16];
- received = socket.async_receive(
- asio::mutable_buffers_1(buffer, sizeof(buffer)),
- 0, yield[ec]
- );
- if (ec || received != sizeof(buffer)) {
- socket.close();
- return or_throw(yield, asio::error::connection_refused, std::move(socket));
- }
- } else if (connect_reply_start[3] == '\x03') {
- // hostname
- char dummy_buffer[256];
- unsigned char size;
- received = socket.async_receive(
- asio::mutable_buffers_1(&size, 1),
- 0, yield[ec]
- );
- if (ec || received != 1) {
- socket.close();
- return or_throw(yield, asio::error::connection_refused, std::move(socket));
- }
- received = socket.async_receive(
- asio::mutable_buffers_1(&dummy_buffer, size),
- 0, yield[ec]
- );
- if (ec || received != size) {
- socket.close();
- return or_throw(yield, asio::error::connection_refused, std::move(socket));
- }
- } else {
- socket.close();
- return or_throw(yield, asio::error::connection_refused, std::move(socket));
- }
- char port_buffer[2];
- received = socket.async_receive(
- asio::mutable_buffers_1(port_buffer, sizeof(port_buffer)),
- 0, yield[ec]
- );
- if (ec || received != sizeof(port_buffer)) {
- socket.close();
- return or_throw(yield, asio::error::connection_refused, std::move(socket));
- }
-
- // Connection accepted.
- return std::move(socket);
-}
-
-} // pt namespace
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pluggable-transports/socks5-client.h b/src/ouiservice/pluggable-transports/socks5-client.h
deleted file mode 100644
index 18aaa83b3..000000000
--- a/src/ouiservice/pluggable-transports/socks5-client.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-#include
-
-#include "../../namespaces.h"
-#include "../../util/signal.h"
-
-namespace ouinet {
-namespace ouiservice {
-namespace pt {
-
-/*
- * Connects to $destination_endpoint using a socks5 proxy at $proxy_endpoint.
- * Supports optional connection arguments key/value pairs,
- * communicated via socks5 authentication.
- * On success, returns a TCP socket that is ready for payload data.
- */
-asio::ip::tcp::socket connect_socks5(
- asio::ip::tcp::endpoint proxy_endpoint,
- asio::ip::tcp::endpoint destination_endpoint,
- boost::optional> connection_arguments,
- asio::io_service& ios,
- asio::yield_context yield,
- Signal& cancel
-);
-
-} // pt namespace
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pluggable-transports/util.h b/src/ouiservice/pluggable-transports/util.h
deleted file mode 100644
index f0e7b9a71..000000000
--- a/src/ouiservice/pluggable-transports/util.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#pragma once
-
-#include
-#include
-
-#include
-
-namespace ouinet {
-namespace ouiservice {
-namespace pt {
-
-/*
- * Escape a string by prefixing all $characters with backslashes, as well
- * as the backslash character.
- */
-inline std::string string_escape(std::string payload, std::string characters)
-{
- std::string output;
- for (auto c : payload) {
- if (c == '\\' || characters.find(c) != std::string::npos) {
- output += '\\';
- }
- output += c;
- }
- return output;
-}
-
-/*
- * Parse a PT-encoded endpoint:
- * - 1.2.3.4:567
- * - [1:2:3:4::5]:678
- */
-inline boost::optional parse_endpoint(std::string endpoint)
-{
- size_t pos = endpoint.rfind(':');
- if (pos == std::string::npos) {
- return boost::none;
- }
- int port;
- try {
- port = std::stoi(endpoint.substr(pos + 1));
- } catch(...) {
- return boost::none;
- }
- if (port < 0 || port > 65535) {
- return boost::none;
- }
-
- std::string address_string = endpoint.substr(0, pos);
- if (
- address_string.size() > 0
- && address_string[0] == '['
- && address_string[address_string.size() - 1] == ']'
- ) {
- address_string = address_string.substr(1, address_string.size() - 2);
- }
- sys::error_code ec;
- asio::ip::address address = asio::ip::address::from_string(address_string, ec);
- if (ec) {
- return boost::none;
- }
-
- return asio::ip::tcp::endpoint(address, (short)port);
-}
-
-inline std::string format_endpoint(asio::ip::tcp::endpoint endpoint)
-{
- if (endpoint.address().is_v4()) {
- return endpoint.address().to_v4().to_string() + ":" + std::to_string(endpoint.port());
- } else {
- return "[" + endpoint.address().to_v6().to_string() + "]:" + std::to_string(endpoint.port());
- }
-}
-
-} // pt namespace
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pt-obfs2.cpp b/src/ouiservice/pt-obfs2.cpp
deleted file mode 100644
index e97391d4a..000000000
--- a/src/ouiservice/pt-obfs2.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-#include "pt-obfs2.h"
-#include "pluggable-transports/client-process.h"
-#include "pluggable-transports/server-process.h"
-#include "pluggable-transports/socks5-client.h"
-#include "../logger.h"
-#include "../or_throw.h"
-#include "../util.h"
-
-#include
-
-namespace ouinet {
-namespace ouiservice {
-
-Obfs2OuiServiceServer::Obfs2OuiServiceServer(
- asio::io_service& ios,
- asio::ip::tcp::endpoint endpoint,
- fs::path state_directory
-):
- PtOuiServiceServer(ios),
- _endpoint(endpoint),
- _state_directory(state_directory)
-{}
-
-std::unique_ptr Obfs2OuiServiceServer::start_server_process(
- asio::io_service& ios,
- asio::ip::tcp::endpoint destination_endpoint,
- asio::yield_context yield,
- Signal& cancel_signal
-) {
- auto server_process = std::make_unique(
- ios,
- "obfs4proxy",
- std::vector(),
- "obfs2",
- _endpoint,
- destination_endpoint,
- std::map(),
- _state_directory.string()
- );
-
- sys::error_code ec;
- server_process->start(yield[ec], cancel_signal);
-
- if (ec) {
- return or_throw>(yield, ec);
- }
-
- return std::move(server_process);
-}
-
-
-
-static boost::optional parse_endpoint(std::string endpoint)
-{
- size_t pos = endpoint.rfind(':');
- if (pos == std::string::npos) {
- return boost::none;
- }
-
- int port;
- try {
- port = std::stoi(endpoint.substr(pos + 1));
- } catch(...) {
- return boost::none;
- }
- sys::error_code ec;
- asio::ip::address address = asio::ip::address::from_string(endpoint.substr(0, pos), ec);
- if (ec) {
- return boost::none;
- }
- return asio::ip::tcp::endpoint(address, port);
-}
-
-Obfs2OuiServiceClient::Obfs2OuiServiceClient(
- asio::io_service& ios,
- std::string endpoint,
- fs::path state_directory
-):
- PtOuiServiceClient(ios),
- _endpoint(parse_endpoint(endpoint)),
- _state_directory(state_directory)
-{}
-
-std::unique_ptr Obfs2OuiServiceClient::start_client_process(
- asio::io_service& ios,
- asio::yield_context yield,
- Signal& cancel_signal
-) {
- if (!_endpoint) {
- return or_throw>(yield, asio::error::invalid_argument);
- }
-
- auto client_process = std::make_unique(
- ios,
- "obfs4proxy",
- std::vector(),
- "obfs2",
- _state_directory.string()
- );
-
- sys::error_code ec;
- client_process->start(yield[ec], cancel_signal);
-
- if (ec) {
- return or_throw>(yield, ec);
- }
-
- if (client_process->connection_method() != pt::ClientProcess::Socks5Connection) {
- return or_throw>(yield, asio::error::address_family_not_supported);
- }
-
- return std::move(client_process);
-}
-
-asio::ip::tcp::socket Obfs2OuiServiceClient::connect_through_transport(
- asio::io_service& ios,
- asio::ip::tcp::endpoint transport_endpoint,
- std::string& remote_endpoint_string,
- asio::yield_context yield,
- Signal& cancel_signal
-) {
- remote_endpoint_string = util::str(*_endpoint);
-
- return pt::connect_socks5(
- transport_endpoint,
- *_endpoint,
- boost::none,
- ios,
- yield,
- cancel_signal
- );
-}
-
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pt-obfs2.h b/src/ouiservice/pt-obfs2.h
deleted file mode 100644
index 05bf0be7d..000000000
--- a/src/ouiservice/pt-obfs2.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-
-#include "../ouiservice.h"
-
-#include "pluggable-transports/pt-ouiservice.h"
-
-namespace ouinet {
-namespace ouiservice {
-
-class Obfs2OuiServiceServer : public pt::PtOuiServiceServer
-{
- public:
- Obfs2OuiServiceServer(
- asio::io_service& ios,
- asio::ip::tcp::endpoint endpoint,
- fs::path state_directory
- );
-
- protected:
- std::unique_ptr start_server_process(
- asio::io_service& ios,
- asio::ip::tcp::endpoint destination_endpoint,
- asio::yield_context yield,
- Signal& cancel_signal
- ) override;
-
- private:
- asio::ip::tcp::endpoint _endpoint;
- fs::path _state_directory;
-};
-
-class Obfs2OuiServiceClient : public pt::PtOuiServiceClient
-{
- public:
- Obfs2OuiServiceClient(
- asio::io_service& ios,
- std::string endpoint,
- fs::path state_directory
- );
-
- bool verify_endpoint() const { return (bool)_endpoint; }
-
- protected:
- std::unique_ptr start_client_process(
- asio::io_service& ios,
- asio::yield_context yield,
- Signal& cancel_signal
- ) override;
- asio::ip::tcp::socket connect_through_transport(
- asio::io_service& ios,
- asio::ip::tcp::endpoint transport_endpoint,
- std::string& remote_endpoint_string,
- asio::yield_context yield,
- Signal& cancel_signal
- ) override;
-
- private:
- boost::optional _endpoint;
- fs::path _state_directory;
-};
-
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pt-obfs3.cpp b/src/ouiservice/pt-obfs3.cpp
deleted file mode 100644
index 859b82fab..000000000
--- a/src/ouiservice/pt-obfs3.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-#include "pt-obfs3.h"
-#include "pluggable-transports/client-process.h"
-#include "pluggable-transports/server-process.h"
-#include "pluggable-transports/socks5-client.h"
-#include "../logger.h"
-#include "../or_throw.h"
-#include "../util.h"
-
-#include
-
-namespace ouinet {
-namespace ouiservice {
-
-Obfs3OuiServiceServer::Obfs3OuiServiceServer(
- asio::io_service& ios,
- asio::ip::tcp::endpoint endpoint,
- fs::path state_directory
-):
- PtOuiServiceServer(ios),
- _endpoint(endpoint),
- _state_directory(state_directory)
-{}
-
-std::unique_ptr Obfs3OuiServiceServer::start_server_process(
- asio::io_service& ios,
- asio::ip::tcp::endpoint destination_endpoint,
- asio::yield_context yield,
- Signal& cancel_signal
-) {
- auto server_process = std::make_unique(
- ios,
- "obfs4proxy",
- std::vector(),
- "obfs3",
- _endpoint,
- destination_endpoint,
- std::map(),
- _state_directory.string()
- );
-
- sys::error_code ec;
- server_process->start(yield[ec], cancel_signal);
-
- if (ec) {
- return or_throw>(yield, ec);
- }
-
- return std::move(server_process);
-}
-
-
-
-static boost::optional parse_endpoint(std::string endpoint)
-{
- size_t pos = endpoint.rfind(':');
- if (pos == std::string::npos) {
- return boost::none;
- }
-
- int port;
- try {
- port = std::stoi(endpoint.substr(pos + 1));
- } catch(...) {
- return boost::none;
- }
- sys::error_code ec;
- asio::ip::address address = asio::ip::address::from_string(endpoint.substr(0, pos), ec);
- if (ec) {
- return boost::none;
- }
- return asio::ip::tcp::endpoint(address, port);
-}
-
-Obfs3OuiServiceClient::Obfs3OuiServiceClient(
- asio::io_service& ios,
- std::string endpoint,
- fs::path state_directory
-):
- PtOuiServiceClient(ios),
- _endpoint(parse_endpoint(endpoint)),
- _state_directory(state_directory)
-{}
-
-std::unique_ptr Obfs3OuiServiceClient::start_client_process(
- asio::io_service& ios,
- asio::yield_context yield,
- Signal& cancel_signal
-) {
- if (!_endpoint) {
- return or_throw>(yield, asio::error::invalid_argument);
- }
-
- auto client_process = std::make_unique(
- ios,
- "obfs4proxy",
- std::vector(),
- "obfs3",
- _state_directory.string()
- );
-
- sys::error_code ec;
- client_process->start(yield[ec], cancel_signal);
-
- if (ec) {
- return or_throw>(yield, ec);
- }
-
- if (client_process->connection_method() != pt::ClientProcess::Socks5Connection) {
- return or_throw>(yield, asio::error::address_family_not_supported);
- }
-
- return std::move(client_process);
-}
-
-asio::ip::tcp::socket Obfs3OuiServiceClient::connect_through_transport(
- asio::io_service& ios,
- asio::ip::tcp::endpoint transport_endpoint,
- std::string& remote_endpoint_string,
- asio::yield_context yield,
- Signal& cancel_signal
-) {
- remote_endpoint_string = util::str(*_endpoint);
-
- return pt::connect_socks5(
- transport_endpoint,
- *_endpoint,
- boost::none,
- ios,
- yield,
- cancel_signal
- );
-}
-
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pt-obfs3.h b/src/ouiservice/pt-obfs3.h
deleted file mode 100644
index f9d05e682..000000000
--- a/src/ouiservice/pt-obfs3.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-
-#include "../ouiservice.h"
-
-#include "pluggable-transports/pt-ouiservice.h"
-
-namespace ouinet {
-namespace ouiservice {
-
-class Obfs3OuiServiceServer : public pt::PtOuiServiceServer
-{
- public:
- Obfs3OuiServiceServer(
- asio::io_service& ios,
- asio::ip::tcp::endpoint endpoint,
- fs::path state_directory
- );
-
- protected:
- std::unique_ptr start_server_process(
- asio::io_service& ios,
- asio::ip::tcp::endpoint destination_endpoint,
- asio::yield_context yield,
- Signal& cancel_signal
- ) override;
-
- private:
- asio::ip::tcp::endpoint _endpoint;
- fs::path _state_directory;
-};
-
-class Obfs3OuiServiceClient : public pt::PtOuiServiceClient
-{
- public:
- Obfs3OuiServiceClient(
- asio::io_service& ios,
- std::string endpoint,
- fs::path state_directory
- );
-
- bool verify_endpoint() const { return (bool)_endpoint; }
-
- protected:
- std::unique_ptr start_client_process(
- asio::io_service& ios,
- asio::yield_context yield,
- Signal& cancel_signal
- ) override;
- asio::ip::tcp::socket connect_through_transport(
- asio::io_service& ios,
- asio::ip::tcp::endpoint transport_endpoint,
- std::string& remote_endpoint_string,
- asio::yield_context yield,
- Signal& cancel_signal
- ) override;
-
- private:
- boost::optional _endpoint;
- fs::path _state_directory;
-};
-
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pt-obfs4.cpp b/src/ouiservice/pt-obfs4.cpp
deleted file mode 100644
index 9f1919c3c..000000000
--- a/src/ouiservice/pt-obfs4.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-#include "pt-obfs4.h"
-#include "pluggable-transports/client-process.h"
-#include "pluggable-transports/server-process.h"
-#include "pluggable-transports/socks5-client.h"
-#include "../logger.h"
-#include "../or_throw.h"
-#include "../util.h"
-
-#include
-
-namespace ouinet {
-namespace ouiservice {
-
-Obfs4OuiServiceServer::Obfs4OuiServiceServer(
- asio::io_service& ios,
- asio::ip::tcp::endpoint endpoint,
- fs::path state_directory
-):
- PtOuiServiceServer(ios),
- _endpoint(endpoint),
- _state_directory(state_directory)
-{}
-
-std::unique_ptr Obfs4OuiServiceServer::start_server_process(
- asio::io_service& ios,
- asio::ip::tcp::endpoint destination_endpoint,
- asio::yield_context yield,
- Signal& cancel_signal
-) {
- auto server_process = std::make_unique(
- ios,
- "obfs4proxy",
- std::vector(),
- "obfs4",
- _endpoint,
- destination_endpoint,
- std::map(),
- _state_directory.string()
- );
-
- sys::error_code ec;
- server_process->start(yield[ec], cancel_signal);
-
- if (ec) {
- return or_throw>(yield, ec);
- }
-
- return std::move(server_process);
-}
-
-
-
-static void parse_endpoint(
- std::string endpoint_string,
- boost::optional& endpoint,
- std::string& certificate,
- std::string& iat_mode
-) {
- endpoint = boost::none;
- std::vector parts;
- boost::algorithm::split(parts, endpoint_string, [](char c) { return c == ','; });
- if (parts.size() != 3) {
- return;
- }
- if (parts[1].substr(0, 5) != "cert=") {
- return;
- }
- certificate = parts[1].substr(5);
- if (parts[2].substr(0, 9) != "iat-mode=") {
- return;
- }
- iat_mode = parts[2].substr(9);
-
-
- size_t pos = parts[0].rfind(':');
- if (pos == std::string::npos) {
- return;
- }
-
- int port;
- try {
- port = std::stoi(parts[0].substr(pos + 1));
- } catch(...) {
- return;
- }
- sys::error_code ec;
- asio::ip::address address = asio::ip::address::from_string(parts[0].substr(0, pos), ec);
- if (ec) {
- return;
- }
- endpoint = asio::ip::tcp::endpoint(address, port);
-}
-
-Obfs4OuiServiceClient::Obfs4OuiServiceClient(
- asio::io_service& ios,
- std::string endpoint,
- fs::path state_directory
-):
- PtOuiServiceClient(ios),
- _state_directory(state_directory)
-{
- parse_endpoint(endpoint, _endpoint, _certificate, _iat_mode);
-}
-
-std::unique_ptr Obfs4OuiServiceClient::start_client_process(
- asio::io_service& ios,
- asio::yield_context yield,
- Signal& cancel_signal
-) {
- if (!_endpoint) {
- return or_throw>(yield, asio::error::invalid_argument);
- }
-
- auto client_process = std::make_unique(
- ios,
- "obfs4proxy",
- std::vector(),
- "obfs4",
- _state_directory.string()
- );
-
- sys::error_code ec;
- client_process->start(yield[ec], cancel_signal);
-
- if (ec) {
- return or_throw>(yield, ec);
- }
-
- if (client_process->connection_method() != pt::ClientProcess::Socks5Connection) {
- return or_throw>(yield, asio::error::address_family_not_supported);
- }
-
- return std::move(client_process);
-}
-
-asio::ip::tcp::socket Obfs4OuiServiceClient::connect_through_transport(
- asio::io_service& ios,
- asio::ip::tcp::endpoint transport_endpoint,
- std::string& remote_endpoint_string,
- asio::yield_context yield,
- Signal& cancel_signal
-) {
- std::map connection_arguments;
- connection_arguments["cert"] = _certificate;
- connection_arguments["iat-mode"] = _iat_mode;
-
- remote_endpoint_string = util::str(*_endpoint);
-
- return pt::connect_socks5(
- transport_endpoint,
- *_endpoint,
- connection_arguments,
- ios,
- yield,
- cancel_signal
- );
-}
-
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/pt-obfs4.h b/src/ouiservice/pt-obfs4.h
deleted file mode 100644
index a44f13050..000000000
--- a/src/ouiservice/pt-obfs4.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-
-#include "../ouiservice.h"
-
-#include "pluggable-transports/pt-ouiservice.h"
-
-namespace ouinet {
-namespace ouiservice {
-
-class Obfs4OuiServiceServer : public pt::PtOuiServiceServer
-{
- public:
- Obfs4OuiServiceServer(
- asio::io_service& ios,
- asio::ip::tcp::endpoint endpoint,
- fs::path state_directory
- );
-
- protected:
- std::unique_ptr start_server_process(
- asio::io_service& ios,
- asio::ip::tcp::endpoint destination_endpoint,
- asio::yield_context yield,
- Signal& cancel_signal
- ) override;
-
- private:
- asio::ip::tcp::endpoint _endpoint;
- fs::path _state_directory;
-};
-
-class Obfs4OuiServiceClient : public pt::PtOuiServiceClient
-{
- public:
- Obfs4OuiServiceClient(
- asio::io_service& ios,
- std::string endpoint,
- fs::path state_directory
- );
-
- bool verify_endpoint() const { return (bool)_endpoint; }
-
- protected:
- std::unique_ptr start_client_process(
- asio::io_service& ios,
- asio::yield_context yield,
- Signal& cancel_signal
- ) override;
- asio::ip::tcp::socket connect_through_transport(
- asio::io_service& ios,
- asio::ip::tcp::endpoint transport_endpoint,
- std::string& remote_endpoint_string,
- asio::yield_context yield,
- Signal& cancel_signal
- ) override;
-
- private:
- boost::optional _endpoint;
- std::string _certificate;
- std::string _iat_mode;
- fs::path _state_directory;
-};
-
-} // ouiservice namespace
-} // ouinet namespace
diff --git a/src/ouiservice/tcp.cpp b/src/ouiservice/tcp.cpp
index 4f3249999..6db3756ba 100644
--- a/src/ouiservice/tcp.cpp
+++ b/src/ouiservice/tcp.cpp
@@ -67,39 +67,14 @@ GenericStream TcpOuiServiceServer::accept(asio::yield_context yield)
return GenericStream(std::move(socket), tcp_shutter);
}
-static boost::optional parse_endpoint(std::string endpoint)
-{
- size_t pos = endpoint.rfind(':');
- if (pos == std::string::npos) {
- return boost::none;
- }
-
- int port;
- try {
- port = std::stoi(endpoint.substr(pos + 1));
- } catch(...) {
- return boost::none;
- }
- sys::error_code ec;
- asio::ip::address address = asio::ip::address::from_string(endpoint.substr(0, pos), ec);
- if (ec) {
- return boost::none;
- }
- return asio::ip::tcp::endpoint(address, port);
-}
-
-TcpOuiServiceClient::TcpOuiServiceClient(asio::io_service& ios, std::string endpoint):
+TcpOuiServiceClient::TcpOuiServiceClient(asio::io_service& ios, asio::ip::tcp::endpoint endpoint):
_ios(ios),
- _endpoint(parse_endpoint(endpoint))
+ _endpoint(endpoint)
{}
OuiServiceImplementationClient::ConnectInfo
TcpOuiServiceClient::connect(asio::yield_context yield, Signal& cancel)
{
- if (!_endpoint) {
- return or_throw(yield, asio::error::invalid_argument);
- }
-
sys::error_code ec;
asio::ip::tcp::socket socket(_ios);
@@ -110,7 +85,7 @@ TcpOuiServiceClient::connect(asio::yield_context yield, Signal& cancel)
socket.close(ec);
});
- socket.async_connect(*_endpoint, yield[ec]);
+ socket.async_connect(_endpoint, yield[ec]);
if (ec) {
return or_throw(yield, ec);
@@ -123,7 +98,7 @@ TcpOuiServiceClient::connect(asio::yield_context yield, Signal& cancel)
};
return ConnectInfo{ GenericStream(std::move(socket), tcp_shutter)
- , util::str(*_endpoint) };
+ , util::str(_endpoint) };
}
} // ouiservice namespace
diff --git a/src/ouiservice/tcp.h b/src/ouiservice/tcp.h
index 9308ede29..c4db6b81d 100644
--- a/src/ouiservice/tcp.h
+++ b/src/ouiservice/tcp.h
@@ -2,7 +2,6 @@
#include
#include
-#include
#include "../ouiservice.h"
@@ -31,7 +30,7 @@ class TcpOuiServiceClient : public OuiServiceImplementationClient
using ConnectInfo = OuiServiceImplementationClient::ConnectInfo;
public:
- TcpOuiServiceClient(asio::io_service& ios, std::string endpoint);
+ TcpOuiServiceClient(asio::io_service& ios, asio::ip::tcp::endpoint endpoint);
// Tcp clients don't have any internal async IO to be started/stopped.
void start(asio::yield_context yield) override {}
@@ -40,11 +39,9 @@ class TcpOuiServiceClient : public OuiServiceImplementationClient
ConnectInfo connect( asio::yield_context yield
, Signal& cancel) override;
- bool verify_endpoint() const { return (bool)_endpoint; }
-
private:
asio::io_service& _ios;
- boost::optional _endpoint;
+ asio::ip::tcp::endpoint _endpoint;
};
} // ouiservice namespace
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 09b6a61da..93266590d 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -78,26 +78,6 @@ add_executable(test-logger "test_logger.cpp"
target_link_libraries(test-logger ${Boost_LIBRARIES})
-######################################################################
-add_executable(test-oui-server "ouiservice-server.cpp"
- "../src/asio.cpp"
- "../src/logger.cpp"
- "../src/ouiservice.cpp"
- "../src/ouiservice/tcp.cpp"
-)
-
-target_link_libraries(test-oui-server ${Boost_LIBRARIES})
-
-######################################################################
-add_executable(test-oui-client "ouiservice-client.cpp"
- "../src/asio.cpp"
- "../src/logger.cpp"
- "../src/ouiservice.cpp"
- "../src/ouiservice/tcp.cpp"
-)
-
-target_link_libraries(test-oui-client ${Boost_LIBRARIES})
-
######################################################################
add_executable(test-http-util "test_http_util.cpp" "../src/asio.cpp")
target_include_directories(test-http-util PUBLIC "${Boost_INCLUDE_DIR}")
diff --git a/test/ouiservice-client.cpp b/test/ouiservice-client.cpp
deleted file mode 100644
index 9f37db0f6..000000000
--- a/test/ouiservice-client.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-#include
-#include
-#include
-
-#include "namespaces.h"
-#include "ouiservice.h"
-#include "ouiservice/tcp.h"
-
-//#include "util/crypto.h"
-
-using namespace std;
-using namespace ouinet;
-
-int main(int argc, const char* argv[])
-{
-// util::crypto_init();
-
- if (argc < 2) {
- std::cerr << "Usage: ouiservice-client \n";
- return 1;
- }
- std::string message(argv[1]);
- message += "\n";
-
- asio::io_service ios;
-
- OuiServiceClient client(ios);
-
- client.add(make_unique(ios, "127.0.0.1:10203"));
-
- asio::spawn(ios, [&ios, &client, &message] (asio::yield_context yield) {
- sys::error_code ec;
- client.start(yield[ec]);
-
- if (ec) {
- std::cerr << "Failed to setup ouiservice client: " << ec.message() << endl;
- return;
- }
-
- Signal cancel;
- auto out = client.connect(yield[ec], cancel);
- if (ec) {
- std::cerr << "Failed to connect to server: " << ec.message() << endl;
- return;
- }
-
- GenericStream connection = std::move(out.connection);
- while (message.size()) {
- size_t written = connection.async_write_some(asio::const_buffers_1(message.data(), message.size()), yield[ec]);
- if (ec || !written) {
- return;
- }
- message = message.substr(written);
- }
-
- std::string line;
- while (true) {
- char c;
- size_t read = connection.async_read_some(asio::mutable_buffers_1(&c, 1), yield[ec]);
- if (ec || !read) {
- return;
- }
-
- line += c;
- if (c == '\n') {
- std::cerr << line;
- break;
- }
- }
- });
-
- ios.run();
- return 0;
-}
diff --git a/test/ouiservice-server.cpp b/test/ouiservice-server.cpp
deleted file mode 100644
index 10b0c3267..000000000
--- a/test/ouiservice-server.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#include
-#include