diff --git a/README.md b/README.md
index 6ab4b6a2..bea99be5 100644
--- a/README.md
+++ b/README.md
@@ -1,122 +1,22 @@
-# XMRig
-XMRig is a high performance Monero (XMR) CPU miner, with official support for Windows.
-Originally based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of legacy code, since version 1.0.0 completely rewritten from scratch on C++.
+# XMRig (enWILLYado version)
+[XMRig](https://github.com/xmrig) is a team that has some high performance Monero (XMR) miners, with official support for Windows.
+This fork is originally based on the [CPU-mining](https://github.com/xmrig/xmrig) version with some optimizations/rewrites, interesting features for final users and a little code refactors.
-* This is the **CPU-mining** version, there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia) and [AMD GPU version]( https://github.com/xmrig/xmrig-amd).
+* This software is like the [CPU-mining](https://github.com/xmrig/xmrig) version; but there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia) and [AMD GPU version]( https://github.com/xmrig/xmrig-amd).
* [Roadmap](https://github.com/xmrig/xmrig/issues/106) for next releases.
-
+## Own features
-#### Table of contents
-* [Features](#features)
-* [Download](#download)
-* [Usage](#usage)
-* [Algorithm variations](#algorithm-variations)
-* [Build](https://github.com/xmrig/xmrig/wiki/Build)
-* [Common Issues](#common-issues)
-* [Other information](#other-information)
-* [Donations](#donations)
-* [Contacts](#contacts)
-
-## Features
-* High performance.
-* Official Windows support.
-* Small Windows executable, without dependencies.
-* x86/x64 support.
-* Support for backup (failover) mining server.
-* keepalived support.
-* Command line options compatible with cpuminer.
-* CryptoNight-Lite support for AEON.
-* Smart automatic [CPU configuration](https://github.com/xmrig/xmrig/wiki/Threads).
-* Nicehash support
-* It's open source software.
-
-## Download
-* Binary releases: https://github.com/xmrig/xmrig/releases
-* Git tree: https://github.com/xmrig/xmrig.git
- * Clone with `git clone https://github.com/xmrig/xmrig.git` :hammer: [Build instructions](https://github.com/xmrig/xmrig/wiki/Build).
-
-## Usage
-### Basic example
-```
-xmrig.exe -o pool.monero.hashvault.pro:5555 -u YOUR_WALLET -p x -k
-```
-
-### Failover
-```
-xmrig.exe -o pool.monero.hashvault.pro:5555 -u YOUR_WALLET1 -p x -k -o pool.supportxmr.com:5555 -u YOUR_WALLET2 -p x -k
-```
-For failover you can add multiple pools, maximum count not limited.
-
-### Options
-```
- -a, --algo=ALGO cryptonight (default) or cryptonight-lite
- -o, --url=URL URL of mining server
- -O, --userpass=U:P username:password pair for mining server
- -u, --user=USERNAME username for mining server
- -p, --pass=PASSWORD password for mining server
- -t, --threads=N number of miner threads
- -v, --av=N algorithm variation, 0 auto select
- -k, --keepalive send keepalived for prevent timeout (need pool support)
- -r, --retries=N number of times to retry before switch to backup server (default: 5)
- -R, --retry-pause=N time to pause between retries (default: 5)
- --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1
- --cpu-priority set process priority (0 idle, 2 normal to 5 highest)
- --no-huge-pages disable huge pages support
- --no-color disable colored output
- --donate-level=N donate level, default 5% (5 minutes in 100 minutes)
- --user-agent set custom user-agent string for pool
- -B, --background run the miner in the background
- -c, --config=FILE load a JSON-format configuration file
- -l, --log-file=FILE log all output to a file
- --max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)
- --safe safe adjust threads and av settings for current CPU
- --nicehash enable nicehash/xmrig-proxy support
- --print-time=N print hashrate report every N seconds
- --api-port=N port for the miner API
- --api-access-token=T access token for API
- --api-worker-id=ID custom worker-id for API
- -h, --help display this help and exit
- -V, --version output version information and exit
-```
-
-Also you can use configuration via config file, default **config.json**. You can load multiple config files and combine it with command line options.
-
-## Algorithm variations
-Since version 0.8.0.
-* `--av=1` For CPUs with hardware AES.
-* `--av=2` Lower power mode (double hash) of `1`.
-* `--av=3` Software AES implementation.
-* `--av=4` Lower power mode (double hash) of `3`.
-
-## Common Issues
-### HUGE PAGES unavailable
-* Run XMRig as Administrator.
-* Since version 0.8.0 XMRig automatically enables SeLockMemoryPrivilege for current user, but reboot or sign out still required. [Manual instruction](https://msdn.microsoft.com/en-gb/library/ms190730.aspx).
-
-## Other information
-* No HTTP support, only stratum protocol support.
-* No TLS support.
-* Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via command line option `--donate-level`.
-
-
-### CPU mining performance
-* **Intel i7-7700** - 307 H/s (4 threads)
-* **AMD Ryzen 7 1700X** - 560 H/s (8 threads)
-
-Please note performance is highly dependent on system load. The numbers above are obtained on an idle system. Tasks heavily using a processor cache, such as video playback, can greatly degrade hashrate. Optimal number of threads depends on the size of the L3 cache of a processor, 1 thread requires 2 MB of cache.
-
-### Maximum performance checklist
-* Idle operating system.
-* Do not exceed optimal thread count.
-* Use modern CPUs with AES-NI instruction set.
-* Try setup optimal cpu affinity.
-* Enable fast memory (Large/Huge pages).
+* Connect to pool or proxies over HTTP PROXY.
+* Include basic encrypted communications.
## Donations
-* XMR: `48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD`
-* BTC: `1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT`
+* XMR: `433hhduFBtwVXtQiTTTeqyZsB36XaBLJB6bcQfnqqMs5RJitdpi8xBN21hWiEfuPp2hytmf1cshgK5Grgo6QUvLZCP2QSMi`
+* BTC: `13MTEjDv8JmS4suaRx6CcWNthR1vwPr7Ce`
+* DOGE: `DHif8RTy8E6K4b71u3fXXSk7AEyiuN2sUi`
## Contacts
-* support@xmrig.com
-* [reddit](https://www.reddit.com/user/XMRig/)
+* xmrig@enwillyado.com
+* [telegram](https://telegram.me/enWILLYado)
+
+¡Se habla español!
diff --git a/src/config.json b/src/config.json
index 7813d4b9..49ffb890 100644
--- a/src/config.json
+++ b/src/config.json
@@ -1,11 +1,13 @@
{
"algo": "cryptonight", // cryptonight (default) or cryptonight-lite
+ "user-agent": "", // custom user-agent
"av": 0, // algorithm variation, 0 auto select
"background": false, // true to run the miner in the background
"colors": true, // false to disable colored output
"cpu-affinity": null, // set process affinity to CPU core(s), mask "0x3" for cores 0 and 1
"cpu-priority": null, // set process priority (0 idle, 2 normal to 5 highest)
"donate-level": 5, // donate level, mininum 1%
+ "debug": false,
"log-file": null, // log all output to a file, example: "c:/some/path/xmrig.log"
"max-cpu-usage": 75, // maximum CPU usage for automatic mode, usually limiting factor is CPU cache not this option.
"print-time": 60, // print hashrate report every N seconds
@@ -16,12 +18,22 @@
"threads": null, // number of miner threads
"pools": [
{
- "url": "pool.minemonero.pro:5555", // URL of mining server
+ "url": "pool.minemonero.pro:3333", // --------------- URL of mining server
+ /* "url": "pool.minemonero.pro:443@localhost:8080",*/ // --------------- URL of mining server over HTTP (CONNECT) proxy
+ /* "url": "pool.minemonero.pro:7777#secret_keystream",*/ // URL of mining xmrig-proxy with encrypted support
+ /* "url": "pool.minemonero.pro:8080#secret_keystream@localhost:8080",*/ // URL of mining xmrig-proxy with encrypted support over HTTP (CONNECT) proxy
"user": "", // username for mining server
"pass": "x", // password for mining server
"keepalive": true, // send keepalived for prevent timeout (need pool support)
"nicehash": false // enable nicehash/xmrig-proxy support
- }
+ },
+ {
+ "url": "pool.minemonero.pro:5555@localhost:8080",// URL of mining server with localhost proxy (example)
+ "user": "", // username for mining server
+ "pass": "x", // password for mining server
+ "keepalive": true, // send keepalived for prevent timeout (need pool support)
+ "nicehash": false // enable nicehash/xmrig-proxy support
+ }
],
"api": {
"port": 0, // port for the miner API https://github.com/xmrig/xmrig/wiki/API
diff --git a/src/net/Client.cpp b/src/net/Client.cpp
index 8e8ebcfd..d8658e7a 100644
--- a/src/net/Client.cpp
+++ b/src/net/Client.cpp
@@ -55,6 +55,8 @@ int64_t Client::m_sequence = 1;
Client::Client(int id, const char *agent, IClientListener *listener) :
m_quiet(false),
+ m_keystream(),
+ m_encrypted(false),
m_agent(agent),
m_listener(listener),
m_id(id),
@@ -68,6 +70,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
{
memset(m_ip, 0, sizeof(m_ip));
memset(&m_hints, 0, sizeof(m_hints));
+ memset(m_keystream, 0, sizeof(m_keystream));
m_resolver.data = this;
@@ -128,6 +131,16 @@ void Client::setUrl(const Url *url)
return;
}
+ if (url->hasKeystream())
+ {
+ url->copyKeystream(m_keystream, sizeof(m_keystream));
+ m_encrypted = true;
+ }
+ else
+ {
+ m_encrypted = false;
+ }
+
m_url = url;
}
@@ -271,14 +284,30 @@ int Client::resolve(const char *host)
}
-int64_t Client::send(size_t size)
+int64_t Client::send(size_t size, const bool encrypted)
{
LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_url.host(), m_url.port(), size, m_sendBuf);
- if (state() != ConnectedState || !uv_is_writable(m_stream)) {
+ if ((state() != ConnectedState && state() != ProxingState) || !uv_is_writable(m_stream)) {
LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_url.host(), m_url.port(), m_state);
return -1;
}
+ if(encrypted && m_encrypted)
+ {
+ // Encrypt
+ for(size_t i = 0; i < std::min(size, sizeof(m_keystream)); ++i)
+ {
+ m_sendBuf[i] ^= m_keystream[i];
+ }
+
+ char * send_encr_hex = static_cast(malloc(size * 2 + 1));
+ memset(send_encr_hex, 0, size * 2 + 1);
+ Job::toHex((const unsigned char*)m_sendBuf, size, send_encr_hex);
+ send_encr_hex[size * 2] = '\0';
+ LOG_DEBUG("[%s:%u] send encr. (%d bytes): \"0x%s\"", m_url.host(), m_url.port(), size, send_encr_hex);
+ free(send_encr_hex);
+ }
+
uv_buf_t buf = uv_buf_init(m_sendBuf, (unsigned int) size);
if (uv_try_write(m_stream, &buf, 1) < 0) {
@@ -328,6 +357,27 @@ void Client::connect(struct sockaddr *addr)
uv_tcp_connect(req, m_socket, reinterpret_cast(addr), Client::onConnect);
}
+void Client::prelogin()
+{
+ if (m_url.proxyHost())
+ {
+ setState (ProxingState);
+ const std::string buffer = std::string ("CONNECT ") + m_url.finalHost() + ":" + std::to_string(m_url.finalPort()) + " HTTP/1.1\n";
+
+ const size_t size = buffer.size();
+ memcpy (m_sendBuf, buffer.c_str(), size);
+ m_sendBuf[size] = '\n';
+ m_sendBuf[size + 1] = '\0';
+
+ LOG_DEBUG("Prelogin send (%d bytes): \"%s\"", size, m_sendBuf);
+ send (size + 1, false);
+ }
+ else
+ {
+ setState (ConnectedState);
+ login();
+ }
+}
void Client::login()
{
@@ -565,12 +615,11 @@ void Client::onConnect(uv_connect_t *req, int status)
client->m_stream = static_cast(req->handle);
client->m_stream->data = req->data;
- client->setState(ConnectedState);
uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead);
delete req;
- client->login();
+ client->prelogin();
}
@@ -589,12 +638,43 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
return client->close();
}
+ if (client->state() == ProxingState)
+ {
+ const char* const content = buf->base;
+ LOG_DEBUG("[%s:%u] received from proxy (%d bytes): \"%s\"",
+ client->m_url.host(), client->m_url.port(),
+ nread, content);
+
+ if(content == strstr(content, "HTTP/1.1 200"))
+ {
+ LOG_INFO("[%s:%u] Proxy connected to %s:%u!", client->m_url.host(), client->m_url.port(), client->m_url.finalHost(), client->m_url.finalPort());
+ client->setState(ConnectedState);
+ client->login();
+ }
+ return;
+ }
+
client->m_recvBufPos += nread;
char* end;
char* start = buf->base;
size_t remaining = client->m_recvBufPos;
+ if(client->m_encrypted)
+ {
+ char * read_encr_hex = static_cast(malloc(nread * 2 + 1));
+ memset(read_encr_hex, 0, nread * 2 + 1);
+ Job::toHex((const unsigned char*)start, nread, read_encr_hex);
+ LOG_DEBUG("[%s] read encr. (%d bytes): \"0x%s\"", client->m_ip, nread, read_encr_hex);
+ free(read_encr_hex);
+
+ // DeEncrypt
+ for(int i = 0; i < (int)nread; ++i)
+ {
+ start[i] ^= client->m_keystream[i];
+ }
+ }
+
while ((end = static_cast(memchr(start, '\n', remaining))) != nullptr) {
end++;
size_t len = end - start;
diff --git a/src/net/Client.h b/src/net/Client.h
index 699f4903..9436dc48 100644
--- a/src/net/Client.h
+++ b/src/net/Client.h
@@ -46,6 +46,7 @@ public:
UnconnectedState,
HostLookupState,
ConnectingState,
+ ProxingState,
ConnectedState,
ClosingState
};
@@ -78,9 +79,10 @@ private:
bool parseJob(const rapidjson::Value ¶ms, int *code);
bool parseLogin(const rapidjson::Value &result, int *code);
int resolve(const char *host);
- int64_t send(size_t size);
+ int64_t send(size_t size, const bool encrypted = true);
void close();
void connect(struct sockaddr *addr);
+ void prelogin();
void login();
void parse(char *line, size_t len);
void parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error);
@@ -104,6 +106,8 @@ private:
char m_ip[17];
char m_rpcId[64];
char m_sendBuf[768];
+ char m_keystream[sizeof(m_sendBuf)];
+ bool m_encrypted;
const char *m_agent;
IClientListener *m_listener;
int m_id;
diff --git a/src/net/Url.cpp b/src/net/Url.cpp
index dcbe82af..edc9ab5e 100644
--- a/src/net/Url.cpp
+++ b/src/net/Url.cpp
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include "net/Url.h"
@@ -41,7 +42,10 @@ Url::Url() :
m_host(nullptr),
m_password(nullptr),
m_user(nullptr),
- m_port(kDefaultPort)
+ m_port(kDefaultPort),
+ m_proxy_host(nullptr),
+ m_proxy_port(kDefaultProxyPort),
+ m_keystream(nullptr)
{
}
@@ -63,7 +67,10 @@ Url::Url(const char *url) :
m_host(nullptr),
m_password(nullptr),
m_user(nullptr),
- m_port(kDefaultPort)
+ m_port(kDefaultPort),
+ m_proxy_host(nullptr),
+ m_proxy_port(kDefaultProxyPort),
+ m_keystream(nullptr)
{
parse(url);
}
@@ -74,7 +81,10 @@ Url::Url(const char *host, uint16_t port, const char *user, const char *password
m_nicehash(nicehash),
m_password(password ? strdup(password) : nullptr),
m_user(user ? strdup(user) : nullptr),
- m_port(port)
+ m_port(port),
+ m_proxy_host(nullptr),
+ m_proxy_port(kDefaultProxyPort),
+ m_keystream(nullptr)
{
m_host = strdup(host);
}
@@ -85,9 +95,10 @@ Url::~Url()
free(m_host);
free(m_password);
free(m_user);
+ free(m_proxy_host);
+ free(m_keystream);
}
-
bool Url::parse(const char *url)
{
const char *p = strstr(url, "://");
@@ -116,7 +127,44 @@ bool Url::parse(const char *url)
memcpy(m_host, base, size - 1);
m_host[size - 1] = '\0';
+ const char* proxy = strchr(port, '@');
+ const char* keystream = strchr(port, '#');
+ if(keystream)
+ {
+ ++keystream;
+ if(!proxy)
+ {
+ m_keystream = strdup(keystream);
+ }
+ else
+ {
+ const size_t keystreamsize = proxy - keystream;
+ m_keystream = static_cast(malloc (keystreamsize + 1));
+ m_keystream[keystreamsize] = '\0';
+ memcpy(m_keystream, keystream, keystreamsize);
+ }
+ }
+
m_port = (uint16_t) strtol(port, nullptr, 10);
+ if (!proxy) {
+ m_port = (uint16_t) strtol(port, nullptr, 10);
+ return true;
+ }
+
+ ++proxy;
+
+ const char* proxyport = strchr(proxy, ':');
+ if (!port) {
+ m_proxy_host = strdup(proxy);
+ return false;
+ }
+
+ const size_t proxysize = proxyport++ - proxy + 1;
+ m_proxy_host = static_cast(malloc (proxysize));
+ memcpy(m_proxy_host, proxy, proxysize - 1);
+ m_proxy_host[proxysize - 1] = '\0';
+ m_proxy_port = (uint16_t) strtol(proxyport, nullptr, 10);
+
return true;
}
@@ -177,18 +225,46 @@ void Url::setUser(const char *user)
m_user = strdup(user);
}
+void Url::copyKeystream(char *keystreamDest, const size_t keystreamLen) const
+{
+ if(hasKeystream())
+ {
+ memset(keystreamDest, 1, keystreamLen);
+ memcpy(keystreamDest, m_keystream, std::min(keystreamLen, strlen(m_keystream)));
+ }
+}
Url &Url::operator=(const Url *other)
{
m_keepAlive = other->m_keepAlive;
m_nicehash = other->m_nicehash;
m_port = other->m_port;
+ m_proxy_port = other->m_proxy_port;
free(m_host);
m_host = strdup(other->m_host);
+ free (m_proxy_host);
+ if(other->m_proxy_host)
+ {
+ m_proxy_host = strdup (other->m_proxy_host);
+ }
+ else
+ {
+ m_proxy_host = nullptr;
+ }
+
setPassword(other->m_password);
setUser(other->m_user);
+ free (m_keystream);
+ if(other->m_keystream)
+ {
+ m_keystream = strdup (other->m_keystream);
+ }
+ else
+ {
+ m_keystream = nullptr;
+ }
return *this;
}
diff --git a/src/net/Url.h b/src/net/Url.h
index a1982300..83f63b56 100644
--- a/src/net/Url.h
+++ b/src/net/Url.h
@@ -34,6 +34,7 @@ public:
constexpr static const char *kDefaultPassword = "x";
constexpr static const char *kDefaultUser = "x";
constexpr static uint16_t kDefaultPort = 3333;
+ constexpr static uint16_t kDefaultProxyPort = 8080;
Url();
Url(const char *url);
@@ -43,10 +44,16 @@ public:
inline bool isKeepAlive() const { return m_keepAlive; }
inline bool isNicehash() const { return m_nicehash; }
inline bool isValid() const { return m_host && m_port > 0; }
- inline const char *host() const { return m_host; }
+ inline bool hasKeystream() const { return m_keystream; }
+ inline const char *host() const { return isProxyed() ? proxyHost() : finalHost(); }
inline const char *password() const { return m_password ? m_password : kDefaultPassword; }
inline const char *user() const { return m_user ? m_user : kDefaultUser; }
- inline uint16_t port() const { return m_port; }
+ inline uint16_t port() const { return isProxyed() ? proxyPort() : finalPort(); }
+ inline bool isProxyed() const { return proxyHost(); }
+ inline const char* finalHost() const { return m_host; }
+ inline uint16_t finalPort() const { return m_port; }
+ inline const char* proxyHost() const { return m_proxy_host; }
+ inline uint16_t proxyPort() const { return m_proxy_port; }
inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; }
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
@@ -55,6 +62,7 @@ public:
void applyExceptions();
void setPassword(const char *password);
void setUser(const char *user);
+ void copyKeystream(char *keystreamDest, const size_t keystreamLen) const;
Url &operator=(const Url *other);
@@ -65,6 +73,9 @@ private:
char *m_password;
char *m_user;
uint16_t m_port;
+ char* m_proxy_host;
+ uint16_t m_proxy_port;
+ char* m_keystream;
};
#endif /* __URL_H__ */