summaryrefslogtreecommitdiff
path: root/src/libutp/utp_internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutp/utp_internal.h')
-rw-r--r--src/libutp/utp_internal.h188
1 files changed, 188 insertions, 0 deletions
diff --git a/src/libutp/utp_internal.h b/src/libutp/utp_internal.h
new file mode 100644
index 00000000..1edb1aa2
--- /dev/null
+++ b/src/libutp/utp_internal.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2010-2013 BitTorrent, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef __UTP_INTERNAL_H__
+#define __UTP_INTERNAL_H__
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <algorithm>
+#include <functional>
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+#include "utp.h"
+#include "utp_callbacks.h"
+#include "utp_templates.h"
+#include "utp_packedsockaddr.h"
+
+/* These originally lived in utp_config.h */
+#define CCONTROL_TARGET (100 * 1000) // us
+
+enum bandwidth_type_t {
+ payload_bandwidth, connect_overhead,
+ close_overhead, ack_overhead,
+ header_overhead, retransmit_overhead
+};
+
+#ifdef WIN32
+ #ifdef _MSC_VER
+ #include "libutp_inet_ntop.h"
+ #endif
+
+ // newer versions of MSVC define these in errno.h
+ #ifndef ECONNRESET
+ #define ECONNRESET WSAECONNRESET
+ #define EMSGSIZE WSAEMSGSIZE
+ #define ECONNREFUSED WSAECONNREFUSED
+ #define ETIMEDOUT WSAETIMEDOUT
+ #endif
+#endif
+
+struct PACKED_ATTRIBUTE RST_Info {
+ RST_Info() = default;
+
+ RST_Info(PackedSockAddr _addr, uint32 _connid, uint16 _ack_nr, uint64 _timestamp)
+ : addr{ _addr }
+ , connid{ _connid }
+ , ack_nr{ _ack_nr }
+ , timestamp{ _timestamp }
+ {
+ }
+
+ PackedSockAddr addr;
+ uint32 connid;
+ uint16 ack_nr;
+ uint64 timestamp;
+};
+
+struct UTPSocketKey {
+ PackedSockAddr addr;
+ uint32 recv_id; // "conn_seed", "conn_id"
+
+ UTPSocketKey(const PackedSockAddr& _addr, uint32 _recv_id) {
+ addr = _addr;
+ recv_id = _recv_id;
+ }
+
+ bool operator == (const UTPSocketKey &other) const {
+ return recv_id == other.recv_id && addr == other.addr;
+ }
+
+ uint32 compute_hash() const {
+ return recv_id ^ addr.compute_hash();
+ }
+};
+
+template<>
+struct std::hash<UTPSocketKey>
+{
+ // It's really important that we don't have duplicate keys in the hash table.
+ // If we do, we'll eventually crash. if we try to remove the second instance
+ // of the key, we'll accidentally remove the first instead. then later,
+ // checkTimeouts will try to access the second one's already freed memory.
+ std::size_t operator()(const UTPSocketKey& key) const {
+ return key.compute_hash();
+ }
+};
+
+extern void utp_socket_delete(UTPSocket*);
+
+// Container that owns a set of UTPSockets.
+// The sockets are destroyed when removed from the container.
+class UTPSocketHT {
+
+ // UTPSocket is an opaque type, so we can't use it for V.
+ // Instead, use a unique_ptr<> which deletes via `utp_socket_delete()`.
+ struct SocketDeleter {
+ void operator()(UTPSocket* conn) const noexcept {
+ utp_socket_delete(conn);
+ }
+ };
+
+public:
+ using Key = UTPSocketKey;
+ using Value = UTPSocket;
+ using V = std::unique_ptr<Value, SocketDeleter>;
+ using Map = std::unordered_map<Key, V>;
+
+ [[nodiscard]] auto contains(Key const& key)->bool const {
+ return map_.count(key) != 0U;
+ }
+
+ [[nodiscard]] auto size()->size_t const {
+ return map_.size();
+ }
+
+ [[nodiscard]] Value* lookup(Key const& key) const {
+ const auto iter = map_.find(key);
+ return iter != map_.end() ? iter->second.get() : nullptr;
+ }
+
+ void add(Key const& key, Value* value) {
+ map_[key].reset(value);
+ }
+
+ void erase_if(std::function<bool(Map::iterator const&)> pred) {
+ for (auto it = map_.begin(); it != map_.end(); ) {
+ if (pred(it)) {
+ it = map_.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+
+private:
+ Map map_;
+};
+
+struct struct_utp_context {
+ void *userdata;
+ utp_callback_t* callbacks[UTP_ARRAY_SIZE];
+
+ uint64 current_ms;
+ utp_context_stats context_stats;
+ UTPSocket *last_utp_socket;
+ std::vector<UTPSocket*> ack_sockets;
+ std::vector<RST_Info> rst_info;
+ UTPSocketHT utp_sockets;
+ size_t target_delay;
+ size_t opt_sndbuf;
+ size_t opt_rcvbuf;
+ uint64 last_check;
+
+ struct_utp_context();
+
+ void log(int level, utp_socket *socket, char const *fmt, ...);
+ void log_unchecked(utp_socket *socket, char const *fmt, ...);
+ bool would_log(int level);
+
+ bool log_normal:1; // log normal events?
+ bool log_mtu:1; // log MTU related events?
+ bool log_debug:1; // log debugging events? (Must also compile with UTP_DEBUG_LOGGING defined)
+};
+
+#endif //__UTP_INTERNAL_H__