mirror of https://github.com/oxen-io/lokinet
Merge branch 'master' of https://github.com/loki-project/loki-network
commit
5d90cbe895
@ -0,0 +1 @@
|
||||
build/
|
@ -0,0 +1,50 @@
|
||||
# lokinet builder for windows
|
||||
|
||||
## Building for Windows (mingw-w64 native, or wow64/linux/unix cross-compiler)
|
||||
|
||||
#i686 or x86_64
|
||||
|
||||
$ pacman -Sy base-devel mingw-w64-$ARCH-toolchain git libtool autoconf cmake (or your distro/OS package mgr)
|
||||
$ git clone https://github.com/loki-project/loki-network.git
|
||||
$ cd loki-network
|
||||
$ mkdir -p build; cd build
|
||||
$ cmake .. -DCMAKE_BUILD_TYPE=Debug -DSTATIC_LINK=ON -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DDNS_PORT=53
|
||||
|
||||
# if cross-compiling do
|
||||
$ mkdir -p build; cd build
|
||||
$ export COMPILER=clang # if using clang for windows
|
||||
$ cmake .. -DCMAKE_BUILD_TYPE=[Debug|Release] -DSTATIC_LINK=ON -DCMAKE_CROSSCOMPILING=ON -DCMAKE_C_COMPILER=$ARCH-w64-mingw32-[gcc|clang] -DCMAKE_CXX_COMPILER=$ARCH-w64-mingw32-[g|clang]++ -DDNS_PORT=53 -DCMAKE_TOOLCHAIN_FILE=../contrib/cross/mingw[32].cmake
|
||||
|
||||
## running
|
||||
|
||||
if the machine you run lokinet on has a public address (at the moment) it `will` automatically become a relay,
|
||||
otherwise it will run in client mode.
|
||||
|
||||
|
||||
**NEVER** run lokinet with elevated privileges.
|
||||
|
||||
to set up a lokinet to start on boot:
|
||||
|
||||
C:\> (not ready yet. TODO: write up some SCM install code in the win32 setup)
|
||||
|
||||
alternatively:
|
||||
|
||||
set up the configs and bootstrap (first time only):
|
||||
|
||||
C:\> lokinet -g && lokinet-bootstrap
|
||||
|
||||
run it (foreground):
|
||||
|
||||
C:\> lokinet
|
||||
|
||||
to force client mode edit `$APPDATA/.lokinet/daemon.ini`
|
||||
|
||||
comment out the `[bind]` section, so it looks like this:
|
||||
|
||||
...
|
||||
|
||||
# [bind]
|
||||
# {B7F2ECAC-BB10-4736-8BBD-6E9444E27030}=1090
|
||||
|
||||
|
||||
-despair
|
@ -0,0 +1,26 @@
|
||||
set(CMAKE_SYSTEM_NAME Windows)
|
||||
set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
|
||||
|
||||
add_definitions("-DWINNT_CROSS_COMPILE")
|
||||
|
||||
# target environment on the build host system
|
||||
# second one is for non-root installs
|
||||
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} /home/$ENV{USER}/mingw32 /home/$ENV{USER}/mingw32/${TOOLCHAIN_PREFIX})
|
||||
|
||||
# modify default behavior of FIND_XXX() commands
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
|
||||
# cross compilers to use
|
||||
if($ENV{COMPILER} MATCHES "clang")
|
||||
set(USING_CLANG ON)
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-clang)
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-clang++)
|
||||
else()
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
|
||||
endif()
|
||||
|
||||
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
|
||||
set(WIN64_CROSS_COMPILE ON)
|
@ -0,0 +1,26 @@
|
||||
set(CMAKE_SYSTEM_NAME Windows)
|
||||
set(TOOLCHAIN_PREFIX i686-w64-mingw32)
|
||||
|
||||
add_definitions("-DWINNT_CROSS_COMPILE")
|
||||
|
||||
# target environment on the build host system
|
||||
# second one is for non-root installs
|
||||
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} /home/$ENV{USER}/mingw32 /home/$ENV{USER}/mingw32/${TOOLCHAIN_PREFIX})
|
||||
|
||||
# modify default behavior of FIND_XXX() commands
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
|
||||
# cross compilers to use
|
||||
if($ENV{COMPILER} MATCHES "clang")
|
||||
set(USING_CLANG ON)
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-clang)
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-clang++)
|
||||
else()
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
|
||||
endif()
|
||||
|
||||
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
|
||||
set(WOW64_CROSS_COMPILE ON)
|
@ -0,0 +1,4 @@
|
||||
*.o
|
||||
mbedtls/
|
||||
*.a
|
||||
*.exe
|
@ -0,0 +1,17 @@
|
||||
Copyright (c)2018 Rick V. All rights reserved.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
@ -0,0 +1,54 @@
|
||||
# makefile for windows bootstrap
|
||||
# requires mbedtls to be installed somewhere, for both native and windows targets
|
||||
# requires wget to be installed for ca bundle download
|
||||
|
||||
# to build:
|
||||
# $ [g]make prepare;[g]make lokinet-bootstrap
|
||||
|
||||
# set this beforehand if you use clang
|
||||
CC ?= i686-w64-mingw32-gcc
|
||||
NATIVE_CC ?= cc
|
||||
|
||||
# set these for the native system
|
||||
INCLUDE ?=
|
||||
LIBS ?=
|
||||
|
||||
# set these for 32-bit windows if cross-compiling
|
||||
WINNT_INCLUDE ?=
|
||||
WINNT_LIBS ?=
|
||||
|
||||
.PHONY: download prepare all default
|
||||
|
||||
# windows target only
|
||||
.c.o:
|
||||
$(CC) $(WINNT_INCLUDE) -Ofast -march=core2 -mfpmath=sse $< -c
|
||||
|
||||
zpipe: zpipe.c miniz.c
|
||||
$(NATIVE_CC) $(INCLUDE) $(LIBS) $^ -s -static -o $@
|
||||
|
||||
base64enc: base64enc.c
|
||||
$(NATIVE_CC) $(INCLUDE) $(LIBS) $^ -s -static -o $@ -lmbedx509 -lmbedtls -lmbedcrypto
|
||||
|
||||
download:
|
||||
wget -O ./cacert.pem https://curl.haxx.se/ca/cacert.pem
|
||||
|
||||
prepare: zpipe base64enc download
|
||||
./zpipe < cacert.pem > data.enc
|
||||
./base64enc < data.enc > out.bin
|
||||
sed -ie "s/.\{76\}/&\n/g" out.bin
|
||||
sed -i 's/.*/\"&\"/g' out.bin
|
||||
sed -i '49,2192d' bootstrap.c
|
||||
echo ';' >> out.bin
|
||||
sed -i '48r out.bin' bootstrap.c
|
||||
|
||||
lokinet-bootstrap: bootstrap.o miniz.o
|
||||
$(CC) $(WINNT_LIBS) -static -s $^ -o $@.exe -lmbedx509 -lmbedtls -lmbedcrypto -lws2_32
|
||||
|
||||
clean:
|
||||
-@rm lokinet-bootstrap.exe
|
||||
-@rm base64enc
|
||||
-@rm zpipe
|
||||
-@rm cacert.pem
|
||||
-@rm data.enc
|
||||
-@rm out.*
|
||||
-@rm *.o
|
@ -0,0 +1,35 @@
|
||||
# LokiNET bootstrap for Windows
|
||||
|
||||
This is a tiny executable that does the same thing as the `lokinet-bootstrap` shell script for Linux, specifically for the purpose of bypassing broken or outdated versions of Schannel that do not support current versions of TLS.
|
||||
|
||||
# Building
|
||||
|
||||
## requirements
|
||||
|
||||
- mbedtls 2.13.0 or later, for both host and windows
|
||||
- wget for host (to download Netscape CA bundle from cURL website)
|
||||
- Also included is a patch that can be applied to the mbedtls source to enable features like AES-NI in protected mode, plus some networking fixes for win32
|
||||
|
||||
native build:
|
||||
|
||||
$ export INCLUDE=/mingw32/include LIBS=/mingw32/lib # or a different path
|
||||
$ export CC=cc # change these if you use clang
|
||||
$ export NATIVE_CC=$CC
|
||||
$ export WINNT_INCLUDE=$INCLUDE WINNT_LIBS=$LIBS
|
||||
$ make prepare;make lokinet-bootstrap
|
||||
|
||||
cross-compile build:
|
||||
|
||||
$ export INCLUDE=/usr/local/include LIBS=/usr/local/lib # or a different path
|
||||
$ export CC=i686-w64-mingw32-gcc # change these if you use clang, make sure these are in your system $PATH!
|
||||
$ export NATIVE_CC=cc
|
||||
$ export WINNT_INCLUDE=/path/to/win32/headers WINNT_LIBS=/path/to/win32/libs
|
||||
$ make prepare;make lokinet-bootstrap
|
||||
|
||||
# Usage
|
||||
|
||||
C:\>lokinet-bootstrap [uri] [local download path]
|
||||
|
||||
this is also included in the lokinet installer package.
|
||||
|
||||
-despair86
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c)2018 Rick V. All rights reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sysconf.h"
|
||||
#ifdef HAVE_SETMODE
|
||||
# define SET_BINARY_MODE(handle) setmode(handle, O_BINARY)
|
||||
#else
|
||||
# define SET_BINARY_MODE(handle) ((void)0)
|
||||
#endif
|
||||
#include <mbedtls/base64.h>
|
||||
#include <mbedtls/error.h>
|
||||
|
||||
main(argc, argv)
|
||||
char** argv;
|
||||
{
|
||||
int size,r, inl;
|
||||
unsigned char in[524288];
|
||||
unsigned char out[1048576];
|
||||
unsigned char err[1024];
|
||||
memset(&in, 0, 524288);
|
||||
memset(&out, 0, 1048576);
|
||||
SET_BINARY_MODE(0);
|
||||
/* Read up to 512K of data from stdin */
|
||||
inl = fread(in, 1, 524288, stdin);
|
||||
r = mbedtls_base64_encode(out, 1048576, &size, in, inl);
|
||||
if (r)
|
||||
{
|
||||
mbedtls_strerror(r, err, 1024);
|
||||
printf("error: %s\n", err);
|
||||
return r;
|
||||
}
|
||||
fprintf(stdout, "%s", out);
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,205 @@
|
||||
diff -ruN polarssl-master/include/mbedtls/aesni.h polarssl/include/mbedtls/aesni.h
|
||||
--- polarssl-master/include/mbedtls/aesni.h 2018-03-16 11:25:12.000000000 -0500
|
||||
+++ polarssl/include/mbedtls/aesni.h 2018-04-17 15:47:59.320514100 -0500
|
||||
@@ -26,17 +26,16 @@
|
||||
|
||||
#include "aes.h"
|
||||
|
||||
+/*
|
||||
+ * despair: This code appears to be 32-bit clean. Remove the CPP macros
|
||||
+ * that restrict usage to AMD64 and EM64T processors.
|
||||
+ * Obviously, you still need to have this insn set available in order to
|
||||
+ * use it in either of protected or long mode anyway.
|
||||
+ */
|
||||
+
|
||||
#define MBEDTLS_AESNI_AES 0x02000000u
|
||||
#define MBEDTLS_AESNI_CLMUL 0x00000002u
|
||||
|
||||
-#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
|
||||
- ( defined(__amd64__) || defined(__x86_64__) ) && \
|
||||
- ! defined(MBEDTLS_HAVE_X86_64)
|
||||
-#define MBEDTLS_HAVE_X86_64
|
||||
-#endif
|
||||
-
|
||||
-#if defined(MBEDTLS_HAVE_X86_64)
|
||||
-
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -107,6 +106,4 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
-#endif /* MBEDTLS_HAVE_X86_64 */
|
||||
-
|
||||
#endif /* MBEDTLS_AESNI_H */
|
||||
diff -ruN polarssl-master/include/mbedtls/bn_mul.h polarssl/include/mbedtls/bn_mul.h
|
||||
--- polarssl-master/include/mbedtls/bn_mul.h 2018-03-16 11:25:12.000000000 -0500
|
||||
+++ polarssl/include/mbedtls/bn_mul.h 2018-04-17 15:42:09.045117300 -0500
|
||||
@@ -754,7 +754,9 @@
|
||||
#if defined(MBEDTLS_HAVE_SSE2)
|
||||
|
||||
#define EMIT __asm _emit
|
||||
-
|
||||
+/* Because the Visual C++ inline assembler STILL does
|
||||
+ not support MMX insns! reeeeee (old -GM flag no longer exists)
|
||||
+ */
|
||||
#define MULADDC_HUIT \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
|
||||
EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
|
||||
diff -ruN polarssl-master/include/mbedtls/config.h polarssl/include/mbedtls/config.h
|
||||
--- polarssl-master/include/mbedtls/config.h 2018-03-16 11:25:12.000000000 -0500
|
||||
+++ polarssl/include/mbedtls/config.h 2018-04-17 17:27:18.350938700 -0500
|
||||
@@ -91,7 +91,7 @@
|
||||
*
|
||||
* Uncomment if the CPU supports SSE2 (IA-32 specific).
|
||||
*/
|
||||
-//#define MBEDTLS_HAVE_SSE2
|
||||
+#define MBEDTLS_HAVE_SSE2
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_HAVE_TIME
|
||||
@@ -1571,7 +1571,7 @@
|
||||
* Module: library/aesni.c
|
||||
* Caller: library/aes.c
|
||||
*
|
||||
- * Requires: MBEDTLS_HAVE_ASM
|
||||
+ * Requires: None. Enable only for i386 or AMD64 targets only! -despair
|
||||
*
|
||||
* This modules adds support for the AES-NI instructions on x86-64
|
||||
*/
|
||||
@@ -1850,7 +1850,7 @@
|
||||
* Requires: MBEDTLS_AES_C or MBEDTLS_DES_C
|
||||
*
|
||||
*/
|
||||
-//#define MBEDTLS_CMAC_C
|
||||
+#define MBEDTLS_CMAC_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_CTR_DRBG_C
|
||||
@@ -2055,7 +2055,7 @@
|
||||
*
|
||||
* Uncomment to enable the HAVEGE random generator.
|
||||
*/
|
||||
-//#define MBEDTLS_HAVEGE_C
|
||||
+#define MBEDTLS_HAVEGE_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_HMAC_DRBG_C
|
||||
diff -ruN polarssl-master/library/aes.c polarssl/library/aes.c
|
||||
--- polarssl-master/library/aes.c 2018-03-16 11:25:12.000000000 -0500
|
||||
+++ polarssl/library/aes.c 2018-04-17 16:51:37.098413400 -0500
|
||||
@@ -514,7 +514,7 @@
|
||||
#endif
|
||||
ctx->rk = RK = ctx->buf;
|
||||
|
||||
-#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
|
||||
+#if defined(MBEDTLS_AESNI_C)
|
||||
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
|
||||
return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) );
|
||||
#endif
|
||||
@@ -621,7 +621,7 @@
|
||||
|
||||
ctx->nr = cty.nr;
|
||||
|
||||
-#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
|
||||
+#if defined(MBEDTLS_AESNI_C)
|
||||
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
|
||||
{
|
||||
mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk,
|
||||
@@ -850,7 +850,7 @@
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
-#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
|
||||
+#if defined(MBEDTLS_AESNI_C)
|
||||
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
|
||||
return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
|
||||
#endif
|
||||
diff -ruN polarssl-master/library/aesni.c polarssl/library/aesni.c
|
||||
--- polarssl-master/library/aesni.c 2018-03-16 11:25:12.000000000 -0500
|
||||
+++ polarssl/library/aesni.c 2018-04-17 16:09:26.050605000 -0500
|
||||
@@ -30,7 +30,16 @@
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
-#if defined(MBEDTLS_AESNI_C)
|
||||
+
|
||||
+/*
|
||||
+ * despair: This code appears to be 32-bit clean. Remove the CPP macros
|
||||
+ * that restrict usage to AMD64 and EM64T processors.
|
||||
+ * Obviously, you still need to have this insn set available in order to
|
||||
+ * use it in either of protected or long mode anyway.
|
||||
+ * GCC or Clang only, no MSVC here, sorry. (Must pass -march=core2 or later
|
||||
+ * if your compiler's default is anything older or generic.)
|
||||
+ */
|
||||
+#if defined(MBEDTLS_AESNI_C) && !defined(_MSC_VER)
|
||||
|
||||
#include "mbedtls/aesni.h"
|
||||
|
||||
@@ -40,8 +49,6 @@
|
||||
#define asm __asm
|
||||
#endif
|
||||
|
||||
-#if defined(MBEDTLS_HAVE_X86_64)
|
||||
-
|
||||
/*
|
||||
* AES-NI support detection routine
|
||||
*/
|
||||
@@ -459,6 +466,4 @@
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
-#endif /* MBEDTLS_HAVE_X86_64 */
|
||||
-
|
||||
#endif /* MBEDTLS_AESNI_C */
|
||||
diff -ruN polarssl-master/library/entropy_poll.c polarssl/library/entropy_poll.c
|
||||
--- polarssl-master/library/entropy_poll.c 2018-03-16 11:25:12.000000000 -0500
|
||||
+++ polarssl/library/entropy_poll.c 2018-04-17 15:52:13.013004200 -0500
|
||||
@@ -56,6 +56,12 @@
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
+/*
|
||||
+ * WARNING(despair): The next release of PolarSSL will remove the existing codepaths
|
||||
+ * to enable Windows RT and UWP app support. This also breaks NT 5.x and early Longhorn.
|
||||
+ *
|
||||
+ * TODO(despair): create CPP macro to switch between old and new CAPI codepaths
|
||||
+ */
|
||||
int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len,
|
||||
size_t *olen )
|
||||
{
|
||||
diff -ruN polarssl-master/library/gcm.c polarssl/library/gcm.c
|
||||
--- polarssl-master/library/gcm.c 2018-03-16 11:25:12.000000000 -0500
|
||||
+++ polarssl/library/gcm.c 2018-04-17 16:53:18.630262400 -0500
|
||||
@@ -126,7 +126,7 @@
|
||||
ctx->HL[8] = vl;
|
||||
ctx->HH[8] = vh;
|
||||
|
||||
-#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
|
||||
+#if defined(MBEDTLS_AESNI_C)
|
||||
/* With CLMUL support, we need only h, not the rest of the table */
|
||||
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
|
||||
return( 0 );
|
||||
@@ -217,7 +217,7 @@
|
||||
unsigned char lo, hi, rem;
|
||||
uint64_t zh, zl;
|
||||
|
||||
-#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
|
||||
+#if defined(MBEDTLS_AESNI_C)
|
||||
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
|
||||
unsigned char h[16];
|
||||
|
||||
diff -ruN polarssl-master/library/net_sockets.c polarssl/library/net_sockets.c
|
||||
--- polarssl-master/library/net_sockets.c 2018-03-16 11:25:12.000000000 -0500
|
||||
+++ polarssl/library/net_sockets.c 2018-04-17 15:50:08.118440600 -0500
|
||||
@@ -51,7 +51,8 @@
|
||||
/* Enables getaddrinfo() & Co */
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#include <ws2tcpip.h>
|
||||
-
|
||||
+/* despair: re-enable Windows 2000/XP */
|
||||
+#include <wspiapi.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,95 @@
|
||||
/**
|
||||
* sysconf.h -- system-dependent macros and settings
|
||||
*
|
||||
* Copyright (C) 2002-2004 Cosmin Truta.
|
||||
* Permission to use and distribute freely.
|
||||
* No warranty.
|
||||
**/
|
||||
|
||||
#ifndef SYSCONF_H
|
||||
#define SYSCONF_H
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Platform identifiers */
|
||||
|
||||
|
||||
/* Detect Unix. */
|
||||
#if defined(unix) || defined(__linux__) || defined(BSD) || defined(__CYGWIN__)
|
||||
/* Add more systems here. */
|
||||
# ifndef UNIX
|
||||
# define UNIX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Detect MS-DOS. */
|
||||
#if defined(__MSDOS__)
|
||||
# ifndef MSDOS
|
||||
# define MSDOS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* TO DO: Detect OS/2. */
|
||||
|
||||
/* Detect Windows. */
|
||||
#if defined(_WIN32) || defined(__WIN32__)
|
||||
# ifndef WIN32
|
||||
# define WIN32
|
||||
# endif
|
||||
#endif
|
||||
#if defined(_WIN64)
|
||||
# ifndef WIN64
|
||||
# define WIN64
|
||||
# endif
|
||||
#endif
|
||||
#if defined(_WINDOWS) || defined(WIN32) || defined(WIN64)
|
||||
# ifndef WINDOWS
|
||||
# define WINDOWS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Enable POSIX-friendly symbols on Microsoft (Visual) C. */
|
||||
#ifdef _MSC_VER
|
||||
# define _POSIX_
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Library access */
|
||||
|
||||
|
||||
#if defined(UNIX)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(_POSIX_VERSION)
|
||||
# include <fcntl.h>
|
||||
# ifndef HAVE_ISATTY
|
||||
# define HAVE_ISATTY
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(MSDOS) || defined(OS2) || defined(WINDOWS) || defined(__CYGWIN__)
|
||||
/* Add more systems here, e.g. MacOS 9 and earlier. */
|
||||
# include <fcntl.h>
|
||||
# include <io.h>
|
||||
# ifndef HAVE_ISATTY
|
||||
# define HAVE_ISATTY
|
||||
# endif
|
||||
# ifndef HAVE_SETMODE
|
||||
# define HAVE_SETMODE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Standard I/O handles. */
|
||||
#define STDIN 0
|
||||
#define STDOUT 1
|
||||
#define STDERR 2
|
||||
|
||||
/* Provide a placeholder for O_BINARY, if it doesn't exist. */
|
||||
#ifndef O_BINARY
|
||||
# define O_BINARY 0
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* SYSCONF_H */
|
@ -0,0 +1,204 @@
|
||||
/* zpipe.c: example of proper use of zlib's inflate() and deflate()
|
||||
Not copyrighted -- provided to the public domain
|
||||
Version 1.4 11 December 2005 Mark Adler */
|
||||
|
||||
/* Version history:
|
||||
1.0 30 Oct 2004 First version
|
||||
1.1 8 Nov 2004 Add void casting for unused return values
|
||||
Use switch statement for inflate() return values
|
||||
1.2 9 Nov 2004 Add assertions to document zlib guarantees
|
||||
1.3 6 Apr 2005 Remove incorrect assertion in inf()
|
||||
1.4 11 Dec 2005 Add hack to avoid MSDOS end-of-line conversions
|
||||
Avoid some compiler warnings for input and output buffers
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "miniz.h"
|
||||
|
||||
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
|
||||
# include <fcntl.h>
|
||||
# include <io.h>
|
||||
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
|
||||
#else
|
||||
# define SET_BINARY_MODE(file)
|
||||
#endif
|
||||
|
||||
#define CHUNK 16384
|
||||
|
||||
/* Compress from file source to file dest until EOF on source.
|
||||
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
|
||||
allocated for processing, Z_STREAM_ERROR if an invalid compression
|
||||
level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
|
||||
version of the library linked do not match, or Z_ERRNO if there is
|
||||
an error reading or writing the files. */
|
||||
int def(FILE *source, FILE *dest, int level)
|
||||
{
|
||||
int ret, flush;
|
||||
unsigned have;
|
||||
z_stream strm;
|
||||
unsigned char in[CHUNK];unsigned char out[CHUNK];
|
||||
|
||||
/* allocate deflate state */
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
ret = deflateInit(&strm, level);
|
||||
if (ret != Z_OK)
|
||||
return ret;
|
||||
|
||||
/* compress until end of file */
|
||||
do {
|
||||
strm.avail_in = fread(in, 1, CHUNK, source);
|
||||
if (ferror(source)) {
|
||||
(void)deflateEnd(&strm);
|
||||
return Z_ERRNO;
|
||||
}
|
||||
flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
|
||||
strm.next_in = in;
|
||||
|
||||
/* run deflate() on input until output buffer not full, finish
|
||||
compression if all of source has been read in */
|
||||
do {
|
||||
strm.avail_out = CHUNK;
|
||||
strm.next_out = out;
|
||||
ret = deflate(&strm, flush); /* no bad return value */
|
||||
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
|
||||
have = CHUNK - strm.avail_out;
|
||||
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
|
||||
(void)deflateEnd(&strm);
|
||||
return Z_ERRNO;
|
||||
}
|
||||
} while (strm.avail_out == 0);
|
||||
assert(strm.avail_in == 0); /* all input will be used */
|
||||
|
||||
/* done when last data in file processed */
|
||||
} while (flush != Z_FINISH);
|
||||
assert(ret == Z_STREAM_END); /* stream will be complete */
|
||||
|
||||
/* clean up and return */
|
||||
(void)deflateEnd(&strm);
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
/* Decompress from file source to file dest until stream ends or EOF.
|
||||
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
|
||||
allocated for processing, Z_DATA_ERROR if the deflate data is
|
||||
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
|
||||
the version of the library linked do not match, or Z_ERRNO if there
|
||||
is an error reading or writing the files. */
|
||||
int inf(FILE *source, FILE *dest)
|
||||
{
|
||||
int ret;
|
||||
unsigned have;
|
||||
z_stream strm;
|
||||
unsigned char in[CHUNK];
|
||||
unsigned char out[CHUNK];
|
||||
|
||||
/* allocate inflate state */
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
strm.avail_in = 0;
|
||||
strm.next_in = Z_NULL;
|
||||
ret = inflateInit(&strm);
|
||||
if (ret != Z_OK)
|
||||
return ret;
|
||||
|
||||
/* decompress until deflate stream ends or end of file */
|
||||
do {
|
||||
strm.avail_in = fread(in, 1, CHUNK, source);
|
||||
if (ferror(source)) {
|
||||
(void)inflateEnd(&strm);
|
||||
return Z_ERRNO;
|
||||
}
|
||||
if (strm.avail_in == 0)
|
||||
break;
|
||||
strm.next_in = in;
|
||||
|
||||
/* run inflate() on input until output buffer not full */
|
||||
do {
|
||||
strm.avail_out = CHUNK;
|
||||
strm.next_out = out;
|
||||
ret = inflate(&strm, Z_NO_FLUSH);
|
||||
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
|
||||
switch (ret) {
|
||||
case Z_NEED_DICT:
|
||||
ret = Z_DATA_ERROR; /* and fall through */
|
||||
case Z_DATA_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
(void)inflateEnd(&strm);
|
||||
return ret;
|
||||
}
|
||||
have = CHUNK - strm.avail_out;
|
||||
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
|
||||
(void)inflateEnd(&strm);
|
||||
return Z_ERRNO;
|
||||
}
|
||||
} while (strm.avail_out == 0);
|
||||
|
||||
/* done when inflate() says it's done */
|
||||
} while (ret != Z_STREAM_END);
|
||||
|
||||
/* clean up and return */
|
||||
(void)inflateEnd(&strm);
|
||||
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
|
||||
}
|
||||
|
||||
/* report a zlib or i/o error */
|
||||
void zerr(int ret)
|
||||
{
|
||||
fputs("zpipe: ", stderr);
|
||||
switch (ret) {
|
||||
case Z_ERRNO:
|
||||
if (ferror(stdin))
|
||||
fputs("error reading stdin\n", stderr);
|
||||
if (ferror(stdout))
|
||||
fputs("error writing stdout\n", stderr);
|
||||
break;
|
||||
case Z_STREAM_ERROR:
|
||||
fputs("invalid compression level\n", stderr);
|
||||
break;
|
||||
case Z_DATA_ERROR:
|
||||
fputs("invalid or incomplete deflate data\n", stderr);
|
||||
break;
|
||||
case Z_MEM_ERROR:
|
||||
fputs("out of memory\n", stderr);
|
||||
break;
|
||||
case Z_VERSION_ERROR:
|
||||
fputs("zlib version mismatch!\n", stderr);
|
||||
}
|
||||
}
|
||||
|
||||
/* compress or decompress from stdin to stdout */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* avoid end-of-line conversions */
|
||||
SET_BINARY_MODE(stdin);
|
||||
SET_BINARY_MODE(stdout);
|
||||
|
||||
/* do compression if no arguments */
|
||||
if (argc == 1) {
|
||||
ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
|
||||
if (ret != Z_OK)
|
||||
zerr(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* do decompression if -d specified */
|
||||
else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
|
||||
ret = inf(stdin, stdout);
|
||||
if (ret != Z_OK)
|
||||
zerr(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* otherwise, report usage */
|
||||
else {
|
||||
fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
# TUN/TAP driver v9 for Windows
|
||||
|
||||
in order to set up tunnels on Windows, you will need
|
||||
to instal this driver.
|
||||
|
||||
* v9.9.2.3 is for Windows 2000/XP/2003 (NDIS 5.0-based)
|
||||
* v9.21.2 is for Windows Vista/7/8.1 and 10 (NDIS 6.0, forward-compatible with NDIS 10.0)
|
||||
|
||||
to instal, extract the corresponding version of the driver for your
|
||||
platform and run `%ARCH%/install_tap.cmd` in an elevated shell
|
||||
|
||||
to remove *ALL* virtual tunnel adapters, run `%ARCH%/del_tap.cmd` in an elevated shell. Use the
|
||||
Device Manager snap-in to remove individual adapter instances.
|
||||
|
||||
Both are signed by OpenVPN Inc, and are available for 32- and 64-bit archs.
|
||||
|
||||
-despair86
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,10 @@
|
||||
FROM debian:latest
|
||||
|
||||
RUN apt update && \
|
||||
apt install -y build-essential cmake git libcap-dev wget rapidjson-dev
|
||||
|
||||
WORKDIR /src/
|
||||
|
||||
COPY . /src/
|
||||
|
||||
RUN make -j 8 JSONRPC=ON
|
@ -0,0 +1,11 @@
|
||||
FROM fedora:latest
|
||||
|
||||
RUN dnf update -y && \
|
||||
dnf upgrade -y && \
|
||||
dnf install -y cmake make git gcc gcc-c++ libcap-devel wget rapidjson-devel
|
||||
|
||||
WORKDIR /src/
|
||||
|
||||
COPY . /src/
|
||||
|
||||
RUN make -j8 JSONRPC=ON
|
@ -0,0 +1,29 @@
|
||||
#ifndef LLARP_STRING_VIEW_HPP
|
||||
#define LLARP_STRING_VIEW_HPP
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
#include <string_view>
|
||||
#include <string>
|
||||
namespace llarp
|
||||
{
|
||||
typedef std::string_view string_view;
|
||||
static std::string
|
||||
string_view_string(const string_view& v)
|
||||
{
|
||||
return std::string(v.data(), v.size());
|
||||
}
|
||||
} // namespace llarp
|
||||
#else
|
||||
#include <string>
|
||||
namespace llarp
|
||||
{
|
||||
typedef std::string string_view;
|
||||
|
||||
static std::string
|
||||
string_view_string(const string_view& v)
|
||||
{
|
||||
return v;
|
||||
};
|
||||
} // namespace llarp
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,118 @@
|
||||
#ifndef __ABYSS_CLIENT_HPP__
|
||||
#define __ABYSS_CLIENT_HPP__
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <llarp/string_view.hpp>
|
||||
#include <abyss/json.hpp>
|
||||
#include <llarp/ev.h>
|
||||
|
||||
namespace abyss
|
||||
{
|
||||
namespace http
|
||||
{
|
||||
typedef std::string RPC_Method_t;
|
||||
typedef json::Value RPC_Params;
|
||||
typedef json::Document RPC_Response;
|
||||
typedef std::unordered_multimap< std::string, std::string > Headers_t;
|
||||
struct ConnImpl;
|
||||
|
||||
/// jsonrpc response handler for client
|
||||
struct IRPCClientHandler
|
||||
{
|
||||
IRPCClientHandler(ConnImpl* impl);
|
||||
virtual ~IRPCClientHandler();
|
||||
|
||||
/// handle response from rpc server
|
||||
/// return true on successful handling
|
||||
/// return false on errors while handling
|
||||
virtual bool
|
||||
HandleResponse(const RPC_Response& response) = 0;
|
||||
|
||||
/// populate http request headers
|
||||
virtual void
|
||||
PopulateReqHeaders(Headers_t& hdr) = 0;
|
||||
|
||||
/// handle fatal internal error while doing request
|
||||
virtual void
|
||||
HandleError() = 0;
|
||||
|
||||
/// return true if we should close
|
||||
bool
|
||||
ShouldClose() const;
|
||||
|
||||
/// close underlying connection
|
||||
void
|
||||
Close() const;
|
||||
|
||||
private:
|
||||
ConnImpl* m_Impl;
|
||||
};
|
||||
|
||||
/// jsonrpc client
|
||||
struct JSONRPC
|
||||
{
|
||||
typedef std::function< IRPCClientHandler*(ConnImpl*) > HandlerFactory;
|
||||
|
||||
JSONRPC();
|
||||
~JSONRPC();
|
||||
|
||||
/// start runing on event loop async
|
||||
/// return true on success otherwise return false
|
||||
bool
|
||||
RunAsync(llarp_ev_loop* loop, const std::string& endpoint);
|
||||
|
||||
/// must be called after RunAsync returns true
|
||||
/// queue a call for rpc
|
||||
void
|
||||
QueueRPC(RPC_Method_t method, RPC_Params params,
|
||||
HandlerFactory createHandler);
|
||||
|
||||
/// drop all pending calls on the floor
|
||||
void
|
||||
DropAllCalls();
|
||||
|
||||
/// handle new outbound connection
|
||||
void
|
||||
Connected(llarp_tcp_conn* conn);
|
||||
|
||||
/// flush queued rpc calls
|
||||
void
|
||||
Flush();
|
||||
|
||||
private:
|
||||
struct Call
|
||||
{
|
||||
Call(RPC_Method_t&& m, RPC_Params&& p, HandlerFactory&& f)
|
||||
: method(std::move(m))
|
||||
, params(std::move(p))
|
||||
, createHandler(std::move(f))
|
||||
{
|
||||
}
|
||||
RPC_Method_t method;
|
||||
RPC_Params params;
|
||||
HandlerFactory createHandler;
|
||||
};
|
||||
|
||||
static void
|
||||
OnConnected(llarp_tcp_connecter* connect, llarp_tcp_conn* conn);
|
||||
|
||||
static void
|
||||
OnConnectFail(llarp_tcp_connecter* connect);
|
||||
|
||||
static void
|
||||
OnTick(llarp_tcp_connecter* connect);
|
||||
|
||||
llarp_tcp_connecter m_connect;
|
||||
llarp_ev_loop* m_Loop;
|
||||
std::deque< Call > m_PendingCalls;
|
||||
std::list< std::unique_ptr< IRPCClientHandler > > m_Conns;
|
||||
};
|
||||
|
||||
} // namespace http
|
||||
} // namespace abyss
|
||||
|
||||
#endif
|
@ -0,0 +1,36 @@
|
||||
#ifndef __ABYSS_HTTP_HPP__
|
||||
#define __ABYSS_HTTP_HPP__
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <llarp/string_view.hpp>
|
||||
#include <abyss/json.hpp>
|
||||
|
||||
namespace abyss
|
||||
{
|
||||
namespace http
|
||||
{
|
||||
struct RequestHeader
|
||||
{
|
||||
typedef std::unordered_multimap< std::string, std::string > Headers_t;
|
||||
Headers_t Headers;
|
||||
std::string Method;
|
||||
std::string Path;
|
||||
};
|
||||
|
||||
struct HeaderReader
|
||||
{
|
||||
RequestHeader Header;
|
||||
virtual ~HeaderReader()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessHeaderLine(abyss::string_view line, bool& done);
|
||||
|
||||
virtual bool
|
||||
ShouldProcessHeader(const abyss::string_view& line) const = 0;
|
||||
};
|
||||
|
||||
} // namespace http
|
||||
} // namespace abyss
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
#ifndef __LIB_ABYSS_HPP__
|
||||
#define __LIB_ABYSS_HPP__
|
||||
#include <abyss/server.hpp>
|
||||
#include <abyss/json.hpp>
|
||||
#include <abyss/client.hpp>
|
||||
#endif
|
||||
|
@ -0,0 +1,399 @@
|
||||
#include <abyss/client.hpp>
|
||||
#include <abyss/http.hpp>
|
||||
#include <llarp/logger.hpp>
|
||||
#include <llarp/crypto.hpp>
|
||||
|
||||
namespace abyss
|
||||
{
|
||||
namespace http
|
||||
{
|
||||
struct ConnImpl : HeaderReader
|
||||
{
|
||||
// big
|
||||
static const size_t MAX_BODY_SIZE = (1024 * 1024);
|
||||
llarp_tcp_conn* m_Conn;
|
||||
json::Document m_RequestBody;
|
||||
Headers_t m_SendHeaders;
|
||||
IRPCClientHandler* handler;
|
||||
std::unique_ptr< abyss::json::IParser > m_BodyParser;
|
||||
json::Document m_Response;
|
||||
|
||||
enum State
|
||||
{
|
||||
eInitial,
|
||||
eReadStatusLine,
|
||||
eReadResponseHeader,
|
||||
eReadResponseBody,
|
||||
eCloseMe
|
||||
};
|
||||
|
||||
State state;
|
||||
|
||||
ConnImpl(llarp_tcp_conn* conn, RPC_Method_t method, RPC_Params params,
|
||||
JSONRPC::HandlerFactory factory)
|
||||
: m_Conn(conn), state(eInitial)
|
||||
{
|
||||
srand(time(nullptr));
|
||||
conn->user = this;
|
||||
conn->closed = &ConnImpl::OnClosed;
|
||||
conn->read = &ConnImpl::OnRead;
|
||||
conn->tick = &ConnImpl::OnTick;
|
||||
|
||||
handler = factory(this);
|
||||
|
||||
m_RequestBody.SetObject();
|
||||
auto& alloc = m_RequestBody.GetAllocator();
|
||||
m_RequestBody.AddMember("jsonrpc", json::Value().SetString("2.0"),
|
||||
alloc);
|
||||
m_RequestBody.AddMember("id", json::Value(abs(rand())), alloc);
|
||||
m_RequestBody.AddMember(
|
||||
"method", json::Value().SetString(method.c_str(), alloc), alloc);
|
||||
m_RequestBody.AddMember("params", params, alloc);
|
||||
}
|
||||
|
||||
static void
|
||||
OnClosed(llarp_tcp_conn* conn)
|
||||
{
|
||||
ConnImpl* self = static_cast< ConnImpl* >(conn->user);
|
||||
self->state = eCloseMe;
|
||||
}
|
||||
|
||||
static void
|
||||
OnRead(llarp_tcp_conn* conn, const void* buf, size_t sz)
|
||||
{
|
||||
ConnImpl* self = static_cast< ConnImpl* >(conn->user);
|
||||
if(!self->ProcessRead((const char*)buf, sz))
|
||||
self->CloseError();
|
||||
}
|
||||
|
||||
static void
|
||||
OnTick(llarp_tcp_conn* conn)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessStatusLine(string_view line) const
|
||||
{
|
||||
auto idx = line.find_first_of(' ');
|
||||
if(idx == string_view::npos)
|
||||
return false;
|
||||
|
||||
string_view codePart = line.substr(1 + idx);
|
||||
idx = codePart.find_first_of(' ');
|
||||
|
||||
if(idx == string_view::npos)
|
||||
return false;
|
||||
return HandleStatusCode(codePart.substr(0, idx));
|
||||
}
|
||||
|
||||
bool
|
||||
ShouldProcessHeader(const abyss::string_view& name) const
|
||||
{
|
||||
return name == "content-length" || name == "content-type";
|
||||
}
|
||||
|
||||
/// return true if we get a 200 status code
|
||||
bool
|
||||
HandleStatusCode(string_view code) const
|
||||
{
|
||||
return code == "200";
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessBody(const char* buf, size_t sz)
|
||||
{
|
||||
// init parser
|
||||
if(m_BodyParser == nullptr)
|
||||
{
|
||||
size_t contentSize = 0;
|
||||
auto itr = Header.Headers.find("content-length");
|
||||
// no content-length header
|
||||
if(itr == Header.Headers.end())
|
||||
return false;
|
||||
|
||||
// check size
|
||||
contentSize = std::stoul(itr->second);
|
||||
if(contentSize > MAX_BODY_SIZE)
|
||||
return false;
|
||||
|
||||
m_BodyParser.reset(abyss::json::MakeParser(contentSize));
|
||||
}
|
||||
if(m_BodyParser && m_BodyParser->FeedData(buf, sz))
|
||||
{
|
||||
switch(m_BodyParser->Parse(m_Response))
|
||||
{
|
||||
case json::IParser::eNeedData:
|
||||
return true;
|
||||
case json::IParser::eDone:
|
||||
handler->HandleResponse(m_Response);
|
||||
Close();
|
||||
return true;
|
||||
case json::IParser::eParseError:
|
||||
handler->HandleError();
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessRead(const char* buf, size_t sz)
|
||||
{
|
||||
if(state == eInitial)
|
||||
return true;
|
||||
if(sz == 0)
|
||||
return true;
|
||||
bool done = false;
|
||||
while(state < eReadResponseBody)
|
||||
{
|
||||
const char* end = strstr(buf, "\r\n");
|
||||
if(end == nullptr)
|
||||
return false;
|
||||
string_view line(buf, end - buf);
|
||||
switch(state)
|
||||
{
|
||||
case eReadStatusLine:
|
||||
if(!ProcessStatusLine(line))
|
||||
return false;
|
||||
sz -= line.size() + (2 * sizeof(char));
|
||||
state = eReadResponseHeader;
|
||||
break;
|
||||
case eReadResponseHeader:
|
||||
if(!ProcessHeaderLine(line, done))
|
||||
return false;
|
||||
sz -= line.size() + (2 * sizeof(char));
|
||||
if(done)
|
||||
state = eReadResponseBody;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
buf = end + (2 * sizeof(char));
|
||||
end = strstr(buf, "\r\n");
|
||||
}
|
||||
if(state == eReadResponseBody)
|
||||
return ProcessBody(buf, sz);
|
||||
return state == eCloseMe;
|
||||
}
|
||||
|
||||
bool
|
||||
ShouldClose() const
|
||||
{
|
||||
return state == eCloseMe;
|
||||
}
|
||||
|
||||
void
|
||||
CloseError()
|
||||
{
|
||||
if(handler)
|
||||
handler->HandleError();
|
||||
handler = nullptr;
|
||||
Close();
|
||||
}
|
||||
|
||||
void
|
||||
Close()
|
||||
{
|
||||
if(m_Conn)
|
||||
llarp_tcp_conn_close(m_Conn);
|
||||
m_Conn = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
SendRequest()
|
||||
{
|
||||
// populate request headers
|
||||
handler->PopulateReqHeaders(m_SendHeaders);
|
||||
// create request body
|
||||
std::string body;
|
||||
json::ToString(m_RequestBody, body);
|
||||
// request base
|
||||
char buf[512] = {0};
|
||||
int sz = snprintf(buf, sizeof(buf),
|
||||
"POST /rpc HTTP/1.0\r\nContent-Type: "
|
||||
"application/json\r\nContent-Length: %lu\r\nAccept: "
|
||||
"application/json\r\n",
|
||||
body.size());
|
||||
if(sz <= 0)
|
||||
return;
|
||||
if(!llarp_tcp_conn_async_write(m_Conn, buf, sz))
|
||||
{
|
||||
llarp::LogError("failed to write first part of request");
|
||||
CloseError();
|
||||
return;
|
||||
}
|
||||
// header delimiter
|
||||
buf[0] = ':';
|
||||
buf[1] = ' ';
|
||||
// CRLF
|
||||
buf[2] = '\r';
|
||||
buf[3] = '\n';
|
||||
// write extra request header
|
||||
for(const auto& item : m_SendHeaders)
|
||||
{
|
||||
// header name
|
||||
if(!llarp_tcp_conn_async_write(m_Conn, item.first.c_str(),
|
||||
item.first.size()))
|
||||
{
|
||||
CloseError();
|
||||
return;
|
||||
}
|
||||
// header delimiter
|
||||
if(!llarp_tcp_conn_async_write(m_Conn, buf, 2 * sizeof(char)))
|
||||
{
|
||||
CloseError();
|
||||
return;
|
||||
}
|
||||
// header value
|
||||
if(!llarp_tcp_conn_async_write(m_Conn, item.second.c_str(),
|
||||
item.second.size()))
|
||||
{
|
||||
CloseError();
|
||||
return;
|
||||
}
|
||||
// CRLF
|
||||
if(!llarp_tcp_conn_async_write(m_Conn, buf + 2, 2 * sizeof(char)))
|
||||
{
|
||||
CloseError();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// CRLF
|
||||
if(!llarp_tcp_conn_async_write(m_Conn, buf + 2, 2 * sizeof(char)))
|
||||
{
|
||||
CloseError();
|
||||
return;
|
||||
}
|
||||
// request body
|
||||
if(!llarp_tcp_conn_async_write(m_Conn, body.c_str(), body.size()))
|
||||
{
|
||||
CloseError();
|
||||
return;
|
||||
}
|
||||
llarp::LogDebug("request sent");
|
||||
state = eReadStatusLine;
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
JSONRPC::Flush()
|
||||
{
|
||||
/// close idle connections
|
||||
auto itr = m_Conns.begin();
|
||||
while(itr != m_Conns.end())
|
||||
{
|
||||
if((*itr)->ShouldClose())
|
||||
{
|
||||
(*itr)->Close();
|
||||
itr = m_Conns.erase(itr);
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
// open at most 10 connections
|
||||
size_t numCalls = std::min(m_PendingCalls.size(), 10UL);
|
||||
llarp::LogDebug("tick connect to rpc ", numCalls, " times");
|
||||
while(numCalls--)
|
||||
{
|
||||
llarp_tcp_async_try_connect(m_Loop, &m_connect);
|
||||
}
|
||||
}
|
||||
|
||||
IRPCClientHandler::IRPCClientHandler(ConnImpl* impl) : m_Impl(impl)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
IRPCClientHandler::ShouldClose() const
|
||||
{
|
||||
return m_Impl && m_Impl->ShouldClose();
|
||||
}
|
||||
|
||||
void
|
||||
IRPCClientHandler::Close() const
|
||||
{
|
||||
if(m_Impl)
|
||||
m_Impl->Close();
|
||||
}
|
||||
|
||||
IRPCClientHandler::~IRPCClientHandler()
|
||||
{
|
||||
if(m_Impl)
|
||||
delete m_Impl;
|
||||
}
|
||||
|
||||
JSONRPC::JSONRPC()
|
||||
{
|
||||
}
|
||||
|
||||
JSONRPC::~JSONRPC()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
JSONRPC::QueueRPC(RPC_Method_t method, RPC_Params params,
|
||||
HandlerFactory createHandler)
|
||||
{
|
||||
m_PendingCalls.emplace_back(std::move(method), std::move(params),
|
||||
std::move(createHandler));
|
||||
}
|
||||
|
||||
bool
|
||||
JSONRPC::RunAsync(llarp_ev_loop* loop, const std::string& remote)
|
||||
{
|
||||
strncpy(m_connect.remote, remote.c_str(), sizeof(m_connect.remote));
|
||||
// TODO: ipv6
|
||||
m_connect.connected = &JSONRPC::OnConnected;
|
||||
m_connect.error = &JSONRPC::OnConnectFail;
|
||||
m_connect.user = this;
|
||||
m_connect.af = AF_INET;
|
||||
m_Loop = loop;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
JSONRPC::OnConnectFail(llarp_tcp_connecter* tcp)
|
||||
{
|
||||
JSONRPC* self = static_cast< JSONRPC* >(tcp->user);
|
||||
llarp::LogError("failed to connect to RPC, dropped all pending calls");
|
||||
self->DropAllCalls();
|
||||
}
|
||||
|
||||
void
|
||||
JSONRPC::OnConnected(llarp_tcp_connecter* tcp, llarp_tcp_conn* conn)
|
||||
{
|
||||
JSONRPC* self = static_cast< JSONRPC* >(tcp->user);
|
||||
llarp::LogDebug("connected to RPC");
|
||||
self->Connected(conn);
|
||||
}
|
||||
|
||||
void
|
||||
JSONRPC::Connected(llarp_tcp_conn* conn)
|
||||
{
|
||||
auto& front = m_PendingCalls.front();
|
||||
ConnImpl* connimpl =
|
||||
new ConnImpl(conn, std::move(front.method), std::move(front.params),
|
||||
std::move(front.createHandler));
|
||||
m_PendingCalls.pop_front();
|
||||
m_Conns.emplace_back(connimpl->handler);
|
||||
connimpl->SendRequest();
|
||||
}
|
||||
|
||||
void
|
||||
JSONRPC::DropAllCalls()
|
||||
{
|
||||
while(m_PendingCalls.size())
|
||||
{
|
||||
auto& front = m_PendingCalls.front();
|
||||
IRPCClientHandler* h = front.createHandler(nullptr);
|
||||
h->HandleError();
|
||||
delete h;
|
||||
m_PendingCalls.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace http
|
||||
} // namespace abyss
|
@ -0,0 +1,36 @@
|
||||
#include <abyss/http.hpp>
|
||||
#include <algorithm>
|
||||
namespace abyss
|
||||
{
|
||||
namespace http
|
||||
{
|
||||
bool
|
||||
HeaderReader::ProcessHeaderLine(string_view line, bool& done)
|
||||
{
|
||||
if(line.size() == 0)
|
||||
{
|
||||
done = true;
|
||||
return true;
|
||||
}
|
||||
auto idx = line.find_first_of(':');
|
||||
if(idx == string_view::npos)
|
||||
return false;
|
||||
string_view header = line.substr(0, idx);
|
||||
string_view val = line.substr(1 + idx);
|
||||
// to lowercase
|
||||
std::string lowerHeader;
|
||||
auto itr = header.begin();
|
||||
while(itr != header.end())
|
||||
{
|
||||
lowerHeader += ::tolower(*itr);
|
||||
++itr;
|
||||
}
|
||||
if(ShouldProcessHeader(string_view(lowerHeader)))
|
||||
{
|
||||
val = val.substr(val.find_first_not_of(' '));
|
||||
Header.Headers.insert(std::make_pair(lowerHeader, val));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace http
|
||||
} // namespace abyss
|
Binary file not shown.
@ -0,0 +1,190 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <libabyss.hpp>
|
||||
#include <llarp/ev.h>
|
||||
#include <llarp/threading.hpp>
|
||||
#include <llarp/net.hpp>
|
||||
|
||||
struct AbyssTestBase : public ::testing::Test
|
||||
{
|
||||
llarp_crypto crypto;
|
||||
llarp_threadpool* threadpool = nullptr;
|
||||
llarp_ev_loop* loop = nullptr;
|
||||
llarp_logic* logic = nullptr;
|
||||
abyss::httpd::BaseReqHandler* server = nullptr;
|
||||
abyss::http::JSONRPC* client = nullptr;
|
||||
const std::string method = "test.method";
|
||||
bool called = false;
|
||||
|
||||
void
|
||||
AssertMethod(const std::string& meth) const
|
||||
{
|
||||
ASSERT_TRUE(meth == method);
|
||||
}
|
||||
|
||||
void
|
||||
SetUp()
|
||||
{
|
||||
// for llarp_randint
|
||||
llarp_crypto_init(&crypto);
|
||||
}
|
||||
|
||||
static void
|
||||
CancelIt(void* u, uint64_t orig, uint64_t left)
|
||||
{
|
||||
if(left)
|
||||
return;
|
||||
static_cast< AbyssTestBase* >(u)->Stop();
|
||||
}
|
||||
|
||||
void
|
||||
Start()
|
||||
{
|
||||
threadpool = llarp_init_same_process_threadpool();
|
||||
llarp_ev_loop_alloc(&loop);
|
||||
logic = llarp_init_single_process_logic(threadpool);
|
||||
|
||||
sockaddr_in addr;
|
||||
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
addr.sin_port = htons((llarp_randint() % 2000) + 2000);
|
||||
addr.sin_family = AF_INET;
|
||||
llarp::Addr a(addr);
|
||||
while(true)
|
||||
{
|
||||
if(server->ServeAsync(loop, logic, a))
|
||||
{
|
||||
client->RunAsync(loop, a.ToString());
|
||||
llarp_logic_call_later(logic, {1000, this, &CancelIt});
|
||||
return;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Stop()
|
||||
{
|
||||
if(server)
|
||||
server->Close();
|
||||
llarp_logic_stop(logic);
|
||||
llarp_ev_loop_stop(loop);
|
||||
llarp_threadpool_stop(threadpool);
|
||||
}
|
||||
|
||||
void
|
||||
TearDown()
|
||||
{
|
||||
if(loop && threadpool && logic)
|
||||
{
|
||||
llarp_free_logic(&logic);
|
||||
llarp_ev_loop_free(&loop);
|
||||
llarp_free_threadpool(&threadpool);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct ClientHandler : public abyss::http::IRPCClientHandler
|
||||
{
|
||||
AbyssTestBase* test;
|
||||
ClientHandler(abyss::http::ConnImpl* impl, AbyssTestBase* parent)
|
||||
: abyss::http::IRPCClientHandler(impl), test(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HandleError()
|
||||
{
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
|
||||
void
|
||||
PopulateReqHeaders(abyss::http::Headers_t& hdr)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
HandleResponse(const abyss::http::RPC_Response& response)
|
||||
{
|
||||
test->Stop();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct ServerHandler : public abyss::httpd::IRPCHandler
|
||||
{
|
||||
AbyssTestBase* test;
|
||||
ServerHandler(abyss::httpd::ConnImpl* impl, AbyssTestBase* parent)
|
||||
: abyss::httpd::IRPCHandler(impl), test(parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
HandleJSONRPC(Method_t method, const Params& params, Response& response)
|
||||
{
|
||||
test->AssertMethod(method);
|
||||
test->called = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct AbyssTest : public AbyssTestBase,
|
||||
public abyss::http::JSONRPC,
|
||||
public abyss::httpd::BaseReqHandler
|
||||
{
|
||||
AbyssTest()
|
||||
: AbyssTestBase()
|
||||
, abyss::http::JSONRPC()
|
||||
, abyss::httpd::BaseReqHandler(1000)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
abyss::http::IRPCClientHandler*
|
||||
NewConn(abyss::http::ConnImpl* impl)
|
||||
{
|
||||
return new ClientHandler(impl, this);
|
||||
}
|
||||
|
||||
abyss::httpd::IRPCHandler*
|
||||
CreateHandler(abyss::httpd::ConnImpl* impl)
|
||||
{
|
||||
return new ServerHandler(impl, this);
|
||||
}
|
||||
|
||||
void
|
||||
SetUp()
|
||||
{
|
||||
AbyssTestBase::SetUp();
|
||||
client = this;
|
||||
server = this;
|
||||
}
|
||||
|
||||
static void
|
||||
FlushIt(void* u)
|
||||
{
|
||||
static_cast< AbyssTest* >(u)->Flush();
|
||||
}
|
||||
|
||||
void
|
||||
AsyncFlush()
|
||||
{
|
||||
llarp_logic_queue_job(logic, {this, &FlushIt});
|
||||
}
|
||||
|
||||
void
|
||||
RunLoop()
|
||||
{
|
||||
llarp_ev_loop_run_single_process(loop, threadpool, logic);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(AbyssTest, TestClientAndServer)
|
||||
{
|
||||
Start();
|
||||
abyss::json::Value params;
|
||||
params.SetObject();
|
||||
QueueRPC(method, std::move(params),
|
||||
std::bind(&AbyssTest::NewConn, this, std::placeholders::_1));
|
||||
AsyncFlush();
|
||||
RunLoop();
|
||||
ASSERT_TRUE(called);
|
||||
};
|
Binary file not shown.
@ -0,0 +1,137 @@
|
||||
; Script generated by the Inno Script Studio Wizard.
|
||||
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||
|
||||
#define MyAppName "loki-network"
|
||||
#define MyAppVersion "0.3.0"
|
||||
#define MyAppPublisher "Loki Project"
|
||||
#define MyAppURL "https://loki.network"
|
||||
#define MyAppExeName "lokinet.exe"
|
||||
; change this to avoid compiler errors -despair
|
||||
#define DevPath "D:\dev\external\llarp\"
|
||||
#include <idp.iss>
|
||||
|
||||
; see ../LICENSE
|
||||
|
||||
[Setup]
|
||||
; NOTE: The value of AppId uniquely identifies this application.
|
||||
; Do not use the same AppId value in installers for other applications.
|
||||
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
||||
AppId={{11335EAC-0385-4C78-A3AA-67731326B653}
|
||||
AppName={#MyAppName}
|
||||
AppVersion={#MyAppVersion}
|
||||
;AppVerName={#MyAppName} {#MyAppVersion}
|
||||
AppPublisher={#MyAppPublisher}
|
||||
AppPublisherURL={#MyAppURL}
|
||||
AppSupportURL={#MyAppURL}
|
||||
AppUpdatesURL={#MyAppURL}
|
||||
DefaultDirName={pf}\{#MyAppPublisher}\{#MyAppName}
|
||||
DefaultGroupName={#MyAppName}
|
||||
AllowNoIcons=yes
|
||||
LicenseFile={#DevPath}LICENSE
|
||||
OutputDir={#DevPath}win32-setup
|
||||
OutputBaseFilename=lokinet-win32
|
||||
Compression=lzma
|
||||
SolidCompression=yes
|
||||
VersionInfoVersion=0.3.0
|
||||
VersionInfoCompany=Loki Project
|
||||
VersionInfoDescription=lokinet for windows
|
||||
VersionInfoTextVersion=0.3.0-dev
|
||||
VersionInfoProductName=loki-network
|
||||
VersionInfoProductVersion=0.3.0
|
||||
VersionInfoProductTextVersion=0.3.0-dev
|
||||
InternalCompressLevel=ultra64
|
||||
MinVersion=0,5.0
|
||||
ArchitecturesInstallIn64BitMode=x64
|
||||
VersionInfoCopyright=Copyright ©2018 Loki Project
|
||||
AlwaysRestart=yes
|
||||
|
||||
[Languages]
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
|
||||
[Tasks]
|
||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
|
||||
|
||||
[Files]
|
||||
; we're grabbing the builds from jenkins-ci now, which are fully linked
|
||||
; only one of these is installed
|
||||
Source: "{#DevPath}build\lokinet.exe"; DestDir: "{app}"; Flags: ignoreversion 32bit; Check: not IsWin64
|
||||
Source: "{#DevPath}build\lokinet64.exe"; DestDir: "{app}"; Flags: ignoreversion 64bit; Check: IsWin64
|
||||
; eh, might as well ship the 32-bit port of everything else
|
||||
Source: "{#DevPath}build\dns.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "{#DevPath}build\llarpc.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "{#DevPath}build\rcutil.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
; delet this after finishing setup, we only need it to extract the drivers
|
||||
; and download an initial RC
|
||||
Source: "{#DevPath}lokinet-bootstrap.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall
|
||||
Source: "{#DevPath}win32-setup\7z.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall
|
||||
Source: "{tmp}\inet6.7z"; DestDir: "{app}"; Flags: ignoreversion external deleteafterinstall; MinVersion: 0,5.0; OnlyBelowVersion: 0,5.1
|
||||
; Copy the correct tuntap driver for the selected platform
|
||||
Source: "{tmp}\tuntapv9.7z"; DestDir: "{app}"; Flags: ignoreversion external deleteafterinstall; OnlyBelowVersion: 0, 6.0
|
||||
Source: "{tmp}\tuntapv9_n6.7z"; DestDir: "{app}"; Flags: ignoreversion external deleteafterinstall; MinVersion: 0,6.0
|
||||
|
||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||
|
||||
[UninstallDelete]
|
||||
Type: filesandordirs; Name: "{app}\tap-windows*"
|
||||
Type: filesandordirs; Name: "{app}\inet6_driver"; MinVersion: 0,5.0; OnlyBelowVersion: 0,5.1
|
||||
Type: filesandordirs; Name: "{userappdata}\.lokinet"
|
||||
|
||||
[UninstallRun]
|
||||
Filename: "{app}\tap-windows-9.21.2\remove.bat"; WorkingDir: "{app}\tap-windows-9.21.2"; MinVersion: 0,6.0; Flags: runascurrentuser
|
||||
Filename: "{app}\tap-windows-9.9.2\remove.bat"; WorkingDir: "{app}\tap-windows-9.9.2"; OnlyBelowVersion: 0,6.0; Flags: runascurrentuser
|
||||
|
||||
[Registry]
|
||||
; TODO: BindView to activate inet6 protocol driver after restart
|
||||
Root: "HKLM"; Subkey: "Software\Microsoft\Windows\CurrentVersion\RunOnce"; ValueType: string; ValueName: "ActivateInet6"; ValueData: "[insert bindview cmd line here]"; MinVersion: 0,5.0; OnlyBelowVersion: 0,5.1
|
||||
|
||||
[Code]
|
||||
procedure InitializeWizard();
|
||||
var
|
||||
Version: TWindowsVersion;
|
||||
S: String;
|
||||
begin
|
||||
GetWindowsVersionEx(Version);
|
||||
if Version.NTPlatform and
|
||||
(Version.Major < 6) then
|
||||
begin
|
||||
// Windows 2000, XP, .NET Svr 2003
|
||||
// these have a horribly crippled WinInet that issues Triple-DES as its most secure
|
||||
// cipher suite
|
||||
idpAddFile('http://www.rvx86.net/files/tuntapv9.7z', ExpandConstant('{tmp}\tuntapv9.7z'));
|
||||
// Windows 2000 only, we need to install inet6 separately
|
||||
if (FileExists(ExpandConstant('{sys}\drivers\tcpip6.sys')) = false) and (Version.Major = 5) and (Version.Minor = 0) then
|
||||
begin
|
||||
idpAddFile('http://www.rvx86.net/files/inet6.7z', ExpandConstant('{tmp}\inet6.7z'));
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// current versions of windows :-)
|
||||
// (Arguably, one could pull this from any of the forks.)
|
||||
idpAddFile('https://github.com/despair86/loki-network/raw/master/contrib/tuntapv9-ndis/tap-windows-9.21.2.7z', ExpandConstant('{tmp}\tuntapv9_n6.7z'));
|
||||
end;
|
||||
idpDownloadAfter(wpReady);
|
||||
end;
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
|
||||
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
|
||||
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
|
||||
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon; OnlyBelowVersion: 0, 6.1
|
||||
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon; MinVersion: 0, 6.1
|
||||
|
||||
[Run]
|
||||
Filename: "{app}\{#MyAppExeName}"; Flags: nowait postinstall skipifsilent; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"
|
||||
; wait until either one or two of these terminates
|
||||
Filename: "{tmp}\7z.exe"; Parameters: "x tuntapv9.7z"; WorkingDir: "{app}"; Flags: runascurrentuser waituntilterminated; Description: "extract TUN/TAP-v9 driver"; StatusMsg: "Extracting driver..."; OnlyBelowVersion: 0, 6.0
|
||||
Filename: "{tmp}\7z.exe"; Parameters: "x tuntapv9_n6.7z"; WorkingDir: "{app}"; Flags: runascurrentuser waituntilterminated; Description: "extract TUN/TAP-v9 driver"; StatusMsg: "Extracting driver..."; MinVersion: 0, 6.0
|
||||
Filename: "{tmp}\7z.exe"; Parameters: "x inet6.7z"; WorkingDir: "{app}"; Flags: runascurrentuser waituntilterminated; Description: "extract inet6 driver"; StatusMsg: "Extracting IPv6 driver..."; MinVersion: 0, 5.0; OnlyBelowVersion: 0, 5.1
|
||||
Filename: "{tmp}\lokinet-bootstrap.exe"; WorkingDir: "{app}"; Flags: runascurrentuser waituntilterminated; Description: "bootstrap dht"; StatusMsg: "Downloading initial RC..."
|
||||
; then ask to install drivers
|
||||
Filename: "{app}\tap-windows-9.9.2\install.bat"; WorkingDir: "{app}\tap-windows-9.9.2\"; Flags: runascurrentuser waituntilterminated; Description: "Install TUN/TAP-v9 driver"; StatusMsg: "Installing driver..."; OnlyBelowVersion: 0, 6.0
|
||||
Filename: "{app}\tap-windows-9.21.2\install.bat"; WorkingDir: "{app}\tap-windows-9.21.2\"; Flags: runascurrentuser waituntilterminated; Description: "Install TUN/TAP-v9 driver"; StatusMsg: "Installing driver..."; MinVersion: 0, 6.0
|
||||
; install inet6 if not present. (I'd assume netsh displays something helpful if inet6 is already set up and configured.)
|
||||
Filename: "{app}\inet6_driver\setup\hotfix.exe"; Parameters: "/m /z"; WorkingDir: "{app}\inet6_driver\setup\"; Flags: runascurrentuser waituntilterminated; Description: "Install IPv6 driver"; StatusMsg: "Installing IPv6..."; OnlyBelowVersion: 0, 5.1
|
||||
Filename: "{sys}\netsh.exe"; Parameters: "int ipv6 install"; Flags: runascurrentuser waituntilterminated; Description: "install ipv6 on whistler"; StatusMsg: "Installing IPv6..."; MinVersion: 0,5.1; OnlyBelowVersion: 0,6.0
|
Loading…
Reference in New Issue