Added full IPv6 support.
This commit is contained in:
parent
79779b51da
commit
8a6988d381
10 changed files with 200 additions and 77 deletions
|
@ -29,8 +29,8 @@ set(HEADERS
|
|||
src/log/Log.h
|
||||
src/Mem.h
|
||||
src/net/Client.h
|
||||
src/net/Id.h
|
||||
src/net/Job.h
|
||||
src/net/JobId.h
|
||||
src/net/JobResult.h
|
||||
src/net/Network.h
|
||||
src/net/strategies/DonateStrategy.h
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -45,7 +45,19 @@ bool Httpd::start()
|
|||
return false;
|
||||
}
|
||||
|
||||
m_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, m_port, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
|
||||
unsigned int flags = 0;
|
||||
if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) {
|
||||
flags = MHD_USE_EPOLL_LINUX_ONLY | MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY;
|
||||
}
|
||||
else {
|
||||
flags = MHD_USE_SELECT_INTERNALLY;
|
||||
}
|
||||
|
||||
if (MHD_is_feature_supported(MHD_FEATURE_IPv6)) {
|
||||
flags |= MHD_USE_DUAL_STACK;
|
||||
}
|
||||
|
||||
m_daemon = MHD_start_daemon(flags, m_port, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
|
||||
if (!m_daemon) {
|
||||
LOG_ERR("HTTP Daemon failed to start.");
|
||||
return false;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
|
|
@ -54,6 +54,7 @@ int64_t Client::m_sequence = 1;
|
|||
|
||||
|
||||
Client::Client(int id, const char *agent, IClientListener *listener) :
|
||||
m_ipv6(false),
|
||||
m_quiet(false),
|
||||
m_agent(agent),
|
||||
m_listener(listener),
|
||||
|
@ -71,7 +72,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
|
|||
|
||||
m_resolver.data = this;
|
||||
|
||||
m_hints.ai_family = PF_INET;
|
||||
m_hints.ai_family = AF_UNSPEC;
|
||||
m_hints.ai_socktype = SOCK_STREAM;
|
||||
m_hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
|
@ -109,19 +110,6 @@ void Client::connect(const Url *url)
|
|||
}
|
||||
|
||||
|
||||
void Client::disconnect()
|
||||
{
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
uv_timer_stop(&m_keepAliveTimer);
|
||||
# endif
|
||||
|
||||
m_expire = 0;
|
||||
m_failures = -1;
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void Client::setUrl(const Url *url)
|
||||
{
|
||||
if (!url || !url->isValid()) {
|
||||
|
@ -150,6 +138,19 @@ void Client::tick(uint64_t now)
|
|||
}
|
||||
|
||||
|
||||
bool Client::disconnect()
|
||||
{
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
uv_timer_stop(&m_keepAliveTimer);
|
||||
# endif
|
||||
|
||||
m_expire = 0;
|
||||
m_failures = -1;
|
||||
|
||||
return close();
|
||||
}
|
||||
|
||||
|
||||
int64_t Client::submit(const JobResult &result)
|
||||
{
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
|
@ -167,13 +168,29 @@ int64_t Client::submit(const JobResult &result)
|
|||
# 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",
|
||||
m_sequence, m_rpcId, result.jobId.data(), nonce, data);
|
||||
m_sequence, m_rpcId.data(), result.jobId.data(), nonce, data);
|
||||
|
||||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
|
||||
return send(size);
|
||||
}
|
||||
|
||||
|
||||
bool Client::close()
|
||||
{
|
||||
if (m_state == UnconnectedState || m_state == ClosingState || !m_socket) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setState(ClosingState);
|
||||
|
||||
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(m_socket)) == 0) {
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(m_socket), Client::onClose);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Client::isCriticalError(const char *message)
|
||||
{
|
||||
if (!message) {
|
||||
|
@ -235,15 +252,11 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code)
|
|||
|
||||
bool Client::parseLogin(const rapidjson::Value &result, int *code)
|
||||
{
|
||||
const char *id = result["id"].GetString();
|
||||
if (!id || strlen(id) >= sizeof(m_rpcId)) {
|
||||
if (!m_rpcId.setId(result["id"].GetString())) {
|
||||
*code = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(m_rpcId, 0, sizeof(m_rpcId));
|
||||
memcpy(m_rpcId, id, strlen(id));
|
||||
|
||||
return parseJob(result["job"], code);
|
||||
}
|
||||
|
||||
|
@ -291,21 +304,25 @@ int64_t Client::send(size_t size)
|
|||
}
|
||||
|
||||
|
||||
void Client::close()
|
||||
void Client::connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6)
|
||||
{
|
||||
if (m_state == UnconnectedState || m_state == ClosingState || !m_socket) {
|
||||
return;
|
||||
addrinfo *addr = nullptr;
|
||||
m_ipv6 = ipv4.empty() && !ipv6.empty();
|
||||
|
||||
if (m_ipv6) {
|
||||
addr = ipv6[ipv6.size() == 1 ? 0 : rand() % ipv6.size()];
|
||||
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(addr->ai_addr), m_ip, 45);
|
||||
}
|
||||
else {
|
||||
addr = ipv4[ipv4.size() == 1 ? 0 : rand() % ipv4.size()];
|
||||
uv_ip4_name(reinterpret_cast<sockaddr_in*>(addr->ai_addr), m_ip, 16);
|
||||
}
|
||||
|
||||
setState(ClosingState);
|
||||
|
||||
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(m_socket)) == 0) {
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(m_socket), Client::onClose);
|
||||
}
|
||||
connect(addr->ai_addr);
|
||||
}
|
||||
|
||||
|
||||
void Client::connect(struct sockaddr *addr)
|
||||
void Client::connect(sockaddr *addr)
|
||||
{
|
||||
setState(ConnectingState);
|
||||
|
||||
|
@ -374,6 +391,11 @@ void Client::parse(char *line, size_t len)
|
|||
|
||||
LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_url.host(), m_url.port(), len, line);
|
||||
|
||||
if (len < 32 || line[0] != '{') {
|
||||
LOG_ERR("[%s:%u] JSON decode failed", m_url.host(), m_url.port());
|
||||
return;
|
||||
}
|
||||
|
||||
rapidjson::Document doc;
|
||||
if (doc.ParseInsitu(line).HasParseError()) {
|
||||
if (!m_quiet) {
|
||||
|
@ -456,7 +478,8 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
|
|||
LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code);
|
||||
}
|
||||
|
||||
return close();
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
m_failures = 0;
|
||||
|
@ -476,7 +499,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
|
|||
|
||||
void Client::ping()
|
||||
{
|
||||
send(snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence, m_rpcId));
|
||||
send(snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence, m_rpcId.data()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -532,7 +555,7 @@ void Client::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t
|
|||
auto client = getClient(handle->data);
|
||||
|
||||
buf->base = &client->m_recvBuf.base[client->m_recvBufPos];
|
||||
buf->len = client->m_recvBuf.len - (unsigned long)client->m_recvBufPos;
|
||||
buf->len = client->m_recvBuf.len - client->m_recvBufPos;
|
||||
}
|
||||
|
||||
|
||||
|
@ -582,11 +605,13 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
|
|||
LOG_ERR("[%s:%u] read error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror((int) nread));
|
||||
}
|
||||
|
||||
return client->close();
|
||||
client->close();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((size_t) nread > (sizeof(m_buf) - 8 - client->m_recvBufPos)) {
|
||||
return client->close();
|
||||
client->close();
|
||||
return;
|
||||
}
|
||||
|
||||
client->m_recvBufPos += nread;
|
||||
|
@ -628,24 +653,27 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
|
|||
|
||||
addrinfo *ptr = res;
|
||||
std::vector<addrinfo*> ipv4;
|
||||
std::vector<addrinfo*> ipv6;
|
||||
|
||||
while (ptr != nullptr) {
|
||||
if (ptr->ai_family == AF_INET) {
|
||||
ipv4.push_back(ptr);
|
||||
}
|
||||
|
||||
if (ptr->ai_family == AF_INET6) {
|
||||
ipv6.push_back(ptr);
|
||||
}
|
||||
|
||||
ptr = ptr->ai_next;
|
||||
}
|
||||
|
||||
if (ipv4.empty()) {
|
||||
LOG_ERR("[%s:%u] DNS error: \"No IPv4 records found\"", client->m_url.host(), client->m_url.port());
|
||||
if (ipv4.empty() && ipv6.empty()) {
|
||||
LOG_ERR("[%s:%u] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_url.host(), client->m_url.port());
|
||||
|
||||
uv_freeaddrinfo(res);
|
||||
return client->reconnect();
|
||||
}
|
||||
|
||||
ptr = ipv4[rand() % ipv4.size()];
|
||||
|
||||
uv_ip4_name(reinterpret_cast<sockaddr_in*>(ptr->ai_addr), client->m_ip, 16);
|
||||
|
||||
client->connect(ptr->ai_addr);
|
||||
client->connect(ipv4, ipv6);
|
||||
uv_freeaddrinfo(res);
|
||||
}
|
||||
|
|
|
@ -27,8 +27,10 @@
|
|||
|
||||
#include <map>
|
||||
#include <uv.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "net/Id.h"
|
||||
#include "net/Job.h"
|
||||
#include "net/SubmitResult.h"
|
||||
#include "net/Url.h"
|
||||
|
@ -56,10 +58,10 @@ public:
|
|||
Client(int id, const char *agent, IClientListener *listener);
|
||||
~Client();
|
||||
|
||||
bool disconnect();
|
||||
int64_t submit(const JobResult &result);
|
||||
void connect();
|
||||
void connect(const Url *url);
|
||||
void disconnect();
|
||||
void setUrl(const Url *url);
|
||||
void tick(uint64_t now);
|
||||
|
||||
|
@ -74,13 +76,14 @@ public:
|
|||
inline void setRetryPause(int ms) { m_retryPause = ms; }
|
||||
|
||||
private:
|
||||
bool close();
|
||||
bool isCriticalError(const char *message);
|
||||
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);
|
||||
void close();
|
||||
void connect(struct sockaddr *addr);
|
||||
void connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6);
|
||||
void connect(sockaddr *addr);
|
||||
void login();
|
||||
void parse(char *line, size_t len);
|
||||
void parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error);
|
||||
|
@ -99,10 +102,10 @@ private:
|
|||
static inline Client *getClient(void *data) { return static_cast<Client*>(data); }
|
||||
|
||||
addrinfo m_hints;
|
||||
bool m_ipv6;
|
||||
bool m_quiet;
|
||||
char m_buf[2048];
|
||||
char m_ip[17];
|
||||
char m_rpcId[64];
|
||||
char m_ip[46];
|
||||
char m_sendBuf[768];
|
||||
const char *m_agent;
|
||||
IClientListener *m_listener;
|
||||
|
@ -120,6 +123,7 @@ private:
|
|||
uv_getaddrinfo_t m_resolver;
|
||||
uv_stream_t *m_stream;
|
||||
uv_tcp_t *m_socket;
|
||||
xmrig::Id m_rpcId;
|
||||
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
uv_timer_t m_keepAliveTimer;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -21,40 +21,51 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __JOBID_H__
|
||||
#define __JOBID_H__
|
||||
#ifndef __ID_H__
|
||||
#define __ID_H__
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
class JobId
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Id
|
||||
{
|
||||
public:
|
||||
inline JobId()
|
||||
inline Id()
|
||||
{
|
||||
memset(m_data, 0, sizeof(m_data));
|
||||
}
|
||||
|
||||
|
||||
inline JobId(const char *id, size_t sizeFix = 0)
|
||||
inline Id(const char *id, size_t sizeFix = 0)
|
||||
{
|
||||
setId(id, sizeFix);
|
||||
}
|
||||
|
||||
|
||||
inline bool operator==(const JobId &other) const
|
||||
inline bool operator==(const Id &other) const
|
||||
{
|
||||
return memcmp(m_data, other.m_data, sizeof(m_data)) == 0;
|
||||
}
|
||||
|
||||
|
||||
inline bool operator!=(const JobId &other) const
|
||||
inline bool operator!=(const Id &other) const
|
||||
{
|
||||
return memcmp(m_data, other.m_data, sizeof(m_data)) != 0;
|
||||
}
|
||||
|
||||
|
||||
Id &operator=(const Id &other)
|
||||
{
|
||||
memcpy(m_data, other.m_data, sizeof(m_data));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline bool setId(const char *id, size_t sizeFix = 0)
|
||||
{
|
||||
memset(m_data, 0, sizeof(m_data));
|
||||
|
@ -80,4 +91,8 @@ private:
|
|||
char m_data[64];
|
||||
};
|
||||
|
||||
#endif /* __JOBID_H__ */
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* __ID_H__ */
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
|
||||
#include "align.h"
|
||||
#include "net/JobId.h"
|
||||
#include "net/Id.h"
|
||||
|
||||
|
||||
class Job
|
||||
|
@ -46,9 +46,9 @@ public:
|
|||
inline bool isNicehash() const { return m_nicehash; }
|
||||
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
|
||||
inline bool setId(const char *id) { return m_id.setId(id); }
|
||||
inline const JobId &id() const { return m_id; }
|
||||
inline const uint32_t *nonce() const { return reinterpret_cast<const uint32_t*>(m_blob + 39); }
|
||||
inline const uint8_t *blob() const { return m_blob; }
|
||||
inline const xmrig::Id &id() const { return m_id; }
|
||||
inline int poolId() const { return m_poolId; }
|
||||
inline int threadId() const { return m_threadId; }
|
||||
inline size_t size() const { return m_size; }
|
||||
|
@ -77,10 +77,10 @@ private:
|
|||
bool m_nicehash;
|
||||
int m_poolId;
|
||||
int m_threadId;
|
||||
JobId m_id;
|
||||
size_t m_size;
|
||||
uint64_t m_diff;
|
||||
uint64_t m_target;
|
||||
xmrig::Id m_id;
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
VAR_ALIGN(16, char m_rawBlob[169]);
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -36,11 +36,11 @@ class JobResult
|
|||
{
|
||||
public:
|
||||
inline JobResult() : poolId(0), diff(0), nonce(0) {}
|
||||
inline JobResult(int poolId, const JobId &jobId, uint32_t nonce, const uint8_t *result, uint32_t diff) :
|
||||
inline JobResult(int poolId, const xmrig::Id &jobId, uint32_t nonce, const uint8_t *result, uint32_t diff) :
|
||||
poolId(poolId),
|
||||
jobId(jobId),
|
||||
diff(diff),
|
||||
nonce(nonce)
|
||||
nonce(nonce),
|
||||
jobId(jobId)
|
||||
{
|
||||
memcpy(this->result, result, sizeof(this->result));
|
||||
}
|
||||
|
@ -71,10 +71,10 @@ public:
|
|||
|
||||
|
||||
int poolId;
|
||||
JobId jobId;
|
||||
uint32_t diff;
|
||||
uint32_t nonce;
|
||||
uint8_t result[32];
|
||||
xmrig::Id jobId;
|
||||
};
|
||||
|
||||
#endif /* __JOBRESULT_H__ */
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -41,6 +41,7 @@ Url::Url() :
|
|||
m_host(nullptr),
|
||||
m_password(nullptr),
|
||||
m_user(nullptr),
|
||||
m_url(nullptr),
|
||||
m_port(kDefaultPort)
|
||||
{
|
||||
}
|
||||
|
@ -63,6 +64,7 @@ Url::Url(const char *url) :
|
|||
m_host(nullptr),
|
||||
m_password(nullptr),
|
||||
m_user(nullptr),
|
||||
m_url(nullptr),
|
||||
m_port(kDefaultPort)
|
||||
{
|
||||
parse(url);
|
||||
|
@ -74,6 +76,7 @@ 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_url(nullptr),
|
||||
m_port(port)
|
||||
{
|
||||
m_host = strdup(host);
|
||||
|
@ -85,6 +88,10 @@ Url::~Url()
|
|||
free(m_host);
|
||||
free(m_password);
|
||||
free(m_user);
|
||||
|
||||
if (m_url) {
|
||||
delete [] m_url;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,6 +112,10 @@ bool Url::parse(const char *url)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (base[0] == '[') {
|
||||
return parseIPv6(base);
|
||||
}
|
||||
|
||||
const char *port = strchr(base, ':');
|
||||
if (!port) {
|
||||
m_host = strdup(base);
|
||||
|
@ -112,9 +123,8 @@ bool Url::parse(const char *url)
|
|||
}
|
||||
|
||||
const size_t size = port++ - base + 1;
|
||||
m_host = static_cast<char*>(malloc(size));
|
||||
m_host = new char[size]();
|
||||
memcpy(m_host, base, size - 1);
|
||||
m_host[size - 1] = '\0';
|
||||
|
||||
m_port = (uint16_t) strtol(port, nullptr, 10);
|
||||
return true;
|
||||
|
@ -139,6 +149,19 @@ bool Url::setUserpass(const char *userpass)
|
|||
}
|
||||
|
||||
|
||||
const char *Url::url() const
|
||||
{
|
||||
if (!m_url) {
|
||||
const size_t size = strlen(m_host) + 8;
|
||||
m_url = new char[size];
|
||||
|
||||
snprintf(m_url, size - 1, "%s:%d", m_host, m_port);
|
||||
}
|
||||
|
||||
return m_url;
|
||||
}
|
||||
|
||||
|
||||
void Url::applyExceptions()
|
||||
{
|
||||
if (!isValid()) {
|
||||
|
@ -178,6 +201,20 @@ void Url::setUser(const char *user)
|
|||
}
|
||||
|
||||
|
||||
bool Url::operator==(const Url &other) const
|
||||
{
|
||||
if (m_port != other.m_port || m_keepAlive != other.m_keepAlive || m_nicehash != other.m_nicehash) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strcmp(host(), other.host()) != 0 || strcmp(user(), other.user()) != 0 || strcmp(password(), other.password()) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Url &Url::operator=(const Url *other)
|
||||
{
|
||||
m_keepAlive = other->m_keepAlive;
|
||||
|
@ -192,3 +229,25 @@ Url &Url::operator=(const Url *other)
|
|||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool Url::parseIPv6(const char *addr)
|
||||
{
|
||||
const char *end = strchr(addr, ']');
|
||||
if (!end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *port = strchr(end, ':');
|
||||
if (!port) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t size = end - addr;
|
||||
m_host = new char[size]();
|
||||
memcpy(m_host, addr + 1, size - 1);
|
||||
|
||||
m_port = (uint16_t) strtol(port + 1, nullptr, 10);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -52,18 +52,23 @@ public:
|
|||
|
||||
bool parse(const char *url);
|
||||
bool setUserpass(const char *userpass);
|
||||
const char *url() const;
|
||||
void applyExceptions();
|
||||
void setPassword(const char *password);
|
||||
void setUser(const char *user);
|
||||
|
||||
bool operator==(const Url &other) const;
|
||||
Url &operator=(const Url *other);
|
||||
|
||||
private:
|
||||
bool parseIPv6(const char *addr);
|
||||
|
||||
bool m_keepAlive;
|
||||
bool m_nicehash;
|
||||
char *m_host;
|
||||
char *m_password;
|
||||
char *m_user;
|
||||
mutable char *m_url;
|
||||
uint16_t m_port;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue