Reimplement whole stratum network communication with boost::asio (#90)
Logger is now thread safe
This commit is contained in:
parent
15d752d9e0
commit
df084acff6
40 changed files with 915 additions and 1942 deletions
|
@ -1,4 +1,4 @@
|
||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
project(xmrig)
|
project(xmrig)
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
|
@ -19,9 +19,9 @@ include (cmake/cpu.cmake)
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
src/api/NetworkState.cpp
|
src/api/NetworkState.cpp
|
||||||
src/App.cpp
|
src/App.cpp
|
||||||
src/3rdparty/clib-net/deps/buffer/buffer.c
|
src/net/BoostTcpConnection.cpp
|
||||||
src/3rdparty/clib-net/src/net.c
|
|
||||||
src/net/Client.cpp
|
src/net/Client.cpp
|
||||||
|
src/net/Connection.cpp
|
||||||
src/net/Job.cpp
|
src/net/Job.cpp
|
||||||
src/net/Network.cpp
|
src/net/Network.cpp
|
||||||
src/net/strategies/DonateStrategy.cpp
|
src/net/strategies/DonateStrategy.cpp
|
||||||
|
@ -109,10 +109,12 @@ add_definitions(/D__STDC_FORMAT_MACROS)
|
||||||
add_definitions(/DUNICODE)
|
add_definitions(/DUNICODE)
|
||||||
add_definitions(/DMINER_EXECUTABLE_NAME=${MINER_EXECUTABLE_NAME})
|
add_definitions(/DMINER_EXECUTABLE_NAME=${MINER_EXECUTABLE_NAME})
|
||||||
#add_definitions(/DAPP_DEBUG)
|
#add_definitions(/DAPP_DEBUG)
|
||||||
|
add_definitions(-fexceptions)
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
find_package(UV REQUIRED)
|
find_package(UV REQUIRED)
|
||||||
|
find_package(Boost 1.62.0 COMPONENTS system REQUIRED)
|
||||||
|
|
||||||
include(cmake/flags.cmake)
|
include(cmake/flags.cmake)
|
||||||
|
|
||||||
|
@ -123,7 +125,7 @@ if (WITH_TLS)
|
||||||
|
|
||||||
if (OPENSSL_FOUND)
|
if (OPENSSL_FOUND)
|
||||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||||
set(SOURCES_SSL_TLS src/3rdparty/clib-net/src/tls.c)
|
set(SOURCES_SSL_TLS src/net/BoostTlsConnection.cpp)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_TLS=OFF` to build without TLS support")
|
message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_TLS=OFF` to build without TLS support")
|
||||||
endif()
|
endif()
|
||||||
|
@ -201,8 +203,8 @@ endif()
|
||||||
include_directories(src)
|
include_directories(src)
|
||||||
include_directories(src/3rdparty)
|
include_directories(src/3rdparty)
|
||||||
include_directories(${UV_INCLUDE_DIR})
|
include_directories(${UV_INCLUDE_DIR})
|
||||||
include_directories(src/3rdparty/clib-net/include)
|
include_directories(${Boost_INCLUDE_DIRS})
|
||||||
include_directories(src/3rdparty/clib-net/deps)
|
include_directories(${Boost_INCLUDE_DIRS})
|
||||||
|
|
||||||
add_library(xmrig_common STATIC ${SOURCES_COMMON})
|
add_library(xmrig_common STATIC ${SOURCES_COMMON})
|
||||||
add_library(xmrig_os_dependencies STATIC ${SOURCES_OS} ${SOURCES_SYSLOG})
|
add_library(xmrig_os_dependencies STATIC ${SOURCES_OS} ${SOURCES_SYSLOG})
|
||||||
|
@ -219,7 +221,7 @@ endif (WITH_CC_SERVER OR WITH_CC_CLIENT)
|
||||||
add_executable(xmrigMiner ${SOURCES} ${SOURCES_CRYPTO} ${HTTPD_SOURCES} ${SOURCES_CC_CLIENT} res/app.rc)
|
add_executable(xmrigMiner ${SOURCES} ${SOURCES_CRYPTO} ${HTTPD_SOURCES} ${SOURCES_CC_CLIENT} res/app.rc)
|
||||||
set_target_properties(xmrigMiner PROPERTIES OUTPUT_NAME ${MINER_EXECUTABLE_NAME})
|
set_target_properties(xmrigMiner PROPERTIES OUTPUT_NAME ${MINER_EXECUTABLE_NAME})
|
||||||
|
|
||||||
target_link_libraries(xmrigMiner xmrig_common xmrig_os_dependencies xmrig_cpuid
|
target_link_libraries(xmrigMiner xmrig_common xmrig_os_dependencies xmrig_cpuid ${Boost_LIBRARIES}
|
||||||
${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB})
|
${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB})
|
||||||
|
|
||||||
if (WITH_CC_CLIENT)
|
if (WITH_CC_CLIENT)
|
||||||
|
@ -228,6 +230,7 @@ endif (WITH_CC_CLIENT)
|
||||||
|
|
||||||
if (WITH_TLS)
|
if (WITH_TLS)
|
||||||
target_link_libraries(xmrigMiner xmrig_tls ${OPENSSL_LIBRARIES} ${EXTRA_LIBS})
|
target_link_libraries(xmrigMiner xmrig_tls ${OPENSSL_LIBRARIES} ${EXTRA_LIBS})
|
||||||
|
target_link_libraries(xmrigMiner xmrig_tls ${OPENSSL_LIBRARIES} ${EXTRA_LIBS})
|
||||||
endif (WITH_TLS)
|
endif (WITH_TLS)
|
||||||
|
|
||||||
add_executable(xmrigDaemon src/cc/XMRigd.cpp res/app.rc)
|
add_executable(xmrigDaemon src/cc/XMRigd.cpp res/app.rc)
|
||||||
|
|
16
src/3rdparty/clib-net/CHANGELOGS
vendored
16
src/3rdparty/clib-net/CHANGELOGS
vendored
|
@ -1,16 +0,0 @@
|
||||||
|
|
||||||
# Change Logs
|
|
||||||
|
|
||||||
2014-4-13(v0.1.1):
|
|
||||||
|
|
||||||
* add a fake function: tls_get_peer_cert
|
|
||||||
|
|
||||||
* tls_handle_bio_error and tls_handle_ssl_error added for a common usage
|
|
||||||
|
|
||||||
* fix a high cpu bug in uv lines
|
|
||||||
|
|
||||||
* make SSL_MODE_RELEASE_BUFFERS be gracefully imported
|
|
||||||
|
|
||||||
* correct onConnect and onRead for ssl
|
|
||||||
|
|
||||||
* fix a memory leak in ssl part
|
|
17
src/3rdparty/clib-net/Makefile
vendored
17
src/3rdparty/clib-net/Makefile
vendored
|
@ -1,17 +0,0 @@
|
||||||
|
|
||||||
CC ?= gcc
|
|
||||||
SRC = $(wildcard src/*.c) tests/simple.c
|
|
||||||
DEPS = $(wildcard deps/*/*.c)
|
|
||||||
CFLAGS = -std=c++11\
|
|
||||||
-Iinclude\
|
|
||||||
-Isrc\
|
|
||||||
-Ideps\
|
|
||||||
-Ideps/libuv/include\
|
|
||||||
-Ldeps/libuv/build/Release\
|
|
||||||
-Wall -Wno-unused-function
|
|
||||||
LDFLAGS = -lcrypto -lssl -luv
|
|
||||||
|
|
||||||
test: $(SRC)
|
|
||||||
$(CC) $(CFLAGS) -o $@ $(SRC) $(DEPS) $(LDFLAGS)
|
|
||||||
|
|
||||||
.PHONY: test
|
|
40
src/3rdparty/clib-net/deps/buffer/History.md
vendored
40
src/3rdparty/clib-net/deps/buffer/History.md
vendored
|
@ -1,40 +0,0 @@
|
||||||
|
|
||||||
0.4.0 / 2015-01-05
|
|
||||||
==================
|
|
||||||
|
|
||||||
* refactor
|
|
||||||
* buffer: Remove printf() statement
|
|
||||||
* Add `buffer_appendf()` (#10, marcomorain)
|
|
||||||
|
|
||||||
0.3.0 / 2014-12-24
|
|
||||||
==================
|
|
||||||
|
|
||||||
* travis: Fail the build if any memory is leaked
|
|
||||||
* test: Fix memory leaks
|
|
||||||
* travis: setup
|
|
||||||
* Add `buffer_append_n(buffer_t *, const char *, size_t)`
|
|
||||||
|
|
||||||
0.2.1 / 2014-12-23
|
|
||||||
==================
|
|
||||||
|
|
||||||
* fix header guard
|
|
||||||
* fix compilation on linux
|
|
||||||
* Add missing null terminator after realloc (buffer resize)
|
|
||||||
* Make it safe to always use `data` as a character string
|
|
||||||
|
|
||||||
0.2.0 / 2013-01-05
|
|
||||||
==================
|
|
||||||
|
|
||||||
* add print_buffer()
|
|
||||||
* add buffer_compact()
|
|
||||||
|
|
||||||
0.1.0 / 2012-12-26
|
|
||||||
==================
|
|
||||||
|
|
||||||
* add trim functions
|
|
||||||
* add buffer_clear(buffer_t *self)
|
|
||||||
* add buffer_fill(buffer_t *self, int c)
|
|
||||||
* add buffer_new_with_string_length(char *str, size_t len)
|
|
||||||
* add buffer_new_with_copy(char *str)
|
|
||||||
* add buffer_indexof()
|
|
||||||
|
|
6
src/3rdparty/clib-net/deps/buffer/Makefile
vendored
6
src/3rdparty/clib-net/deps/buffer/Makefile
vendored
|
@ -1,6 +0,0 @@
|
||||||
|
|
||||||
test: buffer.c test.c
|
|
||||||
@$(CC) $^ -std=c99 -o $@
|
|
||||||
@./test
|
|
||||||
|
|
||||||
.PHONY: test
|
|
82
src/3rdparty/clib-net/deps/buffer/Readme.md
vendored
82
src/3rdparty/clib-net/deps/buffer/Readme.md
vendored
|
@ -1,82 +0,0 @@
|
||||||
|
|
||||||
# buffer
|
|
||||||
|
|
||||||
Tiny C string manipulation library.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Install with [clib](https://github.com/clibs/clib):
|
|
||||||
|
|
||||||
```
|
|
||||||
$ clib install clibs/buffer
|
|
||||||
```
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
```c
|
|
||||||
buffer_t *
|
|
||||||
buffer_new();
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_new_with_size(size_t n);
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_new_with_string(char *str);
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_new_with_string_length(char *str, size_t len);
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_new_with_copy(char *str);
|
|
||||||
|
|
||||||
size_t
|
|
||||||
buffer_size(buffer_t *self);
|
|
||||||
|
|
||||||
size_t
|
|
||||||
buffer_length(buffer_t *self);
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_free(buffer_t *self);
|
|
||||||
|
|
||||||
int
|
|
||||||
buffer_prepend(buffer_t *self, char *str);
|
|
||||||
|
|
||||||
int
|
|
||||||
buffer_append(buffer_t *self, char *str);
|
|
||||||
|
|
||||||
int
|
|
||||||
buffer_equals(buffer_t *self, buffer_t *other);
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
buffer_indexof(buffer_t *self, char *str);
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_slice(buffer_t *self, size_t from, ssize_t to);
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
buffer_compact(buffer_t *self);
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_fill(buffer_t *self, int c);
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_clear(buffer_t *self);
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_trim_left(buffer_t *self);
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_trim_right(buffer_t *self);
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_trim(buffer_t *self);
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_print(buffer_t *self);
|
|
||||||
|
|
||||||
#define buffer_string(self) (self->data)
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT
|
|
353
src/3rdparty/clib-net/deps/buffer/buffer.c
vendored
353
src/3rdparty/clib-net/deps/buffer/buffer.c
vendored
|
@ -1,353 +0,0 @@
|
||||||
//
|
|
||||||
// buffer.c
|
|
||||||
//
|
|
||||||
// Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include "buffer.h"
|
|
||||||
|
|
||||||
// TODO: shared with reference counting
|
|
||||||
// TODO: linked list for append/prepend etc
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compute the nearest multiple of `a` from `b`.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define nearest_multiple_of(a, b) \
|
|
||||||
(((b) + ((a) - 1)) & ~((a) - 1))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate a new buffer with BUFFER_DEFAULT_SIZE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_new() {
|
|
||||||
return buffer_new_with_size(BUFFER_DEFAULT_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate a new buffer with `n` bytes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_new_with_size(size_t n) {
|
|
||||||
buffer_t *self = malloc(sizeof(buffer_t));
|
|
||||||
if (!self) return NULL;
|
|
||||||
self->len = n;
|
|
||||||
self->data = self->alloc = calloc(n + 1, 1);
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate a new buffer with `str`.
|
|
||||||
*/
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_new_with_string(char *str) {
|
|
||||||
return buffer_new_with_string_length(str, strlen(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate a new buffer with `str` and `len`.
|
|
||||||
*/
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_new_with_string_length(char *str, size_t len) {
|
|
||||||
buffer_t *self = malloc(sizeof(buffer_t));
|
|
||||||
if (!self) return NULL;
|
|
||||||
self->len = len;
|
|
||||||
self->data = self->alloc = str;
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate a new buffer with a copy of `str`.
|
|
||||||
*/
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_new_with_copy(char *str) {
|
|
||||||
size_t len = strlen(str);
|
|
||||||
buffer_t *self = buffer_new_with_size(len);
|
|
||||||
if (!self) return NULL;
|
|
||||||
memcpy(self->alloc, str, len);
|
|
||||||
self->data = self->alloc;
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Deallocate excess memory, the number
|
|
||||||
* of bytes removed or -1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
buffer_compact(buffer_t *self) {
|
|
||||||
size_t len = buffer_length(self);
|
|
||||||
size_t rem = self->len - len;
|
|
||||||
char *buf = calloc(len + 1, 1);
|
|
||||||
if (!buf) return -1;
|
|
||||||
memcpy(buf, self->data, len);
|
|
||||||
free(self->alloc);
|
|
||||||
self->len = len;
|
|
||||||
self->data = self->alloc = buf;
|
|
||||||
return rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Free the buffer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_free(buffer_t *self) {
|
|
||||||
free(self->alloc);
|
|
||||||
free(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return buffer size.
|
|
||||||
*/
|
|
||||||
|
|
||||||
size_t
|
|
||||||
buffer_size(buffer_t *self) {
|
|
||||||
return self->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return string length.
|
|
||||||
*/
|
|
||||||
|
|
||||||
size_t
|
|
||||||
buffer_length(buffer_t *self) {
|
|
||||||
return strlen(self->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Resize to hold `n` bytes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
buffer_resize(buffer_t *self, size_t n) {
|
|
||||||
n = nearest_multiple_of(1024, n);
|
|
||||||
self->len = n;
|
|
||||||
self->alloc = self->data = realloc(self->alloc, n + 1);
|
|
||||||
if (!self->alloc) return -1;
|
|
||||||
self->alloc[n] = '\0';
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Append a printf-style formatted string to the buffer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int buffer_appendf(buffer_t *self, const char *format, ...) {
|
|
||||||
va_list ap;
|
|
||||||
va_list tmpa;
|
|
||||||
char *dst = NULL;
|
|
||||||
int length = 0;
|
|
||||||
int required = 0;
|
|
||||||
int bytes = 0;
|
|
||||||
|
|
||||||
va_start(ap, format);
|
|
||||||
|
|
||||||
length = buffer_length(self);
|
|
||||||
|
|
||||||
// First, we compute how many bytes are needed
|
|
||||||
// for the formatted string and allocate that
|
|
||||||
// much more space in the buffer.
|
|
||||||
va_copy(tmpa, ap);
|
|
||||||
required = vsnprintf(NULL, 0, format, tmpa);
|
|
||||||
va_end(tmpa);
|
|
||||||
if (-1 == buffer_resize(self, length + required)) {
|
|
||||||
va_end(ap);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next format the string into the space that we
|
|
||||||
// have made room for.
|
|
||||||
dst = self->data + length;
|
|
||||||
bytes = vsnprintf(dst, 1 + required, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return bytes < 0
|
|
||||||
? -1
|
|
||||||
: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Append `str` to `self` and return 0 on success, -1 on failure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
buffer_append(buffer_t *self, const char *str) {
|
|
||||||
return buffer_append_n(self, str, strlen(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Append the first `len` bytes from `str` to `self` and
|
|
||||||
* return 0 on success, -1 on failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
buffer_append_n(buffer_t *self, const char *str, size_t len) {
|
|
||||||
size_t prev = strlen(self->data);
|
|
||||||
size_t needed = len + prev;
|
|
||||||
|
|
||||||
// enough space
|
|
||||||
if (self->len > needed) {
|
|
||||||
strncat(self->data, str, len);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// resize
|
|
||||||
int ret = buffer_resize(self, needed);
|
|
||||||
if (-1 == ret) return -1;
|
|
||||||
strncat(self->data, str, len);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prepend `str` to `self` and return 0 on success, -1 on failure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
buffer_prepend(buffer_t *self, char *str) {
|
|
||||||
size_t len = strlen(str);
|
|
||||||
size_t prev = strlen(self->data);
|
|
||||||
size_t needed = len + prev;
|
|
||||||
|
|
||||||
// enough space
|
|
||||||
if (self->len > needed) goto move;
|
|
||||||
|
|
||||||
// resize
|
|
||||||
int ret = buffer_resize(self, needed);
|
|
||||||
if (-1 == ret) return -1;
|
|
||||||
|
|
||||||
// move
|
|
||||||
move:
|
|
||||||
memmove(self->data + len, self->data, len + 1);
|
|
||||||
memcpy(self->data, str, len);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return a new buffer based on the `from..to` slice of `buf`,
|
|
||||||
* or NULL on error.
|
|
||||||
*/
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_slice(buffer_t *buf, size_t from, ssize_t to) {
|
|
||||||
size_t len = strlen(buf->data);
|
|
||||||
|
|
||||||
// bad range
|
|
||||||
if (to < from) return NULL;
|
|
||||||
|
|
||||||
// relative to end
|
|
||||||
if (to < 0) to = len - ~to;
|
|
||||||
|
|
||||||
// cap end
|
|
||||||
if (to > len) to = len;
|
|
||||||
|
|
||||||
size_t n = to - from;
|
|
||||||
buffer_t *self = buffer_new_with_size(n);
|
|
||||||
memcpy(self->data, buf->data + from, n);
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return 1 if the buffers contain equivalent data.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
buffer_equals(buffer_t *self, buffer_t *other) {
|
|
||||||
return 0 == strcmp(self->data, other->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the index of the substring `str`, or -1 on failure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
buffer_indexof(buffer_t *self, char *str) {
|
|
||||||
char *sub = strstr(self->data, str);
|
|
||||||
if (!sub) return -1;
|
|
||||||
return sub - self->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Trim leading whitespace.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_trim_left(buffer_t *self) {
|
|
||||||
int c;
|
|
||||||
while ((c = *self->data) && isspace(c)) {
|
|
||||||
++self->data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Trim trailing whitespace.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_trim_right(buffer_t *self) {
|
|
||||||
int c;
|
|
||||||
size_t i = buffer_length(self) - 1;
|
|
||||||
while ((c = self->data[i]) && isspace(c)) {
|
|
||||||
self->data[i--] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Trim trailing and leading whitespace.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_trim(buffer_t *self) {
|
|
||||||
buffer_trim_left(self);
|
|
||||||
buffer_trim_right(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fill the buffer with `c`.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_fill(buffer_t *self, int c) {
|
|
||||||
memset(self->data, c, self->len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fill the buffer with 0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_clear(buffer_t *self) {
|
|
||||||
buffer_fill(self, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Print a hex dump of the buffer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_print(buffer_t *self) {
|
|
||||||
int i;
|
|
||||||
size_t len = self->len;
|
|
||||||
|
|
||||||
printf("\n ");
|
|
||||||
|
|
||||||
// hex
|
|
||||||
for (i = 0; i < len; ++i) {
|
|
||||||
printf(" %02x", self->alloc[i]);
|
|
||||||
if ((i + 1) % 8 == 0) printf("\n ");
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
106
src/3rdparty/clib-net/deps/buffer/buffer.h
vendored
106
src/3rdparty/clib-net/deps/buffer/buffer.h
vendored
|
@ -1,106 +0,0 @@
|
||||||
|
|
||||||
//
|
|
||||||
// buffer.h
|
|
||||||
//
|
|
||||||
// Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BUFFER_H
|
|
||||||
#define BUFFER_H 1
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#include <BaseTsd.h>
|
|
||||||
typedef SSIZE_T ssize_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Default buffer size.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BUFFER_DEFAULT_SIZE
|
|
||||||
#define BUFFER_DEFAULT_SIZE 64
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Buffer struct.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
size_t len;
|
|
||||||
char *alloc;
|
|
||||||
char *data;
|
|
||||||
} buffer_t;
|
|
||||||
|
|
||||||
// prototypes
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_new();
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_new_with_size(size_t n);
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_new_with_string(char *str);
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_new_with_string_length(char *str, size_t len);
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_new_with_copy(char *str);
|
|
||||||
|
|
||||||
size_t
|
|
||||||
buffer_size(buffer_t *self);
|
|
||||||
|
|
||||||
size_t
|
|
||||||
buffer_length(buffer_t *self);
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_free(buffer_t *self);
|
|
||||||
|
|
||||||
int
|
|
||||||
buffer_prepend(buffer_t *self, char *str);
|
|
||||||
|
|
||||||
int
|
|
||||||
buffer_append(buffer_t *self, const char *str);
|
|
||||||
|
|
||||||
int
|
|
||||||
buffer_appendf(buffer_t *self, const char *format, ...);
|
|
||||||
|
|
||||||
int
|
|
||||||
buffer_append_n(buffer_t *self, const char *str, size_t len);
|
|
||||||
|
|
||||||
int
|
|
||||||
buffer_equals(buffer_t *self, buffer_t *other);
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
buffer_indexof(buffer_t *self, char *str);
|
|
||||||
|
|
||||||
buffer_t *
|
|
||||||
buffer_slice(buffer_t *self, size_t from, ssize_t to);
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
buffer_compact(buffer_t *self);
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_fill(buffer_t *self, int c);
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_clear(buffer_t *self);
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_trim_left(buffer_t *self);
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_trim_right(buffer_t *self);
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_trim(buffer_t *self);
|
|
||||||
|
|
||||||
void
|
|
||||||
buffer_print(buffer_t *self);
|
|
||||||
|
|
||||||
#define buffer_string(self) (self->data)
|
|
||||||
|
|
||||||
#endif
|
|
156
src/3rdparty/clib-net/include/net.h
vendored
156
src/3rdparty/clib-net/include/net.h
vendored
|
@ -1,156 +0,0 @@
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2014 <yorkiefixer@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __NET_H__
|
|
||||||
#define __NET_H__
|
|
||||||
|
|
||||||
#include <uv.h>
|
|
||||||
#include <buffer/buffer.h>
|
|
||||||
|
|
||||||
#ifndef XMRIG_NO_TLS
|
|
||||||
#include "tls.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NOT_SSL 0x00
|
|
||||||
#define USE_SSL 0x01
|
|
||||||
|
|
||||||
#define NET_OK 0
|
|
||||||
#define NET_VERSION_MAJOR 0
|
|
||||||
#define NET_VERSION_MINOR 1
|
|
||||||
#define NET_VERSION_PATCH 2
|
|
||||||
#define NET_VERSION_IS_RELEASE 0
|
|
||||||
|
|
||||||
typedef struct net_s net_t;
|
|
||||||
typedef struct addrinfo net_ai;
|
|
||||||
typedef struct sockaddr_in socketPair_t;
|
|
||||||
|
|
||||||
|
|
||||||
struct net_s {
|
|
||||||
char *hostname;
|
|
||||||
int port;
|
|
||||||
int connected;
|
|
||||||
uv_getaddrinfo_t *resolver;
|
|
||||||
uv_loop_t *loop;
|
|
||||||
uv_tcp_t *handle;
|
|
||||||
uv_connect_t *conn;
|
|
||||||
int use_ssl;
|
|
||||||
int tls_established;
|
|
||||||
|
|
||||||
#ifndef XMRIG_NO_TLS
|
|
||||||
tls_t *tls;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *data;
|
|
||||||
void (*conn_cb)(net_t*);
|
|
||||||
void (*read_cb)(net_t*, size_t, char*);
|
|
||||||
void (*error_cb)(net_t*, int, char*);
|
|
||||||
void (*close_cb)(net_t*);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create an new network.
|
|
||||||
*/
|
|
||||||
net_t *
|
|
||||||
net_new(char * hostname, int port);
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef XMRIG_NO_TLS
|
|
||||||
/*
|
|
||||||
* Set SSL's Context
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
net_set_tls(net_t * net, tls_ctx * ctx);
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* Do connect to new
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
net_connect(net_t * net);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Just close the holding connection
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
net_close(net_t * net, void (*cb)(uv_handle_t*));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* free connection
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
net_free(net_t * net);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* real free function
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
net_free_cb(uv_handle_t * handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* DNS resolve
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
net_resolve(net_t * net);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* DNS -> IP done, and call `net_resolve_cb`
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
net_resolve_cb(uv_getaddrinfo_t *rv, int stat, net_ai * ai);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* connect created, and call `net_connect_cb`
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
net_connect_cb(uv_connect_t *conn, int stat);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* realloc buffer before you read
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
net_alloc(uv_handle_t* handle, size_t size, uv_buf_t* buf);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* read buffer
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
net_read(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* write buffer
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
net_write(net_t * net, char * buf);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* write buffer with length specified
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
net_write2(net_t * net, char * buf, unsigned int len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* return use_ssl
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
net_use_ssl(net_t * net);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* continue to read after on data
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
net_resume(net_t * net);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* pause read
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
net_pause(net_t * net);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* set error_cb
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
net_set_error_cb(net_t * net, void * cb);
|
|
||||||
|
|
||||||
#endif /* __NET_H__ */
|
|
133
src/3rdparty/clib-net/include/tls.h
vendored
133
src/3rdparty/clib-net/include/tls.h
vendored
|
@ -1,133 +0,0 @@
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2014 <yorkiefixer@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __TLS_H__
|
|
||||||
#define __TLS_H__
|
|
||||||
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
#include <openssl/err.h>
|
|
||||||
#include <openssl/x509.h>
|
|
||||||
#include <openssl/x509v3.h>
|
|
||||||
#include <buffer/buffer.h>
|
|
||||||
|
|
||||||
#define SSL_CHUNK_SIZE 512
|
|
||||||
|
|
||||||
typedef SSL_CTX tls_ctx;
|
|
||||||
typedef struct tls_s {
|
|
||||||
SSL_CTX * ctx;
|
|
||||||
SSL * ssl;
|
|
||||||
BIO * bio_in;
|
|
||||||
BIO * bio_out;
|
|
||||||
buffer_t * buffer;
|
|
||||||
int connected;
|
|
||||||
char * data;
|
|
||||||
char buf[SSL_CHUNK_SIZE]; /* internal usage */
|
|
||||||
} tls_t;
|
|
||||||
|
|
||||||
static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
|
|
||||||
| ASN1_STRFLGS_ESC_MSB
|
|
||||||
| XN_FLAG_SEP_MULTILINE
|
|
||||||
| XN_FLAG_FN_SN;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* initialize the ssl
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ssl_init();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* destroy the ssl settings and internal tables
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ssl_destroy();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* create a context for ssl
|
|
||||||
*/
|
|
||||||
tls_ctx *
|
|
||||||
tls_ctx_new();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* create a tls instance
|
|
||||||
*/
|
|
||||||
tls_t *
|
|
||||||
tls_create(tls_ctx * ctx);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* shutdown tls
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
tls_shutdown(tls_t * tls);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* destroy a tls instance
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
tls_free(tls_t * tls);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* get peer certification info
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
tls_get_peer_cert(tls_t * tls);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* do connect to tls
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
tls_connect(tls_t * tls);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* handle error in bio
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
tls_handle_bio_error(tls_t * tls, int err);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* handle error in ssl
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
tls_handle_ssl_error(tls_t *tls, int err);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* a port in tls for `bio_read`
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
tls_bio_read(tls_t * tls, int len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* a port in tls for `bio_write`
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
tls_bio_write(tls_t * tls, char * written, int len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* read
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
tls_read(tls_t * tls);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* write
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
tls_write(tls_t * tls, char * written, int len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* write a tls packet
|
|
||||||
*/
|
|
||||||
#define REQUEST_TLS_WRITE(name, cmd, read, req) do { \
|
|
||||||
tls_write(req->tls, cmd); \
|
|
||||||
do { \
|
|
||||||
read = tls_bio_read(req->tls, 0); \
|
|
||||||
if (read > 0) { \
|
|
||||||
REQUEST_WRITE(req, req->tls->buf, read, name); \
|
|
||||||
} \
|
|
||||||
} while (read > 0); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __TLS_H__ */
|
|
53
src/3rdparty/clib-net/readme.md
vendored
53
src/3rdparty/clib-net/readme.md
vendored
|
@ -1,53 +0,0 @@
|
||||||
|
|
||||||
# net-client
|
|
||||||
|
|
||||||
Simple network client
|
|
||||||
|
|
||||||
### Requirement
|
|
||||||
|
|
||||||
* libuv 0.10.x
|
|
||||||
|
|
||||||
* buffer 0.2.0
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ clib install clibs/net
|
|
||||||
$ git clone https://github.com/joyent/libuv.git deps/libuv
|
|
||||||
$ checkout v0.10.25
|
|
||||||
```
|
|
||||||
|
|
||||||
### Run tests
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make test
|
|
||||||
./test
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example
|
|
||||||
|
|
||||||
```c
|
|
||||||
static void
|
|
||||||
imap_parser(net_t * net, size_t read, char * buf) {
|
|
||||||
printf("%s\n", buf);
|
|
||||||
printf("%zu\n", read);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[]) {
|
|
||||||
ssl_init();
|
|
||||||
tls_ctx * ctx = tls_ctx_new();
|
|
||||||
net_t * net = net_new("imap.gmail.com", 993);
|
|
||||||
net->onRead = imap_parser;
|
|
||||||
|
|
||||||
// convert this socket to ssl
|
|
||||||
net_set_tls(net, ctx);
|
|
||||||
net_connect(net);
|
|
||||||
|
|
||||||
uv_run(net->loop, UV_RUN_DEFAULT);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### License
|
|
||||||
|
|
||||||
MIT
|
|
395
src/3rdparty/clib-net/src/net.c
vendored
395
src/3rdparty/clib-net/src/net.c
vendored
|
@ -1,395 +0,0 @@
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <uv.h>
|
|
||||||
#include "net.h"
|
|
||||||
|
|
||||||
net_t *
|
|
||||||
net_new(char * hostname, int port) {
|
|
||||||
net_t * net = (net_t*) malloc(sizeof(net_t));
|
|
||||||
net->loop = uv_default_loop();
|
|
||||||
net->hostname = hostname;
|
|
||||||
net->port = port;
|
|
||||||
net->connected = 0;
|
|
||||||
net->tls_established = 0;
|
|
||||||
net->use_ssl = 0;
|
|
||||||
net->conn_cb = NULL;
|
|
||||||
net->read_cb = NULL;
|
|
||||||
net->error_cb = NULL;
|
|
||||||
net->close_cb = NULL;
|
|
||||||
net->handle = (uv_tcp_t *) malloc(sizeof(uv_tcp_t));
|
|
||||||
net->conn = (uv_connect_t *) malloc(sizeof(uv_connect_t));
|
|
||||||
net->handle->data
|
|
||||||
= net->conn->data
|
|
||||||
= (void *) net;
|
|
||||||
|
|
||||||
return net;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef XMRIG_NO_TLS
|
|
||||||
int
|
|
||||||
net_set_tls(net_t * net, tls_ctx * ctx) {
|
|
||||||
net->use_ssl = USE_SSL;
|
|
||||||
net->tls = tls_create(ctx);
|
|
||||||
return NET_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
net_connect(net_t * net) {
|
|
||||||
net_resolve(net);
|
|
||||||
return NET_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
net_close_cb(uv_handle_t *handle) {
|
|
||||||
net_t * net = (net_t*) handle->data;
|
|
||||||
|
|
||||||
if (net) {
|
|
||||||
if (net->close_cb) {
|
|
||||||
net->close_cb(net);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
net_close(net_t * net, void (*cb)(uv_handle_t*)) {
|
|
||||||
int r = net->connected;
|
|
||||||
if (r == 1) {
|
|
||||||
net->connected = 0;
|
|
||||||
net->tls_established = 0;
|
|
||||||
|
|
||||||
#ifndef XMRIG_NO_TLS
|
|
||||||
if (net->use_ssl) {
|
|
||||||
tls_shutdown(net->tls);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (uv_is_readable((uv_stream_t*)net->handle) == 1) {
|
|
||||||
uv_read_stop((uv_stream_t*)net->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uv_is_closing((const uv_handle_t *) net->handle) == 0) {
|
|
||||||
uv_close((uv_handle_t *)net->handle, net_close_cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef XMRIG_NO_TLS
|
|
||||||
if (net->use_ssl) {
|
|
||||||
tls_free(net->tls);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} else{
|
|
||||||
if (net->close_cb) {
|
|
||||||
net->close_cb(net);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
net_free(net_t * net) {
|
|
||||||
if (net != NULL) {
|
|
||||||
free(net);
|
|
||||||
net = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NET_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
net_free_cb(uv_handle_t * handle) {
|
|
||||||
net_t * net = (net_t *) handle->data;
|
|
||||||
if (net->handle != NULL) {
|
|
||||||
free(net->handle);
|
|
||||||
net->handle = NULL;
|
|
||||||
}
|
|
||||||
if (net->conn != NULL) {
|
|
||||||
free(net->conn);
|
|
||||||
net->conn = NULL;
|
|
||||||
}
|
|
||||||
if (net->resolver != NULL) {
|
|
||||||
free(net->resolver);
|
|
||||||
net->resolver = NULL;
|
|
||||||
}
|
|
||||||
if (net != NULL) {
|
|
||||||
free(net);
|
|
||||||
net = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
net_resolve(net_t * net) {
|
|
||||||
net_ai hints;
|
|
||||||
int ret;
|
|
||||||
char buf[6];
|
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%d", net->port);
|
|
||||||
memset(&hints, 0, sizeof(struct addrinfo));
|
|
||||||
hints.ai_family = AF_INET;
|
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
|
||||||
|
|
||||||
net->resolver = malloc(sizeof(uv_getaddrinfo_t));
|
|
||||||
if (!net->resolver) {
|
|
||||||
/*
|
|
||||||
* TODO(Yorkie): depent parital handles
|
|
||||||
*/
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
net->resolver->data = (void *) net;
|
|
||||||
ret = uv_getaddrinfo(net->loop, net->resolver,
|
|
||||||
net_resolve_cb, net->hostname, NULL, &hints);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
net_resolve_cb(uv_getaddrinfo_t *rv, int err, net_ai * ai) {
|
|
||||||
net_t * net = (net_t*) rv->data;
|
|
||||||
char addr[INET6_ADDRSTRLEN];
|
|
||||||
int ret;
|
|
||||||
struct sockaddr_in dest;
|
|
||||||
|
|
||||||
if (err != 0) {
|
|
||||||
if (net->error_cb) {
|
|
||||||
net->error_cb(net, err, (char *) uv_strerror(err));
|
|
||||||
} else {
|
|
||||||
printf("error(%s:%d) %s", net->hostname, net->port, (char *) uv_strerror(err));
|
|
||||||
net_free(net);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uv_ip4_name((socketPair_t *) ai->ai_addr, addr, INET6_ADDRSTRLEN);
|
|
||||||
ret = uv_ip4_addr(addr, net->port, &dest);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
if (net->error_cb) {
|
|
||||||
net->error_cb(net, ret, (char *) uv_strerror(err));
|
|
||||||
} else {
|
|
||||||
printf("error(%s:%d) %s", net->hostname, net->port, (char *) uv_strerror(err));
|
|
||||||
net_free(net);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* create tcp instance.
|
|
||||||
*/
|
|
||||||
uv_tcp_init(net->loop, net->handle);
|
|
||||||
uv_tcp_nodelay(net->handle, 1);
|
|
||||||
|
|
||||||
# ifndef WIN32
|
|
||||||
uv_tcp_keepalive(net->handle, 1, 60);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
ret = uv_tcp_connect(net->conn, net->handle, (const struct sockaddr*) &dest, net_connect_cb);
|
|
||||||
if (ret != NET_OK) {
|
|
||||||
if (net->error_cb) {
|
|
||||||
net->error_cb(net, ret, (char *) uv_strerror(ret));
|
|
||||||
} else {
|
|
||||||
printf("error(%s:%d) %s", net->hostname, net->port, (char *) uv_strerror(ret));
|
|
||||||
net_free(net);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* free
|
|
||||||
*/
|
|
||||||
uv_freeaddrinfo(ai);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
net_connect_cb(uv_connect_t *conn, int err) {
|
|
||||||
net_t * net = (net_t *) conn->data;
|
|
||||||
int read;
|
|
||||||
|
|
||||||
if (err < 0) {
|
|
||||||
net_free(net);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* change the `connected` state
|
|
||||||
*/
|
|
||||||
net->connected = 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* read buffers via uv
|
|
||||||
*/
|
|
||||||
uv_read_start((uv_stream_t *) net->handle, net_alloc, net_read);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* call `onConnect`, the tcp connection has been
|
|
||||||
* established in user-land.
|
|
||||||
*/
|
|
||||||
if (net->use_ssl == NOT_SSL && net->conn_cb != NULL) {
|
|
||||||
net->conn_cb(net);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef XMRIG_NO_TLS
|
|
||||||
/*
|
|
||||||
* Handle TLS Partial
|
|
||||||
*/
|
|
||||||
if (net->use_ssl == USE_SSL && tls_connect(net->tls) == NET_OK) {
|
|
||||||
do {
|
|
||||||
read = tls_bio_read(net->tls, 0);
|
|
||||||
if (read > 0) {
|
|
||||||
char* buf = (char *) calloc(read, 1);
|
|
||||||
memset(buf, 0, read);
|
|
||||||
memcpy(buf, net->tls->buf, read);
|
|
||||||
uv_buf_t uvbuf = uv_buf_init(buf, read);
|
|
||||||
uv_try_write((uv_stream_t*)net->handle, &uvbuf, 1);
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
} while (read > 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
net_alloc(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
|
|
||||||
buf->base = (char *) calloc(size, 1);
|
|
||||||
buf->len = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
net_read(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
|
|
||||||
net_t * net = (net_t *) handle->data;
|
|
||||||
|
|
||||||
if (nread < 0) {
|
|
||||||
if (net->error_cb) {
|
|
||||||
net->error_cb(net, nread, (char *) uv_strerror(nread));
|
|
||||||
} else {
|
|
||||||
printf("error(%s:%d) %s", net->hostname, net->port, (char *) uv_strerror(nread));
|
|
||||||
net_free(net);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef XMRIG_NO_TLS
|
|
||||||
/*
|
|
||||||
* BIO Return rule:
|
|
||||||
* All these functions return either the amount of data successfully
|
|
||||||
* read or written (if the return value is positive) or that no data
|
|
||||||
* was successfully read or written if the result is 0 or -1. If the
|
|
||||||
* return value is -2 then the operation is not implemented in the specific BIO type.
|
|
||||||
*/
|
|
||||||
if (net->use_ssl) {
|
|
||||||
tls_bio_write(net->tls, buf->base, nread);
|
|
||||||
free(buf->base);
|
|
||||||
|
|
||||||
int read = 0;
|
|
||||||
int stat = tls_read(net->tls);
|
|
||||||
if (stat == 1) {
|
|
||||||
/*
|
|
||||||
* continue: Say hello
|
|
||||||
*/
|
|
||||||
do {
|
|
||||||
read = tls_bio_read(net->tls, 0);
|
|
||||||
if (read > 0) {
|
|
||||||
char* buf2 = (char *) calloc(read, 1);
|
|
||||||
memset(buf2, 0, read);
|
|
||||||
memcpy(buf2, net->tls->buf, read);
|
|
||||||
uv_buf_t uvbuf = uv_buf_init(buf2, read);
|
|
||||||
uv_try_write((uv_stream_t*)net->handle, &uvbuf, 1);
|
|
||||||
free(buf2);
|
|
||||||
}
|
|
||||||
} while (read > 0);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* SSL Connection is created
|
|
||||||
* Here need to call user-land callback
|
|
||||||
*/
|
|
||||||
if (!net->tls_established) {
|
|
||||||
net->tls_established = 1;
|
|
||||||
if (net->conn_cb != NULL) {
|
|
||||||
net->conn_cb(net);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* read buffer
|
|
||||||
*/
|
|
||||||
if (stat == 0) {
|
|
||||||
if (buffer_string(net->tls->buffer) > 0)
|
|
||||||
// uv_read_stop((uv_stream_t*)net->handle);
|
|
||||||
|
|
||||||
if (net->read_cb != NULL && net->connected && net->tls_established) {
|
|
||||||
net->read_cb(net, buffer_length(net->tls->buffer),
|
|
||||||
buffer_string(net->tls->buffer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TCP Part, no SSL, just proxy of uv.
|
|
||||||
*/
|
|
||||||
//uv_read_stop(handle);
|
|
||||||
buf->base[nread] = 0;
|
|
||||||
if (net->read_cb != NULL) {
|
|
||||||
net->read_cb(net, nread, buf->base);
|
|
||||||
free(buf->base);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
net_write(net_t * net, char * buf) {
|
|
||||||
return net_write2(net, buf, strlen(buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
net_write2(net_t * net, char * buf, unsigned int len) {
|
|
||||||
uv_buf_t uvbuf;
|
|
||||||
int read = 0;
|
|
||||||
int res = NET_OK;
|
|
||||||
|
|
||||||
switch (net->use_ssl) {
|
|
||||||
case USE_SSL:
|
|
||||||
#ifndef XMRIG_NO_TLS
|
|
||||||
tls_write(net->tls, buf, (int)len);
|
|
||||||
do {
|
|
||||||
read = tls_bio_read(net->tls, 0);
|
|
||||||
if (read > 0) {
|
|
||||||
uvbuf = uv_buf_init(net->tls->buf, read);
|
|
||||||
res = uv_try_write((uv_stream_t*)net->handle, &uvbuf,1);
|
|
||||||
}
|
|
||||||
} while (read > 0);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case NOT_SSL:
|
|
||||||
uvbuf = uv_buf_init(buf, len);
|
|
||||||
res = uv_try_write((uv_stream_t*)net->handle, &uvbuf, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
net_use_ssl(net_t * net) {
|
|
||||||
return net->use_ssl == USE_SSL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
net_resume(net_t * net) {
|
|
||||||
uv_read_start((uv_stream_t *)net->handle, net_alloc, net_read);
|
|
||||||
return NET_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
net_pause(net_t * net) {
|
|
||||||
uv_read_stop((uv_stream_t *)net->handle);
|
|
||||||
return NET_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
net_set_error_cb(net_t * net, void * cb) {
|
|
||||||
net->error_cb = cb;
|
|
||||||
return NET_OK;
|
|
||||||
}
|
|
221
src/3rdparty/clib-net/src/tls.c
vendored
221
src/3rdparty/clib-net/src/tls.c
vendored
|
@ -1,221 +0,0 @@
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2014 <yorkiefixer@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include "tls.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
ssl_init() {
|
|
||||||
SSL_library_init();
|
|
||||||
OpenSSL_add_all_algorithms();
|
|
||||||
SSL_load_error_strings();
|
|
||||||
ERR_load_crypto_strings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ssl_destroy() {
|
|
||||||
EVP_cleanup();
|
|
||||||
ERR_free_strings();
|
|
||||||
}
|
|
||||||
|
|
||||||
tls_ctx *
|
|
||||||
tls_ctx_new() {
|
|
||||||
tls_ctx *ctx = SSL_CTX_new(SSLv23_method());
|
|
||||||
#ifdef SSL_OP_NO_COMPRESSION
|
|
||||||
SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
tls_t *
|
|
||||||
tls_create(tls_ctx *ctx) {
|
|
||||||
tls_t * tls = (tls_t *) malloc(sizeof(tls_t)+1);
|
|
||||||
if (tls == NULL)
|
|
||||||
fprintf(stderr, "tls> %s", "Out of Memory");
|
|
||||||
|
|
||||||
tls->ctx = ctx;
|
|
||||||
tls->ssl = SSL_new(tls->ctx);
|
|
||||||
tls->bio_in = BIO_new(BIO_s_mem());
|
|
||||||
tls->bio_out = BIO_new(BIO_s_mem());
|
|
||||||
tls->connected = -1;
|
|
||||||
tls->buffer = buffer_new();
|
|
||||||
|
|
||||||
#ifdef SSL_MODE_RELEASE_BUFFERS
|
|
||||||
long mode = SSL_get_mode(tls->ssl);
|
|
||||||
SSL_set_mode(tls->ssl, mode | SSL_MODE_RELEASE_BUFFERS);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (tls->ssl == NULL)
|
|
||||||
printf("tls> %s", "Out of Memory");
|
|
||||||
|
|
||||||
SSL_set_connect_state(tls->ssl);
|
|
||||||
SSL_set_bio(tls->ssl, tls->bio_in, tls->bio_out);
|
|
||||||
return tls;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
tls_shutdown(tls_t * tls) {
|
|
||||||
assert(tls != NULL);
|
|
||||||
if (SSL_shutdown(tls->ssl) == 0) {
|
|
||||||
SSL_shutdown(tls->ssl);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
tls_free(tls_t * tls) {
|
|
||||||
if (tls->ssl) {
|
|
||||||
SSL_free(tls->ssl);
|
|
||||||
SSL_CTX_free(tls->ctx);
|
|
||||||
tls->ssl = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer_free(tls->buffer);
|
|
||||||
free(tls);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
tls_get_peer_cert(tls_t *tls) {
|
|
||||||
X509* peer_cert = SSL_get_peer_certificate(tls->ssl);
|
|
||||||
if (peer_cert != NULL) {
|
|
||||||
/*
|
|
||||||
* TODO(Yorkie): This function is used just for debug
|
|
||||||
*/
|
|
||||||
X509_free(peer_cert);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
tls_connect(tls_t *tls) {
|
|
||||||
int rv;
|
|
||||||
int er;
|
|
||||||
|
|
||||||
rv = SSL_do_handshake(tls->ssl);
|
|
||||||
if (rv == 1) {
|
|
||||||
/*
|
|
||||||
* `SSL_do_handshake()` could not return 1,
|
|
||||||
* that caused no message could be returned in `SSL_get_error()`.
|
|
||||||
* TODO(Yorkie): handle error, exit?
|
|
||||||
*/
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SSL_is_init_finished(tls->ssl))
|
|
||||||
er = SSL_connect(tls->ssl);
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (er < 0 && SSL_get_error(tls->ssl, er) == SSL_ERROR_WANT_READ)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
tls_handle_bio_error(tls_t *tls, int err) {
|
|
||||||
int rv;
|
|
||||||
int retry = BIO_should_retry(tls->bio_out);
|
|
||||||
if (BIO_should_write(tls->bio_out))
|
|
||||||
rv = -retry;
|
|
||||||
else if (BIO_should_read(tls->bio_out))
|
|
||||||
rv = -retry;
|
|
||||||
else {
|
|
||||||
char ssl_error_buf[512];
|
|
||||||
ERR_error_string_n(err, ssl_error_buf, sizeof(ssl_error_buf));
|
|
||||||
fprintf(stderr, "[%p] BIO: read failed: (%d) %s\n", tls->ssl, err, ssl_error_buf);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
tls_handle_ssl_error(tls_t *tls, int err) {
|
|
||||||
int ret;
|
|
||||||
int rv = SSL_get_error(tls->ssl, err);
|
|
||||||
switch (rv) {
|
|
||||||
case SSL_ERROR_WANT_READ:
|
|
||||||
ret = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = -2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
tls_bio_read(tls_t *tls, int buf_len) {
|
|
||||||
if (buf_len == 0) {
|
|
||||||
buf_len = sizeof(tls->buf);
|
|
||||||
}
|
|
||||||
memset(tls->buf, 0, buf_len);
|
|
||||||
|
|
||||||
int ret = BIO_read(tls->bio_out, tls->buf, buf_len);
|
|
||||||
if (ret >= 0) {
|
|
||||||
tls->buf[ret] = 0;
|
|
||||||
return ret;
|
|
||||||
} else {
|
|
||||||
return tls_handle_bio_error(tls, ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
tls_bio_write(tls_t *tls, char *buf, int len) {
|
|
||||||
int ret = BIO_write(tls->bio_in, buf, len);
|
|
||||||
if (ret >= 0)
|
|
||||||
return ret;
|
|
||||||
else
|
|
||||||
return tls_handle_bio_error(tls, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
tls_read(tls_t *tls) {
|
|
||||||
int err;
|
|
||||||
int ret;
|
|
||||||
int read;
|
|
||||||
|
|
||||||
int done = SSL_is_init_finished(tls->ssl);
|
|
||||||
if (!done) {
|
|
||||||
err = SSL_connect(tls->ssl);
|
|
||||||
if (err <= 0) {
|
|
||||||
return tls_handle_ssl_error(tls, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO(Yorkie): returns not 1 nor < 0
|
|
||||||
*/
|
|
||||||
assert(err == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* finished */
|
|
||||||
buffer_clear(tls->buffer);
|
|
||||||
|
|
||||||
ret = -1;
|
|
||||||
do {
|
|
||||||
read = SSL_read(tls->ssl, tls->buf, SSL_CHUNK_SIZE);
|
|
||||||
if (read > 0) {
|
|
||||||
ret = 0;
|
|
||||||
tls->buf[read] = 0;
|
|
||||||
buffer_append(tls->buffer, tls->buf);
|
|
||||||
} else {
|
|
||||||
tls_handle_ssl_error(tls, read);
|
|
||||||
}
|
|
||||||
} while (read > 0);
|
|
||||||
|
|
||||||
if (tls->connected == -1) {
|
|
||||||
tls->connected = 1;
|
|
||||||
} else {
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
tls_write(tls_t *tls, char *buf_w, int len) {
|
|
||||||
return SSL_write(tls->ssl, buf_w, len);
|
|
||||||
}
|
|
|
@ -1013,9 +1013,4 @@ bool Options::parseCCUrl(const char* url)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Options::setForcePowVersion(Options::PowVersion powVersion)
|
|
||||||
{
|
|
||||||
m_forcePowVersion = powVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -113,8 +113,6 @@ public:
|
||||||
|
|
||||||
const char *algoName() const;
|
const char *algoName() const;
|
||||||
|
|
||||||
void setForcePowVersion(PowVersion version);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
constexpr static uint16_t kDefaultCCPort = 3344;
|
constexpr static uint16_t kDefaultCCPort = 3344;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define WIN32_LEAN_AND_MEAN /* avoid including junk */
|
#define WIN32_LEAN_AND_MEAN /* avoid including junk */
|
||||||
|
@ -66,21 +67,15 @@ int main(int argc, char **argv) {
|
||||||
do {
|
do {
|
||||||
status = system(xmrigMinerPath.c_str());
|
status = system(xmrigMinerPath.c_str());
|
||||||
#if defined(_WIN32) || defined(WIN32)
|
#if defined(_WIN32) || defined(WIN32)
|
||||||
if (status == 255) { // 255 segfault on windows
|
} while (status != EINVAL && status != SIGHUP && status != SIGINT);
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
||||||
printf("Crashed. Restarting in 1s.\n");
|
|
||||||
}
|
|
||||||
} while (status == EINTR || status == 255); // 255 segfault on windows
|
|
||||||
|
|
||||||
|
|
||||||
if (status == EINVAL) {
|
if (status == EINVAL) {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (WEXITSTATUS(status) == 139) { // 139 segfault on *nix
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
printf("Exit: %d converted WEXITSTATUS: %d\n", status, WEXITSTATUS(status));
|
||||||
printf("Crashed. Restarting in 1s.\n");
|
|
||||||
}
|
} while (WEXITSTATUS(status) != EINVAL && WEXITSTATUS(status) != SIGHUP && WEXITSTATUS(status) != SIGINT);
|
||||||
} while (WEXITSTATUS(status) == EINTR || WEXITSTATUS(status) == 139); // 139 segfault on *nix
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,10 +34,10 @@
|
||||||
#include "crypto/CryptoNight_test.h"
|
#include "crypto/CryptoNight_test.h"
|
||||||
|
|
||||||
template <size_t NUM_HASH_BLOCKS>
|
template <size_t NUM_HASH_BLOCKS>
|
||||||
static void cryptonight_aesni(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
static void cryptonight_aesni(Options::PowVersion powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
||||||
# if !defined(XMRIG_ARMv7)
|
# if !defined(XMRIG_ARMv7)
|
||||||
if ((reinterpret_cast<const uint8_t*>(input)[0] > 6 && Options::i()->forcePowVersion() == Options::PowVersion::POW_AUTODETECT) ||
|
if ((reinterpret_cast<const uint8_t*>(input)[0] > 6 && powVersion == Options::PowVersion::POW_AUTODETECT) ||
|
||||||
Options::i()->forcePowVersion() == Options::PowVersion::POW_V2) {
|
powVersion == Options::PowVersion::POW_V2) {
|
||||||
CryptoNightMultiHash<0x80000, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
CryptoNightMultiHash<0x80000, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
||||||
} else {
|
} else {
|
||||||
CryptoNightMultiHash<0x80000, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
|
CryptoNightMultiHash<0x80000, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
|
||||||
|
@ -46,9 +46,9 @@ static void cryptonight_aesni(const uint8_t* input, size_t size, uint8_t* output
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t NUM_HASH_BLOCKS>
|
template <size_t NUM_HASH_BLOCKS>
|
||||||
static void cryptonight_softaes(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
static void cryptonight_softaes(Options::PowVersion powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
||||||
if ((reinterpret_cast<const uint8_t*>(input)[0] > 6 && Options::i()->forcePowVersion() == Options::PowVersion::POW_AUTODETECT) ||
|
if ((reinterpret_cast<const uint8_t*>(input)[0] > 6 && powVersion == Options::PowVersion::POW_AUTODETECT) ||
|
||||||
Options::i()->forcePowVersion() == Options::PowVersion::POW_V2) {
|
powVersion == Options::PowVersion::POW_V2) {
|
||||||
CryptoNightMultiHash<0x80000, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
CryptoNightMultiHash<0x80000, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
||||||
} else {
|
} else {
|
||||||
CryptoNightMultiHash<0x80000, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
|
CryptoNightMultiHash<0x80000, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
|
||||||
|
@ -56,10 +56,10 @@ static void cryptonight_softaes(const uint8_t* input, size_t size, uint8_t* outp
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t NUM_HASH_BLOCKS>
|
template <size_t NUM_HASH_BLOCKS>
|
||||||
static void cryptonight_lite_aesni(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
static void cryptonight_lite_aesni(Options::PowVersion powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
||||||
# if !defined(XMRIG_ARMv7)
|
# if !defined(XMRIG_ARMv7)
|
||||||
if ((reinterpret_cast<const uint8_t*>(input)[0] > 1 && Options::i()->forcePowVersion() == Options::PowVersion::POW_AUTODETECT) ||
|
if ((reinterpret_cast<const uint8_t*>(input)[0] > 1 && powVersion == Options::PowVersion::POW_AUTODETECT) ||
|
||||||
Options::i()->forcePowVersion() == Options::PowVersion::POW_V2) {
|
powVersion == Options::PowVersion::POW_V2) {
|
||||||
CryptoNightMultiHash<0x40000, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
CryptoNightMultiHash<0x40000, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
||||||
} else {
|
} else {
|
||||||
CryptoNightMultiHash<0x40000, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
|
CryptoNightMultiHash<0x40000, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
|
||||||
|
@ -68,9 +68,9 @@ static void cryptonight_lite_aesni(const uint8_t* input, size_t size, uint8_t* o
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t NUM_HASH_BLOCKS>
|
template <size_t NUM_HASH_BLOCKS>
|
||||||
static void cryptonight_lite_softaes(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
static void cryptonight_lite_softaes(Options::PowVersion powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
||||||
if ((reinterpret_cast<const uint8_t*>(input)[0] > 1 && Options::i()->forcePowVersion() == Options::PowVersion::POW_AUTODETECT) ||
|
if ((reinterpret_cast<const uint8_t*>(input)[0] > 1 && powVersion == Options::PowVersion::POW_AUTODETECT) ||
|
||||||
Options::i()->forcePowVersion() == Options::PowVersion::POW_V2) {
|
powVersion == Options::PowVersion::POW_V2) {
|
||||||
CryptoNightMultiHash<0x40000, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
CryptoNightMultiHash<0x40000, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
||||||
} else {
|
} else {
|
||||||
CryptoNightMultiHash<0x40000, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
|
CryptoNightMultiHash<0x40000, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
|
||||||
|
@ -79,18 +79,18 @@ static void cryptonight_lite_softaes(const uint8_t* input, size_t size, uint8_t*
|
||||||
|
|
||||||
|
|
||||||
template <size_t NUM_HASH_BLOCKS>
|
template <size_t NUM_HASH_BLOCKS>
|
||||||
static void cryptonight_heavy_aesni(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
static void cryptonight_heavy_aesni(Options::PowVersion powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
||||||
# if !defined(XMRIG_ARMv7)
|
# if !defined(XMRIG_ARMv7)
|
||||||
CryptoNightMultiHash<0x40000, MEMORY_HEAVY, 0x3FFFF0, false, NUM_HASH_BLOCKS>::hashHeavy(input, size, output, ctx);
|
CryptoNightMultiHash<0x40000, MEMORY_HEAVY, 0x3FFFF0, false, NUM_HASH_BLOCKS>::hashHeavy(input, size, output, ctx);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t NUM_HASH_BLOCKS>
|
template <size_t NUM_HASH_BLOCKS>
|
||||||
static void cryptonight_heavy_softaes(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
static void cryptonight_heavy_softaes(Options::PowVersion powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
||||||
CryptoNightMultiHash<0x40000, MEMORY_HEAVY, 0x3FFFF0, true, NUM_HASH_BLOCKS>::hashHeavy(input, size, output, ctx);
|
CryptoNightMultiHash<0x40000, MEMORY_HEAVY, 0x3FFFF0, true, NUM_HASH_BLOCKS>::hashHeavy(input, size, output, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void (*cryptonight_hash_ctx[MAX_NUM_HASH_BLOCKS])(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx);
|
void (*cryptonight_hash_ctx[MAX_NUM_HASH_BLOCKS])(Options::PowVersion powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx);
|
||||||
|
|
||||||
template <size_t HASH_FACTOR>
|
template <size_t HASH_FACTOR>
|
||||||
void setCryptoNightHashMethods(Options::Algo algo, bool aesni)
|
void setCryptoNightHashMethods(Options::Algo algo, bool aesni)
|
||||||
|
@ -136,9 +136,9 @@ bool CryptoNight::init(int algo, bool aesni)
|
||||||
return selfTest(algo);
|
return selfTest(algo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CryptoNight::hash(size_t factor, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx)
|
void CryptoNight::hash(size_t factor, Options::PowVersion powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx)
|
||||||
{
|
{
|
||||||
cryptonight_hash_ctx[factor-1](input, size, output, ctx);
|
cryptonight_hash_ctx[factor-1](powVersion, input, size, output, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CryptoNight::selfTest(int algo)
|
bool CryptoNight::selfTest(int algo)
|
||||||
|
@ -169,81 +169,82 @@ bool CryptoNight::selfTest(int algo)
|
||||||
bool resultV2Pow = true;
|
bool resultV2Pow = true;
|
||||||
bool resultHeavy = true;
|
bool resultHeavy = true;
|
||||||
|
|
||||||
if (algo == Options::ALGO_CRYPTONIGHT_HEAVY)
|
if (algo == Options::ALGO_CRYPTONIGHT_HEAVY) {
|
||||||
{
|
// cn-heavy tests
|
||||||
cryptonight_hash_ctx[0](test_input, 76, output, ctx);
|
|
||||||
|
cryptonight_hash_ctx[0](Options::PowVersion::POW_AUTODETECT, test_input, 76, output, ctx);
|
||||||
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 32) == 0;
|
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 32) == 0;
|
||||||
|
|
||||||
#if MAX_NUM_HASH_BLOCKS > 1
|
#if MAX_NUM_HASH_BLOCKS > 1
|
||||||
cryptonight_hash_ctx[1](test_input, 76, output, ctx);
|
cryptonight_hash_ctx[1](Options::PowVersion::POW_AUTODETECT, test_input, 76, output, ctx);
|
||||||
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 64) == 0;
|
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 64) == 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MAX_NUM_HASH_BLOCKS > 2
|
#if MAX_NUM_HASH_BLOCKS > 2
|
||||||
cryptonight_hash_ctx[2](test_input, 76, output, ctx);
|
cryptonight_hash_ctx[2](Options::PowVersion::POW_AUTODETECT, test_input, 76, output, ctx);
|
||||||
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 96) == 0;
|
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 96) == 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (Options::i()->forcePowVersion() == Options::PowVersion::POW_AUTODETECT ||
|
// < v7 tests autodetect
|
||||||
Options::i()->forcePowVersion() == Options::PowVersion::POW_V1) {
|
cryptonight_hash_ctx[0](Options::PowVersion::POW_AUTODETECT,test_input, 76, output, ctx);
|
||||||
cryptonight_hash_ctx[0](test_input, 76, output, ctx);
|
|
||||||
resultV1Pow = resultV1Pow &&
|
resultV1Pow = resultV1Pow &&
|
||||||
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
|
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
|
||||||
32) == 0;
|
32) == 0;
|
||||||
|
|
||||||
#if MAX_NUM_HASH_BLOCKS > 1
|
#if MAX_NUM_HASH_BLOCKS > 1
|
||||||
cryptonight_hash_ctx[1](test_input, 76, output, ctx);
|
cryptonight_hash_ctx[1](Options::PowVersion::POW_AUTODETECT, test_input, 76, output, ctx);
|
||||||
resultV1Pow = resultV1Pow &&
|
resultV1Pow = resultV1Pow &&
|
||||||
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
|
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
|
||||||
64) == 0;
|
64) == 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MAX_NUM_HASH_BLOCKS > 2
|
#if MAX_NUM_HASH_BLOCKS > 2
|
||||||
cryptonight_hash_ctx[2](test_input, 76, output, ctx);
|
cryptonight_hash_ctx[2](Options::PowVersion::POW_AUTODETECT, test_input, 76, output, ctx);
|
||||||
resultV1Pow = resultV1Pow &&
|
resultV1Pow = resultV1Pow &&
|
||||||
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
|
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
|
||||||
96) == 0;
|
96) == 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// < v7 tests force pow
|
||||||
#if MAX_NUM_HASH_BLOCKS > 3
|
#if MAX_NUM_HASH_BLOCKS > 3
|
||||||
cryptonight_hash_ctx[3](test_input, 76, output, ctx);
|
cryptonight_hash_ctx[3](Options::PowVersion::POW_V1, test_input, 76, output, ctx);
|
||||||
resultV1Pow = resultV1Pow &&
|
resultV1Pow = resultV1Pow &&
|
||||||
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
|
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
|
||||||
128) == 0;
|
128) == 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MAX_NUM_HASH_BLOCKS > 4
|
#if MAX_NUM_HASH_BLOCKS > 4
|
||||||
cryptonight_hash_ctx[4](test_input, 76, output, ctx);
|
cryptonight_hash_ctx[4](Options::PowVersion::POW_V1, test_input, 76, output, ctx);
|
||||||
resultV1Pow = resultV1Pow &&
|
resultV1Pow = resultV1Pow &&
|
||||||
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
|
memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_light : test_output,
|
||||||
160) == 0;
|
160) == 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
// monero/aeon v2 pow (monero/aeon blockchain version 7)
|
// v7 tests autodetect
|
||||||
if (Options::i()->forcePowVersion() == Options::PowVersion::POW_AUTODETECT ||
|
cryptonight_hash_ctx[0](Options::PowVersion::POW_AUTODETECT, test_input_monero_v2_pow_0,
|
||||||
Options::i()->forcePowVersion() == Options::PowVersion::POW_V2) {
|
sizeof(test_input_monero_v2_pow_0), output, ctx);
|
||||||
cryptonight_hash_ctx[0](test_input_monero_v2_pow_0, sizeof(test_input_monero_v2_pow_0), output, ctx);
|
|
||||||
resultV2Pow = resultV2Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE
|
resultV2Pow = resultV2Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE
|
||||||
? test_output_monero_v2_pow_light[0]
|
? test_output_monero_v2_pow_light[0]
|
||||||
: test_output_monero_v2_pow[0], 32) == 0;
|
: test_output_monero_v2_pow[0], 32) == 0;
|
||||||
|
|
||||||
#if MAX_NUM_HASH_BLOCKS > 1
|
#if MAX_NUM_HASH_BLOCKS > 1
|
||||||
cryptonight_hash_ctx[1](test_input_monero_v2_pow_1, sizeof(test_input_monero_v2_pow_1), output, ctx);
|
cryptonight_hash_ctx[1](Options::PowVersion::POW_AUTODETECT, test_input_monero_v2_pow_1,
|
||||||
|
sizeof(test_input_monero_v2_pow_1), output, ctx);
|
||||||
resultV2Pow = resultV2Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE
|
resultV2Pow = resultV2Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE
|
||||||
? test_output_monero_v2_pow_light[1]
|
? test_output_monero_v2_pow_light[1]
|
||||||
: test_output_monero_v2_pow[1], 32) == 0;
|
: test_output_monero_v2_pow[1], 32) == 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// v7 tests force pow
|
||||||
#if MAX_NUM_HASH_BLOCKS > 2
|
#if MAX_NUM_HASH_BLOCKS > 2
|
||||||
cryptonight_hash_ctx[2](test_input_monero_v2_pow_2, sizeof(test_input_monero_v2_pow_2), output, ctx);
|
cryptonight_hash_ctx[2](Options::PowVersion::POW_V2, test_input_monero_v2_pow_2,
|
||||||
|
sizeof(test_input_monero_v2_pow_2), output, ctx);
|
||||||
resultV2Pow = resultV2Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE
|
resultV2Pow = resultV2Pow && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE
|
||||||
? test_output_monero_v2_pow_light[2]
|
? test_output_monero_v2_pow_light[2]
|
||||||
: test_output_monero_v2_pow[2], 32) == 0;
|
: test_output_monero_v2_pow[2], 32) == 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_mm_free(ctx->memory);
|
_mm_free(ctx->memory);
|
||||||
_mm_free(ctx);
|
_mm_free(ctx);
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ class CryptoNight
|
||||||
public:
|
public:
|
||||||
static bool init(int algo, bool aesni);
|
static bool init(int algo, bool aesni);
|
||||||
|
|
||||||
static void hash(size_t factor, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx);
|
static void hash(size_t factor, Options::PowVersion powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool selfTest(int algo);
|
static bool selfTest(int algo);
|
||||||
|
|
|
@ -36,8 +36,24 @@
|
||||||
Log *Log::m_self = nullptr;
|
Log *Log::m_self = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
Log::Log()
|
||||||
|
{
|
||||||
|
uv_mutex_init(&m_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::~Log()
|
||||||
|
{
|
||||||
|
for (auto backend : m_backends) {
|
||||||
|
delete backend;
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_mutex_destroy(&m_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
void Log::message(Log::Level level, const char* fmt, ...)
|
void Log::message(Log::Level level, const char* fmt, ...)
|
||||||
{
|
{
|
||||||
|
uv_mutex_lock(&m_mutex);
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_list copy;
|
va_list copy;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
@ -47,11 +63,15 @@ void Log::message(Log::Level level, const char* fmt, ...)
|
||||||
backend->message(level, fmt, copy);
|
backend->message(level, fmt, copy);
|
||||||
va_end(copy);
|
va_end(copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uv_mutex_unlock(&m_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Log::text(const char* fmt, ...)
|
void Log::text(const char* fmt, ...)
|
||||||
{
|
{
|
||||||
|
uv_mutex_lock(&m_mutex);
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_list copy;
|
va_list copy;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
@ -63,12 +83,6 @@ void Log::text(const char* fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
|
||||||
|
|
||||||
|
uv_mutex_unlock(&m_mutex);
|
||||||
Log::~Log()
|
|
||||||
{
|
|
||||||
for (auto backend : m_backends) {
|
|
||||||
delete backend;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,10 +63,12 @@ public:
|
||||||
void text(const char* fmt, ...);
|
void text(const char* fmt, ...);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline Log() {}
|
Log();
|
||||||
~Log();
|
~Log();
|
||||||
|
|
||||||
static Log *m_self;
|
static Log *m_self;
|
||||||
|
|
||||||
|
uv_mutex_t m_mutex;
|
||||||
std::vector<ILogBackend*> m_backends;
|
std::vector<ILogBackend*> m_backends;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
144
src/net/BoostConnection.h
Normal file
144
src/net/BoostConnection.h
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
/* XMRigCC
|
||||||
|
* Copyright 2018 Sebastian Stolzenberg <https://github.com/sebastianstolzenberg>
|
||||||
|
* Copyright 2018- BenDr0id <ben@graef.in>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BOOSTCONNECTION_H__
|
||||||
|
#define __BOOSTCONNECTION_H__
|
||||||
|
|
||||||
|
#include "net/Connection.h"
|
||||||
|
#include "log/Log.h"
|
||||||
|
|
||||||
|
template <class SOCKET>
|
||||||
|
class BoostConnection : public Connection, public std::enable_shared_from_this<BoostConnection<SOCKET> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BoostConnection(const ConnectionListener::Ptr& listener)
|
||||||
|
: Connection(listener)
|
||||||
|
, socket_(ioService_)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~BoostConnection()
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void connect(const std::string& server, uint16_t port) override
|
||||||
|
{
|
||||||
|
LOG_DEBUG("[%s:%d] Connecting", server.c_str(), port);
|
||||||
|
|
||||||
|
boost::asio::ip::tcp::resolver resolver(ioService_);
|
||||||
|
boost::asio::ip::tcp::resolver::query query(server, std::to_string(port));
|
||||||
|
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
|
||||||
|
|
||||||
|
socket_.connect(iterator,
|
||||||
|
boost::bind(&BoostConnection::handleConnect, this->shared_from_this(),
|
||||||
|
boost::asio::placeholders::error));
|
||||||
|
|
||||||
|
std::thread([this]() { ioService_.run(); }).detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleConnect(const boost::system::error_code& error)
|
||||||
|
{
|
||||||
|
if (!error) {
|
||||||
|
startReading();
|
||||||
|
LOG_DEBUG("[%s:%d] Connected", getConnectedIp().c_str(), getConnectedPort());
|
||||||
|
notifyConnected();
|
||||||
|
} else {
|
||||||
|
notifyError(error.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void disconnect() override
|
||||||
|
{
|
||||||
|
if (isConnected()) {
|
||||||
|
LOG_DEBUG("[%s:%d] Disconnecting", getConnectedIp().c_str(), getConnectedPort());
|
||||||
|
socket_.get().lowest_layer().close();
|
||||||
|
}
|
||||||
|
|
||||||
|
ioService_.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isConnected() const override
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
socket_.get().lowest_layer().remote_endpoint(ec);
|
||||||
|
return !ec && socket_.get().lowest_layer().is_open();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getConnectedIp() const override
|
||||||
|
{
|
||||||
|
return isConnected() ? socket_.get().lowest_layer().remote_endpoint().address().to_string() : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getConnectedPort() const override
|
||||||
|
{
|
||||||
|
return isConnected() ? socket_.get().lowest_layer().remote_endpoint().port() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void send(const char* data, std::size_t size) override
|
||||||
|
{
|
||||||
|
LOG_DEBUG("[%s:%d] Sending: %.*s", getConnectedIp().c_str(), getConnectedPort(), size, data);
|
||||||
|
|
||||||
|
boost::asio::async_write(socket_.get(),
|
||||||
|
boost::asio::buffer(data, size),
|
||||||
|
boost::bind(&BoostConnection::handleWrite, this->shared_from_this(),
|
||||||
|
boost::asio::placeholders::error,
|
||||||
|
boost::asio::placeholders::bytes_transferred));
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleWrite(const boost::system::error_code& error,
|
||||||
|
size_t bytes_transferred)
|
||||||
|
{
|
||||||
|
if (error) {
|
||||||
|
LOG_DEBUG_ERR("[%s:%d] Sending failed: %s", getConnectedIp().c_str(), getConnectedPort(), error.message().c_str());
|
||||||
|
notifyError(error.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void startReading()
|
||||||
|
{
|
||||||
|
boost::asio::async_read(socket_.get(),
|
||||||
|
boost::asio::buffer(receiveBuffer_, sizeof(receiveBuffer_)),
|
||||||
|
boost::asio::transfer_at_least(1),
|
||||||
|
boost::bind(&BoostConnection::handleRead, this->shared_from_this(),
|
||||||
|
boost::asio::placeholders::error,
|
||||||
|
boost::asio::placeholders::bytes_transferred));
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleRead(const boost::system::error_code& error,
|
||||||
|
size_t bytes_transferred)
|
||||||
|
{
|
||||||
|
if (!error) {
|
||||||
|
LOG_DEBUG("[%s:%d] Read: %.*s", getConnectedIp().c_str(), getConnectedPort(), bytes_transferred, receiveBuffer_);
|
||||||
|
notifyRead(receiveBuffer_, bytes_transferred);
|
||||||
|
startReading();
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG_ERR("[%s:%d] Read failed: %s", getConnectedIp().c_str(), getConnectedPort(), error.message().c_str());
|
||||||
|
notifyError(error.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::asio::io_service ioService_;
|
||||||
|
SOCKET socket_;
|
||||||
|
char receiveBuffer_[2048];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __BOOSTCONNECTION_H__ */
|
72
src/net/BoostTcpConnection.cpp
Normal file
72
src/net/BoostTcpConnection.cpp
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/* XMRigCC
|
||||||
|
* Copyright 2018 Sebastian Stolzenberg <https://github.com/sebastianstolzenberg>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
|
#include "net/BoostConnection.h"
|
||||||
|
#include "net/BoostTcpConnection.h"
|
||||||
|
|
||||||
|
class BoostTcpSocket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::asio::ip::tcp::socket SocketType;
|
||||||
|
public:
|
||||||
|
BoostTcpSocket(boost::asio::io_service& ioService)
|
||||||
|
: socket_(ioService)
|
||||||
|
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ITERATOR, class HANDLER>
|
||||||
|
void connect(ITERATOR& iterator, HANDLER handler)
|
||||||
|
{
|
||||||
|
boost::asio::async_connect(
|
||||||
|
socket_, iterator,
|
||||||
|
[this, handler](const boost::system::error_code& ec, const ITERATOR& iterator)
|
||||||
|
{
|
||||||
|
if (!ec) {
|
||||||
|
socket_.set_option(boost::asio::ip::tcp::no_delay(true));
|
||||||
|
socket_.set_option(boost::asio::socket_base::keep_alive(true));
|
||||||
|
}
|
||||||
|
handler(ec);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SocketType& get()
|
||||||
|
{
|
||||||
|
return socket_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SocketType& get() const
|
||||||
|
{
|
||||||
|
return socket_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SocketType socket_;
|
||||||
|
};
|
||||||
|
|
||||||
|
Connection::Ptr establishBoostTcpConnection(const ConnectionListener::Ptr& listener)
|
||||||
|
{
|
||||||
|
return std::make_shared<BoostConnection<BoostTcpSocket> >(listener);
|
||||||
|
}
|
26
src/net/BoostTcpConnection.h
Normal file
26
src/net/BoostTcpConnection.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/* XMRigCC
|
||||||
|
* Copyright 2018 Sebastian Stolzenberg <https://github.com/sebastianstolzenberg>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BOOSTTCPCONNECTION_H__
|
||||||
|
#define __BOOSTTCPCONNECTION_H__
|
||||||
|
|
||||||
|
#include "net/Connection.h"
|
||||||
|
|
||||||
|
Connection::Ptr establishBoostTcpConnection(const ConnectionListener::Ptr& listener);
|
||||||
|
|
||||||
|
#endif /* __BOOSTTCPCONNECTION_H__ */
|
83
src/net/BoostTlsConnection.cpp
Normal file
83
src/net/BoostTlsConnection.cpp
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
/* XMRigCC
|
||||||
|
* Copyright 2018 Sebastian Stolzenberg <https://github.com/sebastianstolzenberg>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include <boost/asio/ssl.hpp>
|
||||||
|
|
||||||
|
#include "net/BoostConnection.h"
|
||||||
|
#include "net/BoostTlsConnection.h"
|
||||||
|
|
||||||
|
class BoostTlsSocket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SocketType;
|
||||||
|
public:
|
||||||
|
BoostTlsSocket(boost::asio::io_service& ioService)
|
||||||
|
: sslContext_(boost::asio::ssl::context::sslv23_client)
|
||||||
|
, socket_(ioService, sslContext_)
|
||||||
|
|
||||||
|
{
|
||||||
|
socket_.set_verify_mode(boost::asio::ssl::verify_none);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ITERATOR, class HANDLER>
|
||||||
|
void connect(ITERATOR& iterator, HANDLER handler)
|
||||||
|
{
|
||||||
|
boost::asio::async_connect(
|
||||||
|
socket_.lowest_layer(), iterator,
|
||||||
|
[this, handler](const boost::system::error_code& ec, const ITERATOR& iterator)
|
||||||
|
{
|
||||||
|
if (!ec) {
|
||||||
|
socket_.lowest_layer().set_option(boost::asio::ip::tcp::no_delay(true));
|
||||||
|
socket_.lowest_layer().set_option(boost::asio::socket_base::keep_alive(true));
|
||||||
|
socket_.async_handshake(
|
||||||
|
boost::asio::ssl::stream_base::client,
|
||||||
|
[handler](const boost::system::error_code& ec) {
|
||||||
|
handler(ec);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
handler(ec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SocketType& get()
|
||||||
|
{
|
||||||
|
return socket_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SocketType& get() const
|
||||||
|
{
|
||||||
|
return socket_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::asio::ssl::context sslContext_;
|
||||||
|
SocketType socket_;
|
||||||
|
};
|
||||||
|
|
||||||
|
Connection::Ptr establishBoostTlsConnection(const ConnectionListener::Ptr& listener)
|
||||||
|
{
|
||||||
|
return std::make_shared<BoostConnection<BoostTlsSocket> >(listener);
|
||||||
|
}
|
26
src/net/BoostTlsConnection.h
Normal file
26
src/net/BoostTlsConnection.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/* XMRigCC
|
||||||
|
* Copyright 2018 Sebastian Stolzenberg <https://github.com/sebastianstolzenberg>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BOOSTTLSCONNECTION_H__
|
||||||
|
#define __BOOSTTLSCONNECTION_H__
|
||||||
|
|
||||||
|
#include "net/Connection.h"
|
||||||
|
|
||||||
|
Connection::Ptr establishBoostTlsConnection(const ConnectionListener::Ptr& listener);
|
||||||
|
|
||||||
|
#endif /* __BOOSTTLSCONNECTION_H__ */
|
|
@ -5,6 +5,7 @@
|
||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||||
|
* Copyright 2018 Sebastian Stolzenberg <https://github.com/sebastianstolzenberg>
|
||||||
* Copyright 2018- BenDr0id <ben@graef.in>
|
* Copyright 2018- BenDr0id <ben@graef.in>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -32,19 +33,12 @@
|
||||||
#include "interfaces/IClientListener.h"
|
#include "interfaces/IClientListener.h"
|
||||||
#include "log/Log.h"
|
#include "log/Log.h"
|
||||||
#include "net/Client.h"
|
#include "net/Client.h"
|
||||||
|
#include "net/JobResult.h"
|
||||||
#include "rapidjson/document.h"
|
#include "rapidjson/document.h"
|
||||||
#include "rapidjson/error/en.h"
|
#include "rapidjson/error/en.h"
|
||||||
#include "rapidjson/stringbuffer.h"
|
#include "rapidjson/stringbuffer.h"
|
||||||
#include "rapidjson/writer.h"
|
#include "rapidjson/writer.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef XMRIG_PROXY_PROJECT
|
|
||||||
# include "proxy/JobResult.h"
|
|
||||||
#else
|
|
||||||
# include "net/JobResult.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
|
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
|
||||||
#endif
|
#endif
|
||||||
|
@ -68,40 +62,51 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
|
||||||
m_recvBuf.base = m_buf;
|
m_recvBuf.base = m_buf;
|
||||||
m_recvBuf.len = sizeof(m_buf);
|
m_recvBuf.len = sizeof(m_buf);
|
||||||
|
|
||||||
# ifndef XMRIG_PROXY_PROJECT
|
|
||||||
m_keepAliveTimer.data = this;
|
m_keepAliveTimer.data = this;
|
||||||
|
|
||||||
uv_timer_init(uv_default_loop(), &m_keepAliveTimer);
|
uv_timer_init(uv_default_loop(), &m_keepAliveTimer);
|
||||||
# endif
|
|
||||||
|
uv_mutex_init(&m_mutex);
|
||||||
|
|
||||||
|
uv_async_init(uv_default_loop(), &onConnectedAsync, Client::onConnected);
|
||||||
|
uv_async_init(uv_default_loop(), &onReceivedAsync, Client::onReceived);
|
||||||
|
uv_async_init(uv_default_loop(), &onErrorAsync, Client::onError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Client::~Client()
|
Client::~Client()
|
||||||
{
|
{
|
||||||
if (m_net) {
|
uv_close((uv_handle_t*) &onConnectedAsync, NULL);
|
||||||
net_free(m_net);
|
uv_close((uv_handle_t*) &onReceivedAsync, NULL);
|
||||||
}
|
uv_close((uv_handle_t*) &onErrorAsync, NULL);
|
||||||
|
|
||||||
|
uv_mutex_destroy(&m_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Connect to server.
|
|
||||||
*
|
|
||||||
* @param url
|
|
||||||
*/
|
|
||||||
void Client::connect(const Url *url)
|
void Client::connect(const Url *url)
|
||||||
{
|
{
|
||||||
|
LOG_DEBUG("connect %s", url);
|
||||||
|
|
||||||
setUrl(url);
|
setUrl(url);
|
||||||
connect();
|
connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Client::connect()
|
||||||
|
{
|
||||||
|
LOG_DEBUG("connect");
|
||||||
|
|
||||||
|
m_connection = establishConnection(shared_from_this(),
|
||||||
|
m_url.useTls() ? CONNECTION_TYPE_TLS : CONNECTION_TYPE_TCP,
|
||||||
|
m_url.host(), m_url.port());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Client::disconnect()
|
void Client::disconnect()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Client::disconnect");
|
LOG_DEBUG("disconnect");
|
||||||
|
|
||||||
# ifndef XMRIG_PROXY_PROJECT
|
|
||||||
uv_timer_stop(&m_keepAliveTimer);
|
uv_timer_stop(&m_keepAliveTimer);
|
||||||
# endif
|
|
||||||
|
|
||||||
m_expire = 0;
|
m_expire = 0;
|
||||||
m_failures = -1;
|
m_failures = -1;
|
||||||
|
@ -112,6 +117,8 @@ void Client::disconnect()
|
||||||
|
|
||||||
void Client::setUrl(const Url *url)
|
void Client::setUrl(const Url *url)
|
||||||
{
|
{
|
||||||
|
LOG_DEBUG("setUrl");
|
||||||
|
|
||||||
if (!url || !url->isValid()) {
|
if (!url || !url->isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -126,12 +133,15 @@ void Client::tick(uint64_t now)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_net) {
|
LOG_DEBUG("tick expired");
|
||||||
|
|
||||||
|
if (m_connection) {
|
||||||
LOG_WARN("[%s:%u] timeout", m_url.host(), m_url.port());
|
LOG_WARN("[%s:%u] timeout", m_url.host(), m_url.port());
|
||||||
close();
|
LOG_DEBUG("tick -> reconnect");
|
||||||
|
reconnect();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG_DEBUG("Client::tick -> connect");
|
LOG_DEBUG("tick -> connect");
|
||||||
connect();
|
connect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,10 +149,6 @@ void Client::tick(uint64_t now)
|
||||||
|
|
||||||
int64_t Client::submit(const JobResult &result)
|
int64_t Client::submit(const JobResult &result)
|
||||||
{
|
{
|
||||||
# ifdef XMRIG_PROXY_PROJECT
|
|
||||||
const char *nonce = result.nonce;
|
|
||||||
const char *data = result.result;
|
|
||||||
# else
|
|
||||||
char nonce[9];
|
char nonce[9];
|
||||||
char data[65];
|
char data[65];
|
||||||
|
|
||||||
|
@ -151,13 +157,24 @@ int64_t Client::submit(const JobResult &result)
|
||||||
|
|
||||||
Job::toHex(result.result, 32, data);
|
Job::toHex(result.result, 32, data);
|
||||||
data[64] = '\0';
|
data[64] = '\0';
|
||||||
# endif
|
|
||||||
|
|
||||||
const size_t size = snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRIu64 ",\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n",
|
const int size = snprintf(m_sendBuf, sizeof(m_sendBuf),
|
||||||
|
"{"
|
||||||
|
"\"id\":%" PRIu64 ","
|
||||||
|
"\"jsonrpc\":\"2.0\","
|
||||||
|
"\"method\":\"submit\","
|
||||||
|
"\"params\":"
|
||||||
|
"{"
|
||||||
|
"\"id\":\"%s\","
|
||||||
|
"\"job_id\":\"%s\","
|
||||||
|
"\"nonce\":\"%s\","
|
||||||
|
"\"result\":\"%s\""
|
||||||
|
"}"
|
||||||
|
"}\n",
|
||||||
m_sequence, m_rpcId, result.jobId.data(), nonce, data);
|
m_sequence, m_rpcId, result.jobId.data(), nonce, data);
|
||||||
|
|
||||||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
|
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
|
||||||
return send(size);
|
return send(m_sendBuf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -191,6 +208,7 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code)
|
||||||
}
|
}
|
||||||
|
|
||||||
Job job(m_id, m_nicehash);
|
Job job(m_id, m_nicehash);
|
||||||
|
|
||||||
if (!job.setId(params["job_id"].GetString())) {
|
if (!job.setId(params["job_id"].GetString())) {
|
||||||
*code = 3;
|
*code = 3;
|
||||||
return false;
|
return false;
|
||||||
|
@ -211,17 +229,19 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code)
|
||||||
|
|
||||||
switch (variantFromProxy) {
|
switch (variantFromProxy) {
|
||||||
case -1:
|
case -1:
|
||||||
Options::i()->setForcePowVersion(Options::POW_AUTODETECT);
|
job.setPowVersion(Options::POW_AUTODETECT);
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
Options::i()->setForcePowVersion(Options::POW_V1);
|
job.setPowVersion(Options::POW_V1);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
Options::i()->setForcePowVersion(Options::POW_V2);
|
job.setPowVersion(Options::POW_V2);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
job.setPowVersion(Options::i()->forcePowVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_job != job) {
|
if (m_job != job) {
|
||||||
|
@ -238,11 +258,29 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code)
|
||||||
LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port());
|
LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port());
|
||||||
}
|
}
|
||||||
|
|
||||||
close();
|
reconnect();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Client::parseExtensions(const rapidjson::Value &value)
|
||||||
|
{
|
||||||
|
if (!value.IsArray()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const rapidjson::Value &ext : value.GetArray()) {
|
||||||
|
if (!ext.IsString()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(ext.GetString(), "nicehash") == 0) {
|
||||||
|
m_nicehash = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Client::parseLogin(const rapidjson::Value &result, int *code)
|
bool Client::parseLogin(const rapidjson::Value &result, int *code)
|
||||||
{
|
{
|
||||||
const char *id = result["id"].GetString();
|
const char *id = result["id"].GetString();
|
||||||
|
@ -251,9 +289,7 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifndef XMRIG_PROXY_PROJECT
|
|
||||||
m_nicehash = m_url.isNicehash();
|
m_nicehash = m_url.isNicehash();
|
||||||
# endif
|
|
||||||
|
|
||||||
if (result.HasMember("extensions")) {
|
if (result.HasMember("extensions")) {
|
||||||
parseExtensions(result["extensions"]);
|
parseExtensions(result["extensions"]);
|
||||||
|
@ -268,139 +304,31 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t Client::send(size_t size)
|
|
||||||
|
int64_t Client::send(char* buf, size_t size)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Client::send");
|
if (m_connection)
|
||||||
|
{
|
||||||
LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_url.host(), m_url.port(), size, m_sendBuf);
|
m_connection->send(buf, size);
|
||||||
if (!m_net) {
|
|
||||||
LOG_DEBUG_ERR("[%s:%u] send failed", m_url.host(), m_url.port());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (net_write2(m_net, m_sendBuf, static_cast<unsigned int>(size)) < 0) {
|
|
||||||
close();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_expire = uv_now(uv_default_loop()) + kResponseTimeout;
|
m_expire = uv_now(uv_default_loop()) + kResponseTimeout;
|
||||||
return m_sequence++;
|
m_sequence++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_sequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Client::close()
|
void Client::close()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Client::close");
|
LOG_DEBUG("close");
|
||||||
|
|
||||||
if (m_net) {
|
m_connection.reset();
|
||||||
net_close(m_net, nullptr);
|
|
||||||
} else {
|
|
||||||
reconnect();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Client::connect()
|
|
||||||
{
|
|
||||||
LOG_DEBUG("Client::connect");
|
|
||||||
|
|
||||||
m_net = net_new(const_cast<char *>(m_url.host()), m_url.port());
|
|
||||||
m_net->data = this;
|
|
||||||
m_net->conn_cb = Client::onConnect;
|
|
||||||
m_net->read_cb = Client::onRead;
|
|
||||||
m_net->close_cb = Client::onClose;
|
|
||||||
m_net->error_cb = Client::onError;
|
|
||||||
|
|
||||||
#ifndef XMRIG_NO_TLS
|
|
||||||
if (m_url.useTls()) {
|
|
||||||
tls_ctx* tls_ctx = tls_ctx_new();
|
|
||||||
net_set_tls(m_net, tls_ctx);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
net_connect(m_net);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::onRead(net_t *net, size_t size, char *buf)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("Client::onRead");
|
|
||||||
|
|
||||||
auto client = getClient(net->data);
|
|
||||||
|
|
||||||
if (size == 0) {
|
|
||||||
if (size != UV_EOF && !client->m_quiet) {
|
|
||||||
LOG_ERR("[%s:%u] read error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror((int) size));
|
|
||||||
}
|
|
||||||
|
|
||||||
return client->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
client->m_recvBufPos += size;
|
|
||||||
|
|
||||||
char* end;
|
|
||||||
char* start = buf;
|
|
||||||
size_t remaining = client->m_recvBufPos;
|
|
||||||
|
|
||||||
while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) {
|
|
||||||
end++;
|
|
||||||
size_t len = end - start;
|
|
||||||
client->parse(start, len);
|
|
||||||
|
|
||||||
remaining -= len;
|
|
||||||
start = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remaining == 0) {
|
|
||||||
client->m_recvBufPos = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start == buf) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(buf, start, remaining);
|
|
||||||
client->m_recvBufPos = remaining;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::onConnect(net_t *net) {
|
|
||||||
LOG_DEBUG("Client::onConnect");
|
|
||||||
auto client = getClient(net->data);
|
|
||||||
client->login();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::onError(net_t *net, int err, char *errStr)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("Client::onError");
|
|
||||||
|
|
||||||
if (net) {
|
|
||||||
auto client = getClient(net->data);
|
|
||||||
if (!client->m_quiet) {
|
|
||||||
LOG_ERR("[%s:%u] error: \"%s\"", client->m_url.host(), client->m_url.port(), errStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
client->close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::onClose(net_t *net)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("Client::onClose");
|
|
||||||
|
|
||||||
if (net) {
|
|
||||||
auto client = getClient(net->data);
|
|
||||||
|
|
||||||
net_free(net);
|
|
||||||
|
|
||||||
client->m_net = nullptr;
|
|
||||||
|
|
||||||
client->reconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::login()
|
void Client::login()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Client::login");
|
LOG_DEBUG("login");
|
||||||
|
|
||||||
m_results.clear();
|
m_results.clear();
|
||||||
|
|
||||||
|
@ -433,20 +361,54 @@ void Client::login()
|
||||||
m_sendBuf[size] = '\n';
|
m_sendBuf[size] = '\n';
|
||||||
m_sendBuf[size + 1] = '\0';
|
m_sendBuf[size + 1] = '\0';
|
||||||
|
|
||||||
send(size + 1);
|
send(m_sendBuf, size + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::processReceivedData(char* data, size_t size)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("processReceivedData");
|
||||||
|
|
||||||
|
if ((size_t) size > (sizeof(m_buf) - 8 - m_recvBufPos)) {
|
||||||
|
reconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_recvBufPos += size;
|
||||||
|
|
||||||
|
char* end;
|
||||||
|
char* start = data;
|
||||||
|
size_t remaining = m_recvBufPos;
|
||||||
|
|
||||||
|
while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) {
|
||||||
|
end++;
|
||||||
|
size_t len = end - start;
|
||||||
|
parse(start, len);
|
||||||
|
|
||||||
|
remaining -= len;
|
||||||
|
start = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remaining == 0) {
|
||||||
|
m_recvBufPos = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start == data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(data, start, remaining);
|
||||||
|
m_recvBufPos = remaining;
|
||||||
|
}
|
||||||
|
|
||||||
void Client::parse(char *line, size_t len)
|
void Client::parse(char *line, size_t len)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Client::parse");
|
LOG_DEBUG("parse");
|
||||||
|
|
||||||
startTimeout();
|
startTimeout();
|
||||||
|
|
||||||
line[len - 1] = '\0';
|
line[len - 1] = '\0';
|
||||||
|
|
||||||
LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_url.host(), m_url.port(), len, line);
|
|
||||||
|
|
||||||
rapidjson::Document doc;
|
rapidjson::Document doc;
|
||||||
if (doc.ParseInsitu(line).HasParseError()) {
|
if (doc.ParseInsitu(line).HasParseError()) {
|
||||||
if (!m_quiet) {
|
if (!m_quiet) {
|
||||||
|
@ -470,28 +432,11 @@ void Client::parse(char *line, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Client::parseExtensions(const rapidjson::Value &value)
|
|
||||||
{
|
|
||||||
if (!value.IsArray()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const rapidjson::Value &ext : value.GetArray()) {
|
|
||||||
if (!ext.IsString()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(ext.GetString(), "nicehash") == 0) {
|
|
||||||
m_nicehash = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error)
|
void Client::parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error)
|
||||||
{
|
{
|
||||||
if (error.IsObject()) {
|
if (error.IsObject()) {
|
||||||
if (!m_quiet) {
|
if (!m_quiet) {
|
||||||
LOG_ERR("[%s:%u] error: \"%s\", code: %d", m_url.host(), m_url.port(), error["message"].GetString(), error["code"].GetInt());
|
LOG_ERR("[%s:%u] Parse notification failed: \"%s\", code: %d", m_url.host(), m_url.port(), error["message"].GetString(), error["code"].GetInt());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -509,7 +454,7 @@ void Client::parseNotification(const char *method, const rapidjson::Value ¶m
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_WARN("[%s:%u] unsupported method: \"%s\"", m_url.host(), m_url.port(), method);
|
LOG_WARN("[%s:%u] Unsupported method: \"%s\"", m_url.host(), m_url.port(), method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -525,11 +470,11 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
|
||||||
m_results.erase(it);
|
m_results.erase(it);
|
||||||
}
|
}
|
||||||
else if (!m_quiet) {
|
else if (!m_quiet) {
|
||||||
LOG_ERR("[%s:%u] error: \"%s\", code: %d", m_url.host(), m_url.port(), message, error["code"].GetInt());
|
LOG_ERR("[%s:%u] Parse response failed: \"%s\", code: %d", m_url.host(), m_url.port(), message, error["code"].GetInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == 1 || isCriticalError(message)) {
|
if (id == 1 || isCriticalError(message)) {
|
||||||
close();
|
reconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -543,10 +488,10 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
|
||||||
int code = -1;
|
int code = -1;
|
||||||
if (!parseLogin(result, &code)) {
|
if (!parseLogin(result, &code)) {
|
||||||
if (!m_quiet) {
|
if (!m_quiet) {
|
||||||
LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code);
|
LOG_ERR("[%s:%u] Login error code: %d", m_url.host(), m_url.port(), code);
|
||||||
}
|
}
|
||||||
|
|
||||||
return close();
|
return reconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_failures = 0;
|
m_failures = 0;
|
||||||
|
@ -566,26 +511,35 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
|
||||||
|
|
||||||
void Client::ping()
|
void Client::ping()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Client::ping");
|
LOG_DEBUG("ping");
|
||||||
send(snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence, m_rpcId));
|
|
||||||
|
const int size = snprintf(m_sendBuf, sizeof(m_sendBuf),
|
||||||
|
"{"
|
||||||
|
"\"id\":%" PRId64 ","
|
||||||
|
"\"jsonrpc\":\"2.0\","
|
||||||
|
"\"method\":\"keepalived\","
|
||||||
|
"\"params\":"
|
||||||
|
"{"
|
||||||
|
"\"id\":\"%s\""
|
||||||
|
"}"
|
||||||
|
"}\n",
|
||||||
|
m_sequence, m_rpcId);
|
||||||
|
send(m_sendBuf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Client::reconnect() {
|
void Client::reconnect()
|
||||||
|
{
|
||||||
|
LOG_DEBUG("reconnect");
|
||||||
|
|
||||||
LOG_DEBUG("Client::reconnect");
|
close();
|
||||||
|
|
||||||
# ifndef XMRIG_PROXY_PROJECT
|
|
||||||
if (m_url.isKeepAlive()) {
|
if (m_url.isKeepAlive()) {
|
||||||
uv_timer_stop(&m_keepAliveTimer);
|
uv_timer_stop(&m_keepAliveTimer);
|
||||||
}
|
}
|
||||||
# endif
|
|
||||||
|
|
||||||
if (m_failures == -1) {
|
if (m_failures == -1) {
|
||||||
LOG_DEBUG("Client::reconnect -> m_failures == -1");
|
LOG_DEBUG("reconnect -> m_failures == -1");
|
||||||
m_failures = 0;
|
|
||||||
m_expire = 0;
|
|
||||||
|
|
||||||
return m_listener->onClose(this, -1);
|
return m_listener->onClose(this, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,17 +549,86 @@ void Client::reconnect() {
|
||||||
m_expire = uv_now(uv_default_loop()) + m_retryPause;
|
m_expire = uv_now(uv_default_loop()) + m_retryPause;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Client::startTimeout()
|
void Client::startTimeout()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Client::startTimeout");
|
LOG_DEBUG("startTimeout");
|
||||||
|
|
||||||
m_expire = 0;
|
m_expire = 0;
|
||||||
|
|
||||||
# ifndef XMRIG_PROXY_PROJECT
|
|
||||||
if (!m_url.isKeepAlive()) {
|
if (!m_url.isKeepAlive()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_timer_start(&m_keepAliveTimer, [](uv_timer_t *handle) { getClient(handle->data)->ping(); }, kKeepAliveTimeout, 0);
|
uv_timer_start(&m_keepAliveTimer, [](uv_timer_t *handle) { getClient(handle->data)->ping(); }, kKeepAliveTimeout, 0);
|
||||||
# endif
|
}
|
||||||
|
|
||||||
|
void Client::onConnected(uv_async_t *handle)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("onConnected");
|
||||||
|
|
||||||
|
auto client = getClient(handle->data);
|
||||||
|
if (client) {
|
||||||
|
client->login();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::scheduleOnConnected()
|
||||||
|
{
|
||||||
|
LOG_DEBUG("scheduleOnConnected");
|
||||||
|
onConnectedAsync.data = this;
|
||||||
|
|
||||||
|
uv_async_send(&onConnectedAsync);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::onReceived(uv_async_t *handle)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("onReceived");
|
||||||
|
|
||||||
|
auto client = getClient(handle->data);
|
||||||
|
if (client) {
|
||||||
|
uv_mutex_lock(&client->m_mutex);
|
||||||
|
|
||||||
|
while (!client->m_readQueue.empty()) {
|
||||||
|
std::string data = client->m_readQueue.front();
|
||||||
|
client->processReceivedData(const_cast<char *>(data.c_str()), data.size());
|
||||||
|
client->m_readQueue.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_mutex_unlock(&client->m_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::scheduleOnReceived(char* data, std::size_t size)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("scheduleOnReceived");
|
||||||
|
|
||||||
|
uv_mutex_lock(&m_mutex);
|
||||||
|
m_readQueue.emplace_back(data, size);
|
||||||
|
uv_mutex_unlock(&m_mutex);
|
||||||
|
|
||||||
|
onReceivedAsync.data = this;
|
||||||
|
uv_async_send(&onReceivedAsync);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::onError(uv_async_t *handle)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("onError");
|
||||||
|
|
||||||
|
auto client = getClient(handle->data);
|
||||||
|
if (client) {
|
||||||
|
client->reconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::scheduleOnError(const std::string &error)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("scheduleOnError");
|
||||||
|
|
||||||
|
if (!m_quiet) {
|
||||||
|
LOG_ERR("[%s:%u] Error: \"%s\"", m_url.host(), m_url.port(), error.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
onErrorAsync.data = this;
|
||||||
|
uv_async_send(&onErrorAsync);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,34 +29,25 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#include "net/Connection.h"
|
||||||
#include "net/Job.h"
|
#include "net/Job.h"
|
||||||
#include "net/SubmitResult.h"
|
#include "net/SubmitResult.h"
|
||||||
#include "net/Url.h"
|
#include "net/Url.h"
|
||||||
#include "rapidjson/fwd.h"
|
#include "rapidjson/fwd.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "net.h"
|
|
||||||
|
|
||||||
#ifndef XMRIG_NO_TLS
|
|
||||||
#include "tls.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class IClientListener;
|
class IClientListener;
|
||||||
class JobResult;
|
class JobResult;
|
||||||
|
|
||||||
|
|
||||||
class Client
|
class Client : public ConnectionListener,
|
||||||
|
public std::enable_shared_from_this<Client>
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<Client> Ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr static int kResponseTimeout = 20 * 1000;
|
constexpr static int kResponseTimeout = 20 * 1000;
|
||||||
constexpr static int kKeepAliveTimeout = 60 * 1000;
|
constexpr static int kKeepAliveTimeout = 60 * 1000;
|
||||||
|
@ -78,25 +69,29 @@ public:
|
||||||
inline void setQuiet(bool quiet) { m_quiet = quiet; }
|
inline void setQuiet(bool quiet) { m_quiet = quiet; }
|
||||||
inline void setRetryPause(int ms) { m_retryPause = ms; }
|
inline void setRetryPause(int ms) { m_retryPause = ms; }
|
||||||
|
|
||||||
|
static void onConnected(uv_async_t *handle);
|
||||||
|
static void onReceived(uv_async_t *handle);
|
||||||
|
static void onError(uv_async_t *handle);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isCriticalError(const char *message);
|
bool isCriticalError(const char *message);
|
||||||
bool parseJob(const rapidjson::Value ¶ms, int *code);
|
bool parseJob(const rapidjson::Value ¶ms, int *code);
|
||||||
bool parseLogin(const rapidjson::Value &result, int *code);
|
bool parseLogin(const rapidjson::Value &result, int *code);
|
||||||
int64_t send(size_t size);
|
int64_t send(char* buf, size_t size);
|
||||||
void close();
|
void close();
|
||||||
|
void reconnect();
|
||||||
void login();
|
void login();
|
||||||
|
void processReceivedData(char* data, size_t size);
|
||||||
void parse(char *line, size_t len);
|
void parse(char *line, size_t len);
|
||||||
void parseExtensions(const rapidjson::Value &value);
|
|
||||||
void parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error);
|
void parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error);
|
||||||
|
void parseExtensions(const rapidjson::Value &value);
|
||||||
void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
|
void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
|
||||||
void ping();
|
void ping();
|
||||||
void reconnect();
|
|
||||||
void startTimeout();
|
void startTimeout();
|
||||||
|
|
||||||
static void onRead(net_t *net, size_t read, char *buf);
|
virtual void scheduleOnConnected();
|
||||||
static void onConnect(net_t *net);
|
virtual void scheduleOnReceived(char *data, size_t size);
|
||||||
static void onError(net_t *net, int err, char *errStr);
|
virtual void scheduleOnError(const std::string &error);
|
||||||
static void onClose(net_t *net);
|
|
||||||
|
|
||||||
static inline Client *getClient(void *data) { return static_cast<Client*>(data); }
|
static inline Client *getClient(void *data) { return static_cast<Client*>(data); }
|
||||||
|
|
||||||
|
@ -119,11 +114,16 @@ private:
|
||||||
Url m_url;
|
Url m_url;
|
||||||
uv_buf_t m_recvBuf;
|
uv_buf_t m_recvBuf;
|
||||||
|
|
||||||
net_t* m_net;
|
uv_mutex_t m_mutex;
|
||||||
|
std::list<std::string> m_readQueue;
|
||||||
|
|
||||||
|
Connection::Ptr m_connection;
|
||||||
|
|
||||||
|
uv_async_t onConnectedAsync;
|
||||||
|
uv_async_t onReceivedAsync;
|
||||||
|
uv_async_t onErrorAsync;
|
||||||
|
|
||||||
# ifndef XMRIG_PROXY_PROJECT
|
|
||||||
uv_timer_t m_keepAliveTimer;
|
uv_timer_t m_keepAliveTimer;
|
||||||
# endif
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
89
src/net/Connection.cpp
Normal file
89
src/net/Connection.cpp
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/* XMRigCC
|
||||||
|
* Copyright 2018 Sebastian Stolzenberg <https://github.com/sebastianstolzenberg>
|
||||||
|
* Copyright 2018- BenDr0id <ben@graef.in>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <boost/exception/diagnostic_information.hpp>
|
||||||
|
#include <log/Log.h>
|
||||||
|
|
||||||
|
#include "Connection.h"
|
||||||
|
#include "BoostTcpConnection.h"
|
||||||
|
|
||||||
|
#ifndef XMRIG_NO_TLS
|
||||||
|
#include "BoostTlsConnection.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Connection::Connection(const ConnectionListener::Ptr &listener)
|
||||||
|
: listener_(listener)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Connection::notifyConnected()
|
||||||
|
{
|
||||||
|
ConnectionListener::Ptr listener = listener_.lock();
|
||||||
|
if (listener)
|
||||||
|
{
|
||||||
|
listener->scheduleOnConnected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Connection::notifyRead(char* data, size_t size)
|
||||||
|
{
|
||||||
|
ConnectionListener::Ptr listener = listener_.lock();
|
||||||
|
if (listener)
|
||||||
|
{
|
||||||
|
listener->scheduleOnReceived(data, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Connection::notifyError(const std::string& error)
|
||||||
|
{
|
||||||
|
ConnectionListener::Ptr listener = listener_.lock();
|
||||||
|
if (listener)
|
||||||
|
{
|
||||||
|
listener->scheduleOnError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Connection::Ptr establishConnection(const ConnectionListener::Ptr& listener,
|
||||||
|
ConnectionType type, const std::string& host, uint16_t port)
|
||||||
|
{
|
||||||
|
Connection::Ptr connection;
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch (type) {
|
||||||
|
case CONNECTION_TYPE_TLS:
|
||||||
|
#ifndef XMRIG_NO_TLS
|
||||||
|
connection = establishBoostTlsConnection(listener);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case CONNECTION_TYPE_TCP:
|
||||||
|
connection = establishBoostTcpConnection(listener);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
connection->connect(host, port);
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
LOG_ERR("[%s:%d] Failed to establish connection: %s", host.c_str(), port, boost::current_exception_diagnostic_information().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
78
src/net/Connection.h
Normal file
78
src/net/Connection.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/* XMRig
|
||||||
|
* Copyright 2018 Sebastian Stolzenberg <https://github.com/sebastianstolzenberg>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CONNECTION_H__
|
||||||
|
#define __CONNECTION_H__
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
class ConnectionListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<ConnectionListener> Ptr;
|
||||||
|
typedef std::weak_ptr<ConnectionListener> WeakPtr;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ConnectionListener() {};
|
||||||
|
virtual ~ConnectionListener() {};
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void scheduleOnConnected() = 0;
|
||||||
|
virtual void scheduleOnReceived(char *data, std::size_t size) = 0;
|
||||||
|
virtual void scheduleOnError(const std::string &error) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Connection : private boost::noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<Connection> Ptr;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Connection(const ConnectionListener::Ptr& listener);
|
||||||
|
virtual ~Connection() {};
|
||||||
|
void notifyConnected();
|
||||||
|
void notifyRead(char* data, size_t size);
|
||||||
|
void notifyError(const std::string& error);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void connect(const std::string& server, uint16_t port) = 0;
|
||||||
|
virtual void disconnect() = 0;
|
||||||
|
virtual bool isConnected() const = 0;
|
||||||
|
virtual std::string getConnectedIp() const = 0;
|
||||||
|
virtual uint16_t getConnectedPort() const = 0;
|
||||||
|
virtual void send(const char* data, std::size_t size) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConnectionListener::WeakPtr listener_;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ConnectionType
|
||||||
|
{
|
||||||
|
CONNECTION_TYPE_TCP,
|
||||||
|
CONNECTION_TYPE_TLS
|
||||||
|
};
|
||||||
|
|
||||||
|
Connection::Ptr establishConnection(const ConnectionListener::Ptr& listener,
|
||||||
|
ConnectionType type,
|
||||||
|
const std::string& host, uint16_t port);
|
||||||
|
|
||||||
|
#endif /* __CONNECTION_H__ */
|
|
@ -61,7 +61,8 @@ Job::Job(int poolId, bool nicehash) :
|
||||||
m_threadId(-1),
|
m_threadId(-1),
|
||||||
m_size(0),
|
m_size(0),
|
||||||
m_diff(0),
|
m_diff(0),
|
||||||
m_target(0)
|
m_target(0),
|
||||||
|
m_powVersion(Options::POW_AUTODETECT)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <Options.h>
|
||||||
|
|
||||||
|
|
||||||
#include "net/JobId.h"
|
#include "net/JobId.h"
|
||||||
|
@ -49,17 +50,14 @@ public:
|
||||||
inline const uint8_t *blob() const { return m_blob; }
|
inline const uint8_t *blob() const { return m_blob; }
|
||||||
inline int poolId() const { return m_poolId; }
|
inline int poolId() const { return m_poolId; }
|
||||||
inline int threadId() const { return m_threadId; }
|
inline int threadId() const { return m_threadId; }
|
||||||
|
inline Options::PowVersion powVersion() const { return m_powVersion; }
|
||||||
inline size_t size() const { return m_size; }
|
inline size_t size() const { return m_size; }
|
||||||
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
|
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
|
||||||
inline uint32_t diff() const { return (uint32_t) m_diff; }
|
inline uint32_t diff() const { return (uint32_t) m_diff; }
|
||||||
inline uint64_t target() const { return m_target; }
|
inline uint64_t target() const { return m_target; }
|
||||||
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
|
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
|
||||||
inline void setThreadId(int threadId) { m_threadId = threadId; }
|
inline void setThreadId(int threadId) { m_threadId = threadId; }
|
||||||
|
inline void setPowVersion(Options::PowVersion powVersion) { m_powVersion = powVersion; }
|
||||||
# ifdef XMRIG_PROXY_PROJECT
|
|
||||||
inline char *rawBlob() { return m_rawBlob; }
|
|
||||||
inline const char *rawTarget() const { return m_rawTarget; }
|
|
||||||
# endif
|
|
||||||
|
|
||||||
static bool fromHex(const char* in, unsigned int len, unsigned char* out);
|
static bool fromHex(const char* in, unsigned int len, unsigned char* out);
|
||||||
static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast<uint32_t*>(blob + 39); }
|
static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast<uint32_t*>(blob + 39); }
|
||||||
|
@ -79,6 +77,7 @@ private:
|
||||||
size_t m_size;
|
size_t m_size;
|
||||||
uint64_t m_diff;
|
uint64_t m_diff;
|
||||||
uint64_t m_target;
|
uint64_t m_target;
|
||||||
|
Options::PowVersion m_powVersion;
|
||||||
|
|
||||||
# ifdef XMRIG_PROXY_PROJECT
|
# ifdef XMRIG_PROXY_PROJECT
|
||||||
VAR_ALIGN(16, char m_rawBlob[169]);
|
VAR_ALIGN(16, char m_rawBlob[169]);
|
||||||
|
|
|
@ -57,7 +57,7 @@ Network::Network(const Options *options) :
|
||||||
const std::vector<Url*> &pools = options->pools();
|
const std::vector<Url*> &pools = options->pools();
|
||||||
|
|
||||||
#ifndef XMRIG_NO_TLS
|
#ifndef XMRIG_NO_TLS
|
||||||
ssl_init();
|
//ssl_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pools.size() > 1) {
|
if (pools.size() > 1) {
|
||||||
|
@ -81,7 +81,7 @@ Network::Network(const Options *options) :
|
||||||
Network::~Network()
|
Network::~Network()
|
||||||
{
|
{
|
||||||
#ifndef XMRIG_NO_TLS
|
#ifndef XMRIG_NO_TLS
|
||||||
ssl_destroy();
|
//ssl_destroy();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,10 +170,12 @@ void Network::onResultAccepted(Client *client, const SubmitResult &result, const
|
||||||
void Network::setJob(Client *client, const Job &job)
|
void Network::setJob(Client *client, const Job &job)
|
||||||
{
|
{
|
||||||
if (m_options->colors()) {
|
if (m_options->colors()) {
|
||||||
LOG_INFO("\x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d", client->host(), client->port(), job.diff());
|
LOG_INFO("\x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m with diff \x1B[01;37m%d\x1B[0m and PoW \x1B[01;37mv%d",
|
||||||
|
client->host(), client->port(), job.diff(), job.powVersion());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG_INFO("new job from %s:%d diff %d", client->host(), client->port(), job.diff());
|
LOG_INFO("new job from %s:%d with diff %d and PoW v%d",
|
||||||
|
client->host(), client->port(), job.diff(), job.powVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_state.diff = job.diff();
|
m_state.diff = job.diff();
|
||||||
|
|
|
@ -81,7 +81,7 @@ DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) :
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_client = new Client(-1, agent, this);
|
m_client = std::make_shared<Client>(-1, agent, this);
|
||||||
m_client->setUrl(url);
|
m_client->setUrl(url);
|
||||||
m_client->setRetryPause(Options::i()->retryPause() * 1000);
|
m_client->setRetryPause(Options::i()->retryPause() * 1000);
|
||||||
m_client->setQuiet(true);
|
m_client->setQuiet(true);
|
||||||
|
|
|
@ -65,7 +65,7 @@ private:
|
||||||
static void onSuspendTimer(uv_timer_t *handle);
|
static void onSuspendTimer(uv_timer_t *handle);
|
||||||
|
|
||||||
bool m_active;
|
bool m_active;
|
||||||
Client *m_client;
|
Client::Ptr m_client;
|
||||||
const int m_donateTime;
|
const int m_donateTime;
|
||||||
const int m_idleTime;
|
const int m_idleTime;
|
||||||
IStrategyListener *m_listener;
|
IStrategyListener *m_listener;
|
||||||
|
|
|
@ -57,7 +57,7 @@ void FailoverStrategy::resume()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_listener->onJob( m_pools[m_active], m_pools[m_active]->job());
|
m_listener->onJob(m_pools[m_active].get(), m_pools[m_active]->job());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ void FailoverStrategy::stop()
|
||||||
|
|
||||||
void FailoverStrategy::tick(uint64_t now)
|
void FailoverStrategy::tick(uint64_t now)
|
||||||
{
|
{
|
||||||
for (Client *client : m_pools) {
|
for (auto client : m_pools) {
|
||||||
client->tick(now);
|
client->tick(now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ void FailoverStrategy::onResultAccepted(Client *client, const SubmitResult &resu
|
||||||
|
|
||||||
void FailoverStrategy::add(const Url *url, const char *agent)
|
void FailoverStrategy::add(const Url *url, const char *agent)
|
||||||
{
|
{
|
||||||
Client *client = new Client((int) m_pools.size(), agent, this);
|
Client::Ptr client = std::make_shared<Client>((int) m_pools.size(), agent, this);
|
||||||
client->setUrl(url);
|
client->setUrl(url);
|
||||||
client->setRetryPause(Options::i()->retryPause() * 1000);
|
client->setRetryPause(Options::i()->retryPause() * 1000);
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ private:
|
||||||
int m_active;
|
int m_active;
|
||||||
int m_index;
|
int m_index;
|
||||||
IStrategyListener *m_listener;
|
IStrategyListener *m_listener;
|
||||||
std::vector<Client*> m_pools;
|
std::vector<Client::Ptr> m_pools;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __FAILOVERSTRATEGY_H__ */
|
#endif /* __FAILOVERSTRATEGY_H__ */
|
||||||
|
|
|
@ -32,7 +32,7 @@ SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrat
|
||||||
m_active(false),
|
m_active(false),
|
||||||
m_listener(listener)
|
m_listener(listener)
|
||||||
{
|
{
|
||||||
m_client = new Client(0, agent, this);
|
m_client = std::make_shared<Client>(0, agent, this);
|
||||||
m_client->setUrl(url);
|
m_client->setUrl(url);
|
||||||
m_client->setRetryPause(Options::i()->retryPause() * 1000);
|
m_client->setRetryPause(Options::i()->retryPause() * 1000);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ void SinglePoolStrategy::resume()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_listener->onJob(m_client, m_client->job());
|
m_listener->onJob(m_client.get(), m_client->job());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_active;
|
bool m_active;
|
||||||
Client *m_client;
|
Client::Ptr m_client;
|
||||||
IStrategyListener *m_listener;
|
IStrategyListener *m_listener;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#define APP_DESC "XMRigCC CPU miner"
|
#define APP_DESC "XMRigCC CPU miner"
|
||||||
#define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id"
|
#define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id"
|
||||||
#endif
|
#endif
|
||||||
#define APP_VERSION "1.6.0_cn_heavy_support_v1 (based on XMRig 2.5.2)"
|
#define APP_VERSION "1.6.0_reimplement_tls_v2 (based on XMRig 2.5.2)"
|
||||||
#define APP_DOMAIN ""
|
#define APP_DOMAIN ""
|
||||||
#define APP_SITE "https://github.com/Bendr0id/xmrigCC"
|
#define APP_SITE "https://github.com/Bendr0id/xmrigCC"
|
||||||
#define APP_KIND "cpu"
|
#define APP_KIND "cpu"
|
||||||
|
|
|
@ -120,7 +120,7 @@ void MultiWorker::start()
|
||||||
*Job::nonce(m_state->blob + i * m_state->job.size()) = ++m_state->nonces[i];
|
*Job::nonce(m_state->blob + i * m_state->job.size()) = ++m_state->nonces[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
CryptoNight::hash(m_hashMultiplier, m_state->blob, m_state->job.size(), m_hash, m_ctx);
|
CryptoNight::hash(m_hashMultiplier, m_state->job.powVersion(), m_state->blob, m_state->job.size(), m_hash, m_ctx);
|
||||||
|
|
||||||
for (size_t i=0; i < m_hashMultiplier; ++i) {
|
for (size_t i=0; i < m_hashMultiplier; ++i) {
|
||||||
if (*reinterpret_cast<uint64_t *>(m_hash + 24 + i * 32) < m_state->job.target()) {
|
if (*reinterpret_cast<uint64_t *>(m_hash + 24 + i * 32) < m_state->job.target()) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue