1 // libTorrent - BitTorrent library
2 // Copyright (C) 2005-2011, Jari Sundell
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 //
18 // In addition, as a special exception, the copyright holders give
19 // permission to link the code of portions of this program with the
20 // OpenSSL library under certain conditions as described in each
21 // individual source file, and distribute linked combinations
22 // including the two.
23 //
24 // You must obey the GNU General Public License in all respects for
25 // all of the code used other than OpenSSL.  If you modify file(s)
26 // with this exception, you may extend this exception to your version
27 // of the file(s), but you are not obligated to do so.  If you do not
28 // wish to do so, delete this exception statement from your version.
29 // If you delete this exception statement from all source files in the
30 // program, then also delete it here.
31 //
32 // Contact:  Jari Sundell <jaris@ifi.uio.no>
33 //
34 //           Skomakerveien 33
35 //           3185 Skoppum, NORWAY
36 
37 // Add some helpfull words here.
38 
39 #ifndef LIBTORRENT_CONNECTION_MANAGER_H
40 #define LIBTORRENT_CONNECTION_MANAGER_H
41 
42 #include <list>
43 #include <arpa/inet.h>
44 #include <sys/types.h>
45 #include <netinet/in.h>
46 #include <netinet/in_systm.h>
47 #include <netinet/ip.h>
48 #include <sys/socket.h>
49 #include lt_tr1_functional
50 #include <torrent/common.h>
51 
52 namespace torrent {
53 
54 // Standard pair of up/down throttles.
55 // First element is upload throttle, second element is download throttle.
56 typedef std::pair<Throttle*, Throttle*> ThrottlePair;
57 
58 class LIBTORRENT_EXPORT ConnectionManager {
59 public:
60   typedef uint32_t size_type;
61   typedef uint16_t port_type;
62   typedef uint8_t  priority_type;
63 
64   static const priority_type iptos_default     = 0;
65   static const priority_type iptos_lowdelay    = IPTOS_LOWDELAY;
66   static const priority_type iptos_throughput  = IPTOS_THROUGHPUT;
67   static const priority_type iptos_reliability = IPTOS_RELIABILITY;
68 
69 #if defined IPTOS_MINCOST
70   static const priority_type iptos_mincost     = IPTOS_MINCOST;
71 #elif defined IPTOS_LOWCOST
72   static const priority_type iptos_mincost     = IPTOS_LOWCOST;
73 #else
74   static const priority_type iptos_mincost     = iptos_throughput;
75 #endif
76 
77   static const uint32_t encryption_none             = 0;
78   static const uint32_t encryption_allow_incoming   = (1 << 0);
79   static const uint32_t encryption_try_outgoing     = (1 << 1);
80   static const uint32_t encryption_require          = (1 << 2);
81   static const uint32_t encryption_require_RC4      = (1 << 3);
82   static const uint32_t encryption_enable_retry     = (1 << 4);
83   static const uint32_t encryption_prefer_plaintext = (1 << 5);
84 
85   // Internal to libtorrent.
86   static const uint32_t encryption_use_proxy        = (1 << 6);
87   static const uint32_t encryption_retrying         = (1 << 7);
88 
89   enum {
90     handshake_incoming           = 1,
91     handshake_outgoing           = 2,
92     handshake_outgoing_encrypted = 3,
93     handshake_outgoing_proxy     = 4,
94     handshake_success            = 5,
95     handshake_dropped            = 6,
96     handshake_failed             = 7,
97     handshake_retry_plaintext    = 8,
98     handshake_retry_encrypted    = 9
99   };
100 
101   typedef std::function<uint32_t (const sockaddr*)>     slot_filter_type;
102   typedef std::function<ThrottlePair (const sockaddr*)> slot_throttle_type;
103 
104   // The sockaddr argument in the result slot call is NULL if the resolve failed, and the int holds the errno.
105   typedef std::function<void (const sockaddr*, int)> slot_resolver_result_type;
106   typedef std::function<slot_resolver_result_type* (const char*, int, int, slot_resolver_result_type)> slot_resolver_type;
107 
108   ConnectionManager();
109   ~ConnectionManager();
110 
111   // Check that we have not surpassed the max number of open sockets
112   // and that we're allowed to connect to the socket address.
113   //
114   // Consider only checking max number of open sockets.
115   bool                can_connect() const;
116 
117   // Call this to keep the socket count up to date.
inc_socket_count()118   void                inc_socket_count()                      { m_size++; }
dec_socket_count()119   void                dec_socket_count()                      { m_size--; }
120 
size()121   size_type           size() const                            { return m_size; }
max_size()122   size_type           max_size() const                        { return m_maxSize; }
123 
priority()124   priority_type       priority() const                        { return m_priority; }
send_buffer_size()125   uint32_t            send_buffer_size() const                { return m_sendBufferSize; }
receive_buffer_size()126   uint32_t            receive_buffer_size() const             { return m_receiveBufferSize; }
encryption_options()127   uint32_t            encryption_options()                    { return m_encryptionOptions; }
128 
set_max_size(size_type s)129   void                set_max_size(size_type s)               { m_maxSize = s; }
set_priority(priority_type p)130   void                set_priority(priority_type p)           { m_priority = p; }
131   void                set_send_buffer_size(uint32_t s);
132   void                set_receive_buffer_size(uint32_t s);
133   void                set_encryption_options(uint32_t options);
134 
135   // Setting the addresses creates a copy of the address.
bind_address()136   const sockaddr*     bind_address() const                    { return m_bindAddress; }
local_address()137   const sockaddr*     local_address() const                   { return m_localAddress; }
proxy_address()138   const sockaddr*     proxy_address() const                   { return m_proxyAddress; }
139 
140   void                set_bind_address(const sockaddr* sa);
141   void                set_local_address(const sockaddr* sa);
142   void                set_proxy_address(const sockaddr* sa);
143 
144   uint32_t            filter(const sockaddr* sa);
set_filter(const slot_filter_type & s)145   void                set_filter(const slot_filter_type& s)   { m_slot_filter = s; }
146 
147   bool                listen_open(port_type begin, port_type end);
148   void                listen_close();
149 
150   // Since trackers need our port number, it doesn't get cleared after
151   // 'listen_close()'. The client may change the reported port number,
152   // but do note that it gets overwritten after 'listen_open(...)'.
listen_port()153   port_type           listen_port() const                     { return m_listen_port; }
listen_backlog()154   int                 listen_backlog() const                  { return m_listen_backlog; }
set_listen_port(port_type p)155   void                set_listen_port(port_type p)            { m_listen_port = p; }
156   void                set_listen_backlog(int v);
157 
158   // The resolver returns a pointer to its copy of the result slot
159   // which the caller may set blocked to prevent the slot from being
160   // called. The pointer must be NULL if the result slot was already
161   // called because the resolve was synchronous.
resolver()162   slot_resolver_type& resolver()          { return m_slot_resolver; }
163 
164   // The slot returns a ThrottlePair to use for the given address, or
165   // NULLs to use the default throttle.
address_throttle()166   slot_throttle_type& address_throttle()  { return m_slot_address_throttle; }
167 
168   // For internal usage.
listen()169   Listen*             listen()            { return m_listen; }
170 
171 private:
172   ConnectionManager(const ConnectionManager&);
173   void operator = (const ConnectionManager&);
174 
175   size_type           m_size;
176   size_type           m_maxSize;
177 
178   priority_type       m_priority;
179   uint32_t            m_sendBufferSize;
180   uint32_t            m_receiveBufferSize;
181   int                 m_encryptionOptions;
182 
183   sockaddr*           m_bindAddress;
184   sockaddr*           m_localAddress;
185   sockaddr*           m_proxyAddress;
186 
187   Listen*             m_listen;
188   port_type           m_listen_port;
189   uint32_t            m_listen_backlog;
190 
191   slot_filter_type    m_slot_filter;
192   slot_resolver_type  m_slot_resolver;
193   slot_throttle_type  m_slot_address_throttle;
194 };
195 
196 }
197 
198 #endif
199 
200