aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/CMakeLists.txt2
-rw-r--r--contrib/epee/CMakeLists.txt2
-rw-r--r--contrib/epee/include/hex.h65
-rw-r--r--contrib/epee/include/md5_l.inl13
-rw-r--r--contrib/epee/include/misc_log_ex.h8
-rw-r--r--contrib/epee/include/net/http_auth.h2
-rw-r--r--contrib/epee/include/net/http_base.h12
-rw-r--r--contrib/epee/include/net/http_client.h122
-rw-r--r--contrib/epee/include/net/http_protocol_handler.h1
-rw-r--r--contrib/epee/include/net/http_protocol_handler.inl7
-rw-r--r--contrib/epee/include/net/http_server_impl_base.h6
-rw-r--r--contrib/epee/include/net/levin_protocol_handler_async.h1
-rw-r--r--contrib/epee/include/net/net_utils_base.h11
-rw-r--r--contrib/epee/include/span.h130
-rw-r--r--contrib/epee/include/storages/http_abstract_invoke.h11
-rw-r--r--contrib/epee/include/string_tools.h65
-rw-r--r--contrib/epee/src/CMakeLists.txt14
-rw-r--r--contrib/epee/src/hex.cpp82
-rw-r--r--contrib/epee/src/http_auth.cpp26
-rw-r--r--contrib/epee/src/mlog.cpp13
-rw-r--r--contrib/epee/src/string_tools.cpp61
-rwxr-xr-xcontrib/snap/daemon.bash12
-rwxr-xr-xcontrib/snap/log.bash3
-rwxr-xr-xcontrib/snap/monerod-wrapper8
-rw-r--r--contrib/snap/monerod.conf9
-rw-r--r--contrib/snap/setup/gui/icon.pngbin0 -> 19132 bytes
-rw-r--r--contrib/snap/snapcraft.yaml75
-rwxr-xr-xcontrib/snap/wallet.bash7
28 files changed, 593 insertions, 175 deletions
diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt
index 6c2ee73ca..7bd411aed 100644
--- a/contrib/CMakeLists.txt
+++ b/contrib/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2014-2016, The Monero Project
+# Copyright (c) 2014-2017, The Monero Project
#
# All rights reserved.
#
diff --git a/contrib/epee/CMakeLists.txt b/contrib/epee/CMakeLists.txt
index d466b87e0..e7ff6001b 100644
--- a/contrib/epee/CMakeLists.txt
+++ b/contrib/epee/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2014-2016, The Monero Project
+# Copyright (c) 2014-2017, The Monero Project
#
# All rights reserved.
#
diff --git a/contrib/epee/include/hex.h b/contrib/epee/include/hex.h
new file mode 100644
index 000000000..f8d6be048
--- /dev/null
+++ b/contrib/epee/include/hex.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2017, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#pragma once
+
+#include <array>
+#include <cstdint>
+#include <iosfwd>
+#include <string>
+
+#include "span.h"
+
+namespace epee
+{
+ struct to_hex
+ {
+ //! \return A std::string containing hex of `src`.
+ static std::string string(const span<const std::uint8_t> src);
+
+ //! \return An array containing hex of `src`.
+ template<std::size_t N>
+ static std::array<char, N * 2> array(const std::array<std::uint8_t, N>& src) noexcept
+ {
+ std::array<char, N * 2> out{{}};
+ static_assert(N <= 128, "keep the stack size down");
+ buffer_unchecked(out.data(), {src.data(), src.size()});
+ return out;
+ }
+
+ //! Append `src` as hex to `out`.
+ static void buffer(std::ostream& out, const span<const std::uint8_t> src);
+
+ //! Append `< + src + >` as hex to `out`.
+ static void formatted(std::ostream& out, const span<const std::uint8_t> src);
+
+ private:
+ //! Write `src` bytes as hex to `out`. `out` must be twice the length
+ static void buffer_unchecked(char* out, const span<const std::uint8_t> src) noexcept;
+ };
+}
diff --git a/contrib/epee/include/md5_l.inl b/contrib/epee/include/md5_l.inl
index 2aa881092..8e339e006 100644
--- a/contrib/epee/include/md5_l.inl
+++ b/contrib/epee/include/md5_l.inl
@@ -58,14 +58,11 @@ These notices must be retained in any copies of any part of this
documentation and/or software.
*/
-/* do i need all of this just for htonl()? damn. */
-//#include <sys/types.h>
-//#include <sys/param.h>
-//#include <sys/socket.h>
-//#include <netinet/in.h>
-
-
-
+#ifdef _WIN32
+# include <winsock2.h>
+#else
+# include <arpa/inet.h>
+#endif
#include "md5global.h"
#include "md5_l.h"
#include "hmac-md5.h"
diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h
index fbfd6941f..6eeb1441f 100644
--- a/contrib/epee/include/misc_log_ex.h
+++ b/contrib/epee/include/misc_log_ex.h
@@ -49,12 +49,6 @@
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
-#define ELPP_THREAD_SAFE
-#define ELPP_DEFAULT_LOG_FILE ""
-#define ELPP_STACKTRACE_ON_CRASH 0
-#define ELPP_DISABLE_DEFAULT_CRASH_HANDLING
-#define ELPP_FEATURE_CRASH_LOG 1
-#define ELPP_DISABLE_CHECK_MACROS
#include "easylogging++.h"
#define MONERO_DEFAULT_LOG_CATEGORY "default"
@@ -115,7 +109,7 @@
#define _warn(x) MWARNING(x)
#define _erro(x) MERROR(x)
-#define MLOG_SET_THREAD_NAME(x) el::Loggers::setThreadName(x)
+#define MLOG_SET_THREAD_NAME(x) el::Helpers::setThreadName(x)
#ifndef LOCAL_ASSERT
#include <assert.h>
diff --git a/contrib/epee/include/net/http_auth.h b/contrib/epee/include/net/http_auth.h
index f43a19457..bf368e6f4 100644
--- a/contrib/epee/include/net/http_auth.h
+++ b/contrib/epee/include/net/http_auth.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2016, The Monero Project
+// Copyright (c) 2014-2017, The Monero Project
//
// All rights reserved.
//
diff --git a/contrib/epee/include/net/http_base.h b/contrib/epee/include/net/http_base.h
index d8e31521f..e5aa06cb4 100644
--- a/contrib/epee/include/net/http_base.h
+++ b/contrib/epee/include/net/http_base.h
@@ -29,6 +29,9 @@
#pragma once
#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>
+#include <boost/utility/string_ref.hpp>
+#include <string>
+#include <utility>
#include "string_tools.h"
@@ -90,6 +93,15 @@ namespace net_utils
return std::string();
}
+ static inline void add_field(std::string& out, const boost::string_ref name, const boost::string_ref value)
+ {
+ out.append(name.data(), name.size()).append(": ");
+ out.append(value.data(), value.size()).append("\r\n");
+ }
+ static inline void add_field(std::string& out, const std::pair<std::string, std::string>& field)
+ {
+ add_field(out, field.first, field.second);
+ }
struct http_header_info
diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h
index c5aeb9251..67e63f7bf 100644
--- a/contrib/epee/include/net/http_client.h
+++ b/contrib/epee/include/net/http_client.h
@@ -30,6 +30,8 @@
#include <boost/shared_ptr.hpp>
#include <boost/regex.hpp>
#include <boost/lexical_cast.hpp>
+#include <boost/optional/optional.hpp>
+#include <boost/utility/string_ref.hpp>
//#include <mbstring.h>
#include <algorithm>
#include <cctype>
@@ -45,6 +47,7 @@
#include "string_tools.h"
#include "reg_exp_definer.h"
#include "http_base.h"
+#include "http_auth.h"
#include "to_nonconst_iterator.h"
#include "net_parse_helpers.h"
@@ -104,14 +107,14 @@ using namespace std;
//---------------------------------------------------------------------------
static inline const char* get_hex_vals()
{
- static char hexVals[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+ static const char hexVals[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
return hexVals;
}
static inline const char* get_unsave_chars()
{
//static char unsave_chars[] = "\"<>%\\^[]`+$,@:;/!#?=&";
- static char unsave_chars[] = "\"<>%\\^[]`+$,@:;!#&";
+ static const char unsave_chars[] = "\"<>%\\^[]`+$,@:;!#&";
return unsave_chars;
}
@@ -236,9 +239,6 @@ using namespace std;
class http_simple_client: public i_target_handler
{
- public:
-
-
private:
enum reciev_machine_state
{
@@ -263,6 +263,7 @@ using namespace std;
blocked_mode_client m_net_client;
std::string m_host_buff;
std::string m_port;
+ http_client_auth m_auth;
std::string m_header_cache;
http_response_info m_response_info;
size_t m_len_in_summary;
@@ -280,6 +281,7 @@ using namespace std;
, m_net_client()
, m_host_buff()
, m_port()
+ , m_auth()
, m_header_cache()
, m_response_info()
, m_len_in_summary(0)
@@ -291,21 +293,22 @@ using namespace std;
, m_lock()
{}
- bool set_server(const std::string& address)
+ bool set_server(const std::string& address, boost::optional<login> user)
{
http::url_content parsed{};
const bool r = parse_url(address, parsed);
CHECK_AND_ASSERT_MES(r, false, "failed to parse url: " << address);
- set_server(std::move(parsed.host), std::to_string(parsed.port));
+ set_server(std::move(parsed.host), std::to_string(parsed.port), std::move(user));
return true;
}
- void set_server(std::string host, std::string port)
+ void set_server(std::string host, std::string port, boost::optional<login> user)
{
CRITICAL_REGION_LOCAL(m_lock);
disconnect();
m_host_buff = std::move(host);
m_port = std::move(port);
+ m_auth = user ? http_client_auth{std::move(*user)} : http_client_auth{};
}
bool connect(std::chrono::milliseconds timeout)
@@ -334,15 +337,20 @@ using namespace std;
return true;
}
//---------------------------------------------------------------------------
+ virtual bool on_header(const http_response_info &headers)
+ {
+ return true;
+ }
+ //---------------------------------------------------------------------------
inline
- bool invoke_get(const std::string& uri, std::chrono::milliseconds timeout, const std::string& body = std::string(), const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
+ bool invoke_get(const boost::string_ref uri, std::chrono::milliseconds timeout, const std::string& body = std::string(), const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
{
CRITICAL_REGION_LOCAL(m_lock);
return invoke(uri, "GET", body, timeout, ppresponse_info, additional_params);
}
//---------------------------------------------------------------------------
- inline bool invoke(const std::string& uri, const std::string& method, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
+ inline bool invoke(const boost::string_ref uri, const boost::string_ref method, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
{
CRITICAL_REGION_LOCAL(m_lock);
if(!is_connected())
@@ -354,32 +362,64 @@ using namespace std;
return false;
}
}
- m_response_info.clear();
- std::string req_buff = method + " ";
- req_buff += uri + " HTTP/1.1\r\n" +
- "Host: "+ m_host_buff +"\r\n" + "Content-Length: " + boost::lexical_cast<std::string>(body.size()) + "\r\n";
+ std::string req_buff{};
+ req_buff.reserve(2048);
+ req_buff.append(method.data(), method.size()).append(" ").append(uri.data(), uri.size()).append(" HTTP/1.1\r\n");
+ add_field(req_buff, "Host", m_host_buff);
+ add_field(req_buff, "Content-Length", std::to_string(body.size()));
//handle "additional_params"
- for(fields_list::const_iterator it = additional_params.begin(); it!=additional_params.end(); it++)
- req_buff += it->first + ": " + it->second + "\r\n";
- req_buff += "\r\n";
- //--
-
- bool res = m_net_client.send(req_buff, timeout);
- CHECK_AND_ASSERT_MES(res, false, "HTTP_CLIENT: Failed to SEND");
- if(body.size())
- res = m_net_client.send(body, timeout);
- CHECK_AND_ASSERT_MES(res, false, "HTTP_CLIENT: Failed to SEND");
-
- if(ppresponse_info)
- *ppresponse_info = &m_response_info;
-
- m_state = reciev_machine_state_header;
- return handle_reciev(timeout);
+ for(const auto& field : additional_params)
+ add_field(req_buff, field);
+
+ for (unsigned sends = 0; sends < 2; ++sends)
+ {
+ const std::size_t initial_size = req_buff.size();
+ const auto auth = m_auth.get_auth_field(method, uri);
+ if (auth)
+ add_field(req_buff, *auth);
+
+ req_buff += "\r\n";
+ //--
+
+ bool res = m_net_client.send(req_buff, timeout);
+ CHECK_AND_ASSERT_MES(res, false, "HTTP_CLIENT: Failed to SEND");
+ if(body.size())
+ res = m_net_client.send(body, timeout);
+ CHECK_AND_ASSERT_MES(res, false, "HTTP_CLIENT: Failed to SEND");
+
+
+ m_response_info.clear();
+ m_state = reciev_machine_state_header;
+ if (!handle_reciev(timeout))
+ return false;
+ if (m_response_info.m_response_code != 401)
+ {
+ if(ppresponse_info)
+ *ppresponse_info = std::addressof(m_response_info);
+ return true;
+ }
+
+ switch (m_auth.handle_401(m_response_info))
+ {
+ case http_client_auth::kSuccess:
+ break;
+ case http_client_auth::kBadPassword:
+ sends = 2;
+ break;
+ default:
+ case http_client_auth::kParseFailure:
+ LOG_ERROR("Bad server response for authentication");
+ return false;
+ }
+ req_buff.resize(initial_size); // rollback for new auth generation
+ }
+ LOG_ERROR("Client has incorrect username/password for server requiring authentication");
+ return false;
}
//---------------------------------------------------------------------------
- inline bool invoke_post(const std::string& uri, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
+ inline bool invoke_post(const boost::string_ref uri, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
{
CRITICAL_REGION_LOCAL(m_lock);
return invoke(uri, "POST", body, timeout, ppresponse_info, additional_params);
@@ -470,6 +510,12 @@ using namespace std;
m_header_cache.erase(m_header_cache.begin()+pos+4, m_header_cache.end());
analize_cached_header_and_invoke_state();
+ if (!on_header(m_response_info))
+ {
+ MDEBUG("Connection cancelled by on_header");
+ m_state = reciev_machine_state_done;
+ return false;
+ }
m_header_cache.clear();
if(!recv_buff.size() && (m_state != reciev_machine_state_error && m_state != reciev_machine_state_done))
need_more_data = true;
@@ -492,7 +538,11 @@ using namespace std;
}
CHECK_AND_ASSERT_MES(m_len_in_remain >= recv_buff.size(), false, "m_len_in_remain >= recv_buff.size()");
m_len_in_remain -= recv_buff.size();
- m_pcontent_encoding_handler->update_in(recv_buff);
+ if (!m_pcontent_encoding_handler->update_in(recv_buff))
+ {
+ m_state = reciev_machine_state_done;
+ return false;
+ }
if(m_len_in_remain == 0)
m_state = reciev_machine_state_done;
@@ -665,7 +715,11 @@ using namespace std;
m_len_in_remain = 0;
}
- m_pcontent_encoding_handler->update_in(chunk_body);
+ if (!m_pcontent_encoding_handler->update_in(chunk_body))
+ {
+ m_state = reciev_machine_state_error;
+ return false;
+ }
if(!m_len_in_remain)
m_chunked_state = http_chunked_state_chunk_head;
@@ -730,7 +784,7 @@ using namespace std;
else if(result[i++].matched)//"User-Agent"
body_info.m_user_agent = result[field_val];
else if(result[i++].matched)//e.t.c (HAVE TO BE MATCHED!)
- {;}
+ body_info.m_etc_fields.emplace_back(result[11], result[field_val]);
else
{CHECK_AND_ASSERT_MES(false, false, "http_stream_filter::parse_cached_header() not matched last entry in:"<<m_cache_to_process);}
diff --git a/contrib/epee/include/net/http_protocol_handler.h b/contrib/epee/include/net/http_protocol_handler.h
index c2e44c536..babe49ad7 100644
--- a/contrib/epee/include/net/http_protocol_handler.h
+++ b/contrib/epee/include/net/http_protocol_handler.h
@@ -54,7 +54,6 @@ namespace net_utils
struct http_server_config
{
std::string m_folder;
- std::string m_required_user_agent;
boost::optional<login> m_user;
critical_section m_lock;
};
diff --git a/contrib/epee/include/net/http_protocol_handler.inl b/contrib/epee/include/net/http_protocol_handler.inl
index 5bfaf4767..d9eca2479 100644
--- a/contrib/epee/include/net/http_protocol_handler.inl
+++ b/contrib/epee/include/net/http_protocol_handler.inl
@@ -390,13 +390,6 @@ namespace net_utils
return false;
}
- if (!m_config.m_required_user_agent.empty() && m_query_info.m_header_info.m_user_agent != m_config.m_required_user_agent)
- {
- LOG_ERROR("simple_http_connection_handler<t_connection_context>::analize_cached_request_header_and_invoke_state(): unexpected user agent: " << m_query_info.m_header_info.m_user_agent);
- m_state = http_state_error;
- return false;
- }
-
m_cache.erase(0, pos);
std::string req_command_str = m_query_info.m_full_request_str;
diff --git a/contrib/epee/include/net/http_server_impl_base.h b/contrib/epee/include/net/http_server_impl_base.h
index f2a580167..acecbb2d4 100644
--- a/contrib/epee/include/net/http_server_impl_base.h
+++ b/contrib/epee/include/net/http_server_impl_base.h
@@ -56,7 +56,7 @@ namespace epee
{}
bool init(const std::string& bind_port = "0", const std::string& bind_ip = "0.0.0.0",
- std::string user_agent = "", boost::optional<net_utils::http::login> user = boost::none)
+ boost::optional<net_utils::http::login> user = boost::none)
{
//set self as callback handler
@@ -65,11 +65,9 @@ namespace epee
//here set folder for hosting reqests
m_net_server.get_config_object().m_folder = "";
- // workaround till we get auth/encryption
- m_net_server.get_config_object().m_required_user_agent = std::move(user_agent);
m_net_server.get_config_object().m_user = std::move(user);
- LOG_PRINT_L0("Binding on " << bind_ip << ":" << bind_port);
+ MGINFO("Binding on " << bind_ip << ":" << bind_port);
bool res = m_net_server.init_server(bind_port, bind_ip);
if(!res)
{
diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h
index cc6987e8f..891089be6 100644
--- a/contrib/epee/include/net/levin_protocol_handler_async.h
+++ b/contrib/epee/include/net/levin_protocol_handler_async.h
@@ -25,6 +25,7 @@
//
#pragma once
+#include <boost/asio/deadline_timer.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/unordered_map.hpp>
#include <boost/interprocess/detail/atomic.hpp>
diff --git a/contrib/epee/include/net/net_utils_base.h b/contrib/epee/include/net/net_utils_base.h
index cfa51e10d..4334029f7 100644
--- a/contrib/epee/include/net/net_utils_base.h
+++ b/contrib/epee/include/net/net_utils_base.h
@@ -29,6 +29,7 @@
#ifndef _NET_UTILS_BASE_H_
#define _NET_UTILS_BASE_H_
+#include <boost/asio/io_service.hpp>
#include <boost/uuid/uuid.hpp>
#include "string_tools.h"
#include "misc_log_ex.h"
@@ -159,11 +160,11 @@ inline MAKE_LOGGABLE(connection_context_base, ct, os)
#define LOG_TRACE_CC(ct, message) MTRACE(ct << message)
#define LOG_CC(level, ct, message) MLOG(level, ct << message)
-#define LOG_PRINT_CC_L0(ct, message) LOG_PRINT_L0(epee::net_utils::print_connection_context_short(ct) << message)
-#define LOG_PRINT_CC_L1(ct, message) LOG_PRINT_L1(epee::net_utils::print_connection_context_short(ct) << message)
-#define LOG_PRINT_CC_L2(ct, message) LOG_PRINT_L2(epee::net_utils::print_connection_context_short(ct) << message)
-#define LOG_PRINT_CC_L3(ct, message) LOG_PRINT_L3(epee::net_utils::print_connection_context_short(ct) << message)
-#define LOG_PRINT_CC_L4(ct, message) LOG_PRINT_L4(epee::net_utils::print_connection_context_short(ct) << message)
+#define LOG_PRINT_CC_L0(ct, message) LOG_PRINT_L0(ct << message)
+#define LOG_PRINT_CC_L1(ct, message) LOG_PRINT_L1(ct << message)
+#define LOG_PRINT_CC_L2(ct, message) LOG_PRINT_L2(ct << message)
+#define LOG_PRINT_CC_L3(ct, message) LOG_PRINT_L3(ct << message)
+#define LOG_PRINT_CC_L4(ct, message) LOG_PRINT_L4(ct << message)
#define LOG_PRINT_CCONTEXT_L0(message) LOG_PRINT_CC_L0(context, message)
#define LOG_PRINT_CCONTEXT_L1(message) LOG_PRINT_CC_L1(context, message)
diff --git a/contrib/epee/include/span.h b/contrib/epee/include/span.h
new file mode 100644
index 000000000..ea4ba63dd
--- /dev/null
+++ b/contrib/epee/include/span.h
@@ -0,0 +1,130 @@
+// Copyright (c) 2017, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#pragma once
+
+#include <cstdint>
+#include <memory>
+#include <type_traits>
+
+namespace epee
+{
+ /*!
+ \brief Non-owning sequence of data. Does not deep copy
+
+ Inspired by `gsl::span` and/or `boost::iterator_range`. This class is
+ intended to be used as a parameter type for functions that need to take a
+ writable or read-only sequence of data. Most common cases are `span<char>`
+ and `span<std::uint8_t>`. Using as a class member is only recommended if
+ clearly documented as not doing a deep-copy. C-arrays are easily convertible
+ to this type.
+
+ \note Conversion from C string literal to `span<const char>` will include
+ the NULL-terminator.
+ \note Never allows derived-to-base pointer conversion; an array of derived
+ types is not an array of base types.
+ */
+ template<typename T>
+ class span
+ {
+ /* Supporting class types is tricky - the {ptr,len} constructor will allow
+ derived-to-base conversions. This is NOT desireable because an array of
+ derived types is not an array of base types. It is possible to handle
+ this case, implement when/if needed. */
+ static_assert(!std::is_class<T>(), "no class types are currently allowed");
+ public:
+ using value_type = T;
+ using size_type = std::size_t;
+ using difference_type = std::ptrdiff_t;
+ using pointer = T*;
+ using const_pointer = const T*;
+ using reference = T&;
+ using const_reference = const T&;
+ using iterator = pointer;
+ using const_iterator = const_pointer;
+
+ constexpr span() noexcept : ptr(nullptr), len(0) {}
+ constexpr span(std::nullptr_t) noexcept : span() {}
+
+ constexpr span(T* const src_ptr, const std::size_t count) noexcept
+ : ptr(src_ptr), len(count) {}
+
+ //! Conversion from C-array. Prevents common bugs with sizeof + arrays.
+ template<std::size_t N>
+ constexpr span(T (&src)[N]) noexcept : span(src, N) {}
+
+ constexpr span(const span&) noexcept = default;
+ span& operator=(const span&) noexcept = default;
+
+ constexpr iterator begin() const noexcept { return ptr; }
+ constexpr const_iterator cbegin() const noexcept { return ptr; }
+
+ constexpr iterator end() const noexcept { return begin() + size(); }
+ constexpr const_iterator cend() const noexcept { return cbegin() + size(); }
+
+ constexpr bool empty() const noexcept { return size() == 0; }
+ constexpr pointer data() const noexcept { return ptr; }
+ constexpr std::size_t size() const noexcept { return len; }
+ constexpr std::size_t size_bytes() const noexcept { return size() * sizeof(value_type); }
+
+ private:
+ T* ptr;
+ std::size_t len;
+ };
+
+ //! \return `span<const T::value_type>` from a STL compatible `src`.
+ template<typename T>
+ constexpr span<const typename T::value_type> to_span(const T& src)
+ {
+ // compiler provides diagnostic if size() is not size_t.
+ return {src.data(), src.size()};
+ }
+
+ template<typename T>
+ constexpr bool has_padding() noexcept
+ {
+ return !std::is_pod<T>() || alignof(T) != 1;
+ }
+
+ //! \return Cast data from `src` as `span<const std::uint8_t>`.
+ template<typename T>
+ span<const std::uint8_t> to_byte_span(const span<const T> src) noexcept
+ {
+ static_assert(!has_padding<T>(), "source type may have padding");
+ return {reinterpret_cast<const std::uint8_t*>(src.data()), src.size_bytes()};
+ }
+
+ //! \return `span<const std::uint8_t>` which represents the bytes at `&src`.
+ template<typename T>
+ span<const std::uint8_t> as_byte_span(const T& src) noexcept
+ {
+ static_assert(!std::is_empty<T>(), "empty types will not work -> sizeof == 1");
+ static_assert(!has_padding<T>(), "source type may have padding");
+ return {reinterpret_cast<const std::uint8_t*>(std::addressof(src)), sizeof(T)};
+ }
+}
diff --git a/contrib/epee/include/storages/http_abstract_invoke.h b/contrib/epee/include/storages/http_abstract_invoke.h
index 36177c7e0..823ce6731 100644
--- a/contrib/epee/include/storages/http_abstract_invoke.h
+++ b/contrib/epee/include/storages/http_abstract_invoke.h
@@ -26,6 +26,9 @@
//
#pragma once
+#include <boost/utility/string_ref.hpp>
+#include <chrono>
+#include <string>
#include "portable_storage_template_helper.h"
#include "net/http_base.h"
#include "net/http_server_handlers_map2.h"
@@ -35,7 +38,7 @@ namespace epee
namespace net_utils
{
template<class t_request, class t_response, class t_transport>
- bool invoke_http_json(const std::string& uri, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(5), const std::string& method = "GET")
+ bool invoke_http_json(const boost::string_ref uri, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref method = "GET")
{
std::string req_param;
if(!serialization::store_t_to_json(out_struct, req_param))
@@ -66,7 +69,7 @@ namespace epee
template<class t_request, class t_response, class t_transport>
- bool invoke_http_bin(const std::string& uri, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(5), const std::string& method = "GET")
+ bool invoke_http_bin(const boost::string_ref uri, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref method = "GET")
{
std::string req_param;
if(!serialization::store_t_to_binary(out_struct, req_param))
@@ -95,7 +98,7 @@ namespace epee
}
template<class t_request, class t_response, class t_transport>
- bool invoke_http_json_rpc(const std::string& uri, std::string method_name, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(5), const std::string& http_method = "GET", const std::string& req_id = "0")
+ bool invoke_http_json_rpc(const boost::string_ref uri, std::string method_name, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref http_method = "GET", const std::string& req_id = "0")
{
epee::json_rpc::request<t_request> req_t = AUTO_VAL_INIT(req_t);
req_t.jsonrpc = "2.0";
@@ -117,7 +120,7 @@ namespace epee
}
template<class t_command, class t_transport>
- bool invoke_http_json_rpc(const std::string& uri, typename t_command::request& out_struct, typename t_command::response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(5), const std::string& http_method = "GET", const std::string& req_id = "0")
+ bool invoke_http_json_rpc(const boost::string_ref uri, typename t_command::request& out_struct, typename t_command::response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref http_method = "GET", const std::string& req_id = "0")
{
return invoke_http_json_rpc(uri, t_command::methodname(), out_struct, result_struct, transport, timeout, http_method, req_id);
}
diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h
index 6292e471c..67984b9e4 100644
--- a/contrib/epee/include/string_tools.h
+++ b/contrib/epee/include/string_tools.h
@@ -29,18 +29,24 @@
#ifndef _STRING_TOOLS_H_
#define _STRING_TOOLS_H_
+// Previously pulled in by ASIO, further cleanup still required ...
+#ifdef _WIN32
+# include <winsock2.h>
+# include <windows.h>
+#endif
+
//#include <objbase.h>
#include <locale>
#include <cstdlib>
#include <iomanip>
+#include <map>
#include <type_traits>
-//#include <strsafe.h>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>
-#include <boost/asio.hpp>
-#include <boost/algorithm/string/compare.hpp>
#include <boost/algorithm/string.hpp>
+#include "hex.h"
+#include "span.h"
#include "warnings.h"
@@ -110,33 +116,10 @@ namespace string_tools
return false;
}
}
- //----------------------------------------------------------------------------
- template<class CharT>
- std::basic_string<CharT> buff_to_hex(const std::basic_string<CharT>& s)
- {
- using namespace std;
- basic_stringstream<CharT> hexStream;
- hexStream << hex << noshowbase << setw(2);
-
- for(typename std::basic_string<CharT>::const_iterator it = s.begin(); it != s.end(); it++)
- {
- hexStream << "0x"<< static_cast<unsigned int>(static_cast<unsigned char>(*it)) << " ";
- }
- return hexStream.str();
- }
//----------------------------------------------------------------------------
- template<class CharT>
- std::basic_string<CharT> buff_to_hex_nodelimer(const std::basic_string<CharT>& s)
+ inline std::string buff_to_hex_nodelimer(const std::string& src)
{
- using namespace std;
- basic_stringstream<CharT> hexStream;
- hexStream << hex << noshowbase;
-
- for(typename std::basic_string<CharT>::const_iterator it = s.begin(); it != s.end(); it++)
- {
- hexStream << setw(2) << setfill('0') << static_cast<unsigned int>(static_cast<unsigned char>(*it));
- }
- return hexStream.str();
+ return to_hex::string(to_byte_span(to_span(src)));
}
//----------------------------------------------------------------------------
template<class CharT>
@@ -327,26 +310,9 @@ POP_WARNINGS
}
//----------------------------------------------------------------------------
-//#ifdef _WINSOCK2API_
- inline std::string get_ip_string_from_int32(uint32_t ip)
- {
- in_addr adr;
- adr.s_addr = ip;
- const char* pbuf = inet_ntoa(adr);
- if(pbuf)
- return pbuf;
- else
- return "[failed]";
- }
+ std::string get_ip_string_from_int32(uint32_t ip);
//----------------------------------------------------------------------------
- inline bool get_ip_int32_from_string(uint32_t& ip, const std::string& ip_str)
- {
- ip = inet_addr(ip_str.c_str());
- if(INADDR_NONE == ip)
- return false;
-
- return true;
- }
+ bool get_ip_int32_from_string(uint32_t& ip, const std::string& ip_str);
//----------------------------------------------------------------------------
inline bool parse_peer_from_string(uint32_t& ip, uint32_t& port, const std::string& addres)
{
@@ -376,7 +342,6 @@ POP_WARNINGS
return true;
}
-//#endif
//----------------------------------------------------------------------------
template<typename t>
inline std::string get_t_as_hex_nwidth(const t& v, std::streamsize w = 8)
@@ -573,9 +538,7 @@ POP_WARNINGS
std::string pod_to_hex(const t_pod_type& s)
{
static_assert(std::is_pod<t_pod_type>::value, "expected pod type");
- std::string buff;
- buff.assign(reinterpret_cast<const char*>(&s), sizeof(s));
- return buff_to_hex_nodelimer(buff);
+ return to_hex::string(as_byte_span(s));
}
//----------------------------------------------------------------------------
template<class t_pod_type>
diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt
index 93c9a94f7..1d5fa0394 100644
--- a/contrib/epee/src/CMakeLists.txt
+++ b/contrib/epee/src/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2014-2016, The Monero Project
+# Copyright (c) 2014-2017, The Monero Project
#
# All rights reserved.
#
@@ -26,7 +26,7 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-add_library(epee STATIC http_auth.cpp mlog.cpp)
+add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp string_tools.cpp)
# Build and install libepee if we're building for GUI
if (BUILD_GUI_DEPS)
if(IOS)
@@ -36,4 +36,12 @@ if (BUILD_GUI_DEPS)
endif()
install(TARGETS epee
ARCHIVE DESTINATION ${lib_folder})
-endif() \ No newline at end of file
+endif()
+
+target_link_libraries(epee
+ PUBLIC
+ crypto
+ easylogging
+ ${Boost_FILESYSTEM_LIBRARY}
+ PRIVATE
+ ${EXTRA_LIBRARIES})
diff --git a/contrib/epee/src/hex.cpp b/contrib/epee/src/hex.cpp
new file mode 100644
index 000000000..cfbd3cf87
--- /dev/null
+++ b/contrib/epee/src/hex.cpp
@@ -0,0 +1,82 @@
+// Copyright (c) 2017, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "hex.h"
+
+#include <iterator>
+#include <limits>
+#include <ostream>
+#include <stdexcept>
+
+namespace epee
+{
+ namespace
+ {
+ template<typename T>
+ void write_hex(T&& out, const span<const std::uint8_t> src)
+ {
+ static constexpr const char hex[] = u8"0123456789abcdef";
+ static_assert(sizeof(hex) == 17, "bad string size");
+ for (const std::uint8_t byte : src)
+ {
+ *out = hex[byte >> 4];
+ ++out;
+ *out = hex[byte & 0x0F];
+ ++out;
+ }
+ }
+ }
+
+ std::string to_hex::string(const span<const std::uint8_t> src)
+ {
+ if (std::numeric_limits<std::size_t>::max() / 2 < src.size())
+ throw std::range_error("hex_view::to_string exceeded maximum size");
+
+ std::string out{};
+ out.resize(src.size() * 2);
+ buffer_unchecked(std::addressof(out[0]), src);
+ return out;
+ }
+
+ void to_hex::buffer(std::ostream& out, const span<const std::uint8_t> src)
+ {
+ write_hex(std::ostreambuf_iterator<char>{out}, src);
+ }
+
+ void to_hex::formatted(std::ostream& out, const span<const std::uint8_t> src)
+ {
+ out.put('<');
+ buffer(out, src);
+ out.put('>');
+ }
+
+ void to_hex::buffer_unchecked(char* out, const span<const std::uint8_t> src) noexcept
+ {
+ return write_hex(out, src);
+ }
+}
diff --git a/contrib/epee/src/http_auth.cpp b/contrib/epee/src/http_auth.cpp
index 7fd32dabc..30e562700 100644
--- a/contrib/epee/src/http_auth.cpp
+++ b/contrib/epee/src/http_auth.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2016, The Monero Project
+// Copyright (c) 2014-2017, The Monero Project
//
// All rights reserved.
//
@@ -67,6 +67,7 @@
#include <type_traits>
#include "crypto/crypto.h"
+#include "hex.h"
#include "md5_l.h"
#include "string_coding.h"
@@ -104,25 +105,6 @@ namespace
//// Digest Algorithms
- template<std::size_t N>
- std::array<char, N * 2> to_hex(const std::array<std::uint8_t, N>& digest) noexcept
- {
- static constexpr const char alphabet[] = u8"0123456789abcdef";
- static_assert(sizeof(alphabet) == 17, "bad alphabet size");
-
- // TODO upgrade (improve performance) of to hex in epee string tools
- std::array<char, N * 2> out{{}};
- auto current = out.begin();
- for (const std::uint8_t byte : digest)
- {
- *current = alphabet[byte >> 4];
- ++current;
- *current = alphabet[byte & 0x0F];
- ++current;
- }
- return out;
- }
-
struct md5_
{
static constexpr const boost::string_ref name = ceref(u8"MD5");
@@ -156,7 +138,7 @@ namespace
std::array<std::uint8_t, 16> digest{{}};
md5::MD5Final(digest.data(), std::addressof(ctx));
- return to_hex(digest);
+ return epee::to_hex::array(digest);
}
};
constexpr const boost::string_ref md5_::name;
@@ -362,7 +344,7 @@ namespace
server_parameters best{};
- const std::list<field>& fields = response.m_additional_fields;
+ const std::list<field>& fields = response.m_header_info.m_etc_fields;
auto current = fields.begin();
const auto end = fields.end();
while (true)
diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp
index 7f9ef4b3a..7487fdbd2 100644
--- a/contrib/epee/src/mlog.cpp
+++ b/contrib/epee/src/mlog.cpp
@@ -33,8 +33,13 @@
INITIALIZE_EASYLOGGINGPP
+#undef MONERO_DEFAULT_LOG_CATEGORY
+#define MONERO_DEFAULT_LOG_CATEGORY "logging"
+
#define MLOG_BASE_FORMAT "%datetime{%Y-%M-%d %H:%m:%s.%g}\t%thread\t%level\t%logger\t%loc\t%msg"
+#define MLOG_LOG(x) CINFO(el::base::Writer,el::base::DispatchAction::FileOnlyLog,MONERO_DEFAULT_LOG_CATEGORY) << x
+
using namespace epee;
static std::string generate_log_filename(const char *base)
@@ -88,10 +93,10 @@ static const char *get_default_categories(int level)
switch (level)
{
case 0:
- categories = "*:WARNING,net*:FATAL,global:INFO,verify:FATAL,stacktrace:INFO";
+ categories = "*:WARNING,net:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,stacktrace:INFO,logging:INFO";
break;
case 1:
- categories = "*:WARNING,global:INFO,stacktrace:INFO";
+ categories = "*:WARNING,global:INFO,stacktrace:INFO,logging:INFO";
break;
case 2:
categories = "*:DEBUG";
@@ -142,7 +147,7 @@ void mlog_configure(const std::string &filename_base, bool console)
void mlog_set_categories(const char *categories)
{
el::Loggers::setCategories(categories);
- MINFO("Mew log categories: " << categories);
+ MLOG_LOG("New log categories: " << categories);
}
// maps epee style log level to new logging system
@@ -150,7 +155,7 @@ void mlog_set_log_level(int level)
{
const char *categories = get_default_categories(level);
el::Loggers::setCategories(categories);
- MINFO("Mew log categories: " << categories);
+ MLOG_LOG("New log categories: " << categories);
}
void mlog_set_log(const char *log)
diff --git a/contrib/epee/src/string_tools.cpp b/contrib/epee/src/string_tools.cpp
new file mode 100644
index 000000000..d04b16b75
--- /dev/null
+++ b/contrib/epee/src/string_tools.cpp
@@ -0,0 +1,61 @@
+// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the Andrey N. Sabelnikov nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include "string_tools.h"
+
+#ifdef _WIN32
+# include <winsock2.h>
+#else
+# include <arpa/inet.h>
+# include <netinet/in.h>
+#endif
+
+namespace epee
+{
+namespace string_tools
+{
+ std::string get_ip_string_from_int32(uint32_t ip)
+ {
+ in_addr adr;
+ adr.s_addr = ip;
+ const char* pbuf = inet_ntoa(adr);
+ if(pbuf)
+ return pbuf;
+ else
+ return "[failed]";
+ }
+ //----------------------------------------------------------------------------
+ bool get_ip_int32_from_string(uint32_t& ip, const std::string& ip_str)
+ {
+ ip = inet_addr(ip_str.c_str());
+ if(INADDR_NONE == ip)
+ return false;
+
+ return true;
+ }
+}
+}
+
diff --git a/contrib/snap/daemon.bash b/contrib/snap/daemon.bash
deleted file mode 100755
index 41d1275de..000000000
--- a/contrib/snap/daemon.bash
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash -e
-
-export LD_LIBRARY_PATH=${SNAP_LIBRARY_PATH}:${SNAP}/usr/lib/x86_64-linux-gnu
-export HOME=${SNAP_DATA}
-cd ${SNAP_DATA}
-
-ARGS=
-if [ -e "${SNAP_DATA}/etc/monerod.conf" ]; then
- ARGS="--config-file ${SNAP_DATA}/etc/monerod.conf"
-fi
-
-exec ${SNAP}/bin/monerod --detach $ARGS
diff --git a/contrib/snap/log.bash b/contrib/snap/log.bash
deleted file mode 100755
index c81efeb2c..000000000
--- a/contrib/snap/log.bash
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash -e
-
-exec tail -c +0 -F ${SNAP_DATA}/.bitmonero/bitmonero.log
diff --git a/contrib/snap/monerod-wrapper b/contrib/snap/monerod-wrapper
new file mode 100755
index 000000000..f7266e11c
--- /dev/null
+++ b/contrib/snap/monerod-wrapper
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if [ ! -d "$SNAP_USER_DATA/etc" ]; then
+ mkdir $SNAP_USER_DATA/etc/
+ cp -R $SNAP/etc/monerod.conf $SNAP_USER_DATA/etc/monerod.conf
+fi
+
+exec "$SNAP/bin/monerod" "$@"
diff --git a/contrib/snap/monerod.conf b/contrib/snap/monerod.conf
new file mode 100644
index 000000000..9b3d308ed
--- /dev/null
+++ b/contrib/snap/monerod.conf
@@ -0,0 +1,9 @@
+# Configuration for monerod
+# Syntax: any command line option may be specified as 'clioptionname=value'.
+# See 'monerod --help' for all available options.
+
+# Overrided by snap:
+# data-dir=/var/lib/monero
+# log-file=/var/log/monero/monero.log
+
+log-level=0
diff --git a/contrib/snap/setup/gui/icon.png b/contrib/snap/setup/gui/icon.png
new file mode 100644
index 000000000..17b8bd47b
--- /dev/null
+++ b/contrib/snap/setup/gui/icon.png
Binary files differ
diff --git a/contrib/snap/snapcraft.yaml b/contrib/snap/snapcraft.yaml
new file mode 100644
index 000000000..11d480d10
--- /dev/null
+++ b/contrib/snap/snapcraft.yaml
@@ -0,0 +1,75 @@
+name: monero
+version: 0.10.2-1
+summary: "Monero: the secure, private, untraceable cryptocurrency https://getmonero.org"
+description: |
+ Monero is a private, secure, untraceable, decentralised digital currency.
+ You are your bank, you control your funds, and nobody can trace your transfers
+ unless you allow them to do so.
+grade: devel
+confinement: strict
+
+apps:
+ monerod:
+ daemon: forking
+ command: |
+ monerod-wrapper --detach --data-dir ${SNAP_COMMON} --config-file ${SNAP_USER_DATA}/etc/monerod.conf
+ plugs:
+ - network
+ - network-bind
+ monero-wallet-rpc:
+ command: |
+ monero-wallet-rpc --log-file ${SNAP_USER_DATA}
+ plugs:
+ - home
+ - network
+ - network-bind
+ monero-wallet-cli:
+ command: |
+ monero-wallet-cli --log-file ${SNAP_USER_DATA}
+ plugs:
+ - home
+ - network
+
+parts:
+ cmake-build:
+ plugin: cmake
+ configflags:
+ - -DBDB_STATIC=1
+ - -DUPNP_STATIC=1
+ - -DBoost_USE_STATIC_LIBS=1
+ - -DBoost_USE_STATIC_RUNTIME=1
+ - -DARCH=default
+ source: .
+ build-packages:
+ - gcc
+ - pkg-config
+ - libunbound-dev
+ - libevent-dev
+ - libboost-all-dev
+ - libdb-dev
+ - libunwind-dev
+ - libminiupnpc-dev
+ - libldns-dev
+ - libexpat1-dev
+ - bison
+ - doxygen
+ - graphviz
+ stage-packages:
+ - libminiupnpc10
+ - libunbound2
+ - libunwind8
+ prime:
+ - bin
+ - usr/lib/
+ - -usr/lib/gcc
+ - -usr/share
+
+ dist-files:
+ plugin: dump
+ source: .
+ organize:
+ contrib/snap/monerod.conf: etc/monerod.conf
+ contrib/snap/monerod-wrapper: bin/monerod-wrapper
+ prime:
+ - etc
+ - bin
diff --git a/contrib/snap/wallet.bash b/contrib/snap/wallet.bash
deleted file mode 100755
index 004f1371e..000000000
--- a/contrib/snap/wallet.bash
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash -e
-
-export LD_LIBRARY_PATH=${SNAP_LIBRARY_PATH}:${SNAP}/usr/lib/x86_64-linux-gnu
-export HOME=${SNAP_USER_DATA}
-cd ${SNAP_USER_DATA}
-
-exec ${SNAP}/usr/bin/rlwrap ${SNAP}/bin/monero-wallet-cli "$@"