blob: 6ced20b380f8bc3b9296e0b4ce2861bd961ee994 [file] [log] [blame]
Paul Stewartc681fa02012-03-02 19:40:04 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Paul Stewartdd60e452011-08-08 11:38:36 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef SHILL_CONNECTION_
6#define SHILL_CONNECTION_
7
Darin Petkov13e6d552012-05-09 14:22:23 +02008#include <deque>
Paul Stewartdd60e452011-08-08 11:38:36 -07009#include <string>
10#include <vector>
11
12#include <base/memory/ref_counted.h>
Darin Petkov13e6d552012-05-09 14:22:23 +020013#include <base/memory/weak_ptr.h>
Paul Stewartdd60e452011-08-08 11:38:36 -070014#include <gtest/gtest_prod.h> // for FRIEND_TEST
15
Paul Stewart4a6748d2012-07-17 14:31:36 -070016#include "shill/ip_address.h"
Paul Stewarte93b0382012-04-24 13:11:28 -070017#include "shill/ipconfig.h"
Paul Stewartdd60e452011-08-08 11:38:36 -070018#include "shill/refptr_types.h"
Paul Stewartbf667612012-06-29 14:49:54 -070019#include "shill/resolver.h"
Paul Stewarte00600e2012-03-16 07:08:00 -070020#include "shill/technology.h"
Paul Stewartdd60e452011-08-08 11:38:36 -070021
22namespace shill {
23
Paul Stewart9a908082011-08-31 12:18:48 -070024class DeviceInfo;
Darin Petkov13e6d552012-05-09 14:22:23 +020025class RTNLHandler;
Paul Stewartdd60e452011-08-08 11:38:36 -070026class RoutingTable;
Darin Petkov13e6d552012-05-09 14:22:23 +020027struct RoutingTableEntry;
Paul Stewartdd60e452011-08-08 11:38:36 -070028
29// The Conneciton maintains the implemented state of an IPConfig, e.g,
30// the IP address, routing table and DNS table entries.
31class Connection : public base::RefCounted<Connection> {
32 public:
Darin Petkov13e6d552012-05-09 14:22:23 +020033 // Clients can instantiate and use Binder to bind to a Connection and get
34 // notified when the bound Connection disconnects. Note that the client's
35 // disconnect callback will be executed at most once, and only if the bound
36 // Connection is destroyed or signals disconnect. The Binder unbinds itself
37 // from the underlying Connection when the Binder instance is destructed.
38 class Binder {
39 public:
40 Binder(const std::string &name, const base::Closure &disconnect_callback);
41 ~Binder();
42
Darin Petkovef1f9fe2012-05-11 16:51:52 +020043 // Binds to |to_connection|. Unbinds the previous bound connection, if
Darin Petkov13e6d552012-05-09 14:22:23 +020044 // any. Pass NULL to just unbind this Binder.
Darin Petkovef1f9fe2012-05-11 16:51:52 +020045 void Attach(const ConnectionRefPtr &to_connection);
Darin Petkov13e6d552012-05-09 14:22:23 +020046
Darin Petkov5eb05422012-05-11 15:45:25 +020047 const std::string &name() const { return name_; }
Darin Petkov13e6d552012-05-09 14:22:23 +020048 bool IsBound() const { return connection_ != NULL; }
Darin Petkovef1f9fe2012-05-11 16:51:52 +020049 ConnectionRefPtr connection() const { return connection_.get(); }
Darin Petkov13e6d552012-05-09 14:22:23 +020050
51 private:
52 friend class Connection;
53 FRIEND_TEST(ConnectionTest, Binder);
54
55 // Invoked by |connection_|.
56 void OnDisconnect();
57
58 const std::string name_;
Darin Petkovef1f9fe2012-05-11 16:51:52 +020059 base::WeakPtr<Connection> connection_;
Darin Petkov13e6d552012-05-09 14:22:23 +020060 const base::Closure client_disconnect_callback_;
61
62 DISALLOW_COPY_AND_ASSIGN(Binder);
63 };
64
Paul Stewart9a908082011-08-31 12:18:48 -070065 Connection(int interface_index,
66 const std::string &interface_name,
Paul Stewarte00600e2012-03-16 07:08:00 -070067 Technology::Identifier technology_,
Paul Stewartbf667612012-06-29 14:49:54 -070068 const DeviceInfo *device_info,
69 bool is_short_dns_timeout_enabled);
Paul Stewartdd60e452011-08-08 11:38:36 -070070
71 // Add the contents of an IPConfig reference to the list of managed state.
72 // This will replace all previous state for this address family.
Paul Stewartc1dec4d2011-12-08 15:25:28 -080073 virtual void UpdateFromIPConfig(const IPConfigRefPtr &config);
Paul Stewartdd60e452011-08-08 11:38:36 -070074
Paul Stewartdf3c0a82012-11-09 15:54:33 -080075 // Return the connection used by the lower binder.
76 virtual ConnectionRefPtr GetLowerConnection() const {
77 return lower_binder_.connection();
78 }
79
Paul Stewartdd60e452011-08-08 11:38:36 -070080 // Sets the current connection as "default", i.e., routes and DNS entries
81 // should be used by all system components that don't select explicitly.
Paul Stewartc681fa02012-03-02 19:40:04 -080082 virtual bool is_default() const { return is_default_; }
Paul Stewartc1dec4d2011-12-08 15:25:28 -080083 virtual void SetIsDefault(bool is_default);
Paul Stewartdd60e452011-08-08 11:38:36 -070084
Paul Stewartc8f4bef2011-12-13 09:45:51 -080085 virtual const std::string &interface_name() const { return interface_name_; }
Paul Stewart4a6748d2012-07-17 14:31:36 -070086 virtual int interface_index() const { return interface_index_; }
Paul Stewartc8f4bef2011-12-13 09:45:51 -080087 virtual const std::vector<std::string> &dns_servers() const {
88 return dns_servers_;
89 }
90
Paul Stewart10241e32012-04-23 18:15:06 -070091 virtual const std::string &ipconfig_rpc_identifier() const {
92 return ipconfig_rpc_identifier_;
93 }
94
Paul Stewartc8f4bef2011-12-13 09:45:51 -080095 // Request to accept traffic routed to this connection even if it is not
96 // the default. This request is ref-counted so the caller must call
97 // ReleaseRouting() when they no longer need this facility.
98 virtual void RequestRouting();
99 virtual void ReleaseRouting();
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800100
Paul Stewartf748a362012-03-07 12:01:20 -0800101 // Request a host route through this connection.
102 virtual bool RequestHostRoute(const IPAddress &destination);
103
Paul Stewart6c72c972012-07-27 11:29:20 -0700104 virtual const IPAddress &local() const { return local_; }
105 virtual const IPAddress &gateway() const { return gateway_; }
Paul Stewartff845fc2012-08-07 07:28:44 -0700106 Technology::Identifier technology() const { return technology_; }
Paul Stewart6c72c972012-07-27 11:29:20 -0700107
Darin Petkov13e6d552012-05-09 14:22:23 +0200108 protected:
109 friend class base::RefCounted<Connection>;
110
111 virtual ~Connection();
Paul Stewart4a6748d2012-07-17 14:31:36 -0700112 virtual bool CreateGatewayRoute();
Darin Petkov13e6d552012-05-09 14:22:23 +0200113
Paul Stewartdd60e452011-08-08 11:38:36 -0700114 private:
115 friend class ConnectionTest;
Paul Stewartdd60e452011-08-08 11:38:36 -0700116 FRIEND_TEST(ConnectionTest, AddConfig);
Darin Petkov13e6d552012-05-09 14:22:23 +0200117 FRIEND_TEST(ConnectionTest, Binder);
118 FRIEND_TEST(ConnectionTest, Binders);
Paul Stewartdd60e452011-08-08 11:38:36 -0700119 FRIEND_TEST(ConnectionTest, Destructor);
Paul Stewart53a30382012-04-26 09:06:59 -0700120 FRIEND_TEST(ConnectionTest, FixGatewayReachability);
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700121 FRIEND_TEST(ConnectionTest, InitState);
Darin Petkov13e6d552012-05-09 14:22:23 +0200122 FRIEND_TEST(ConnectionTest, OnRouteQueryResponse);
123 FRIEND_TEST(ConnectionTest, RequestHostRoute);
Ben Chana0163122012-09-25 15:10:52 -0700124 FRIEND_TEST(ConnectionTest, BlackholeIPv6);
Darin Petkov5eb05422012-05-11 15:45:25 +0200125 FRIEND_TEST(VPNServiceTest, OnConnectionDisconnected);
Paul Stewartdd60e452011-08-08 11:38:36 -0700126
127 static const uint32 kDefaultMetric;
Paul Stewart7cfca042011-12-08 14:18:17 -0800128 static const uint32 kNonDefaultMetricBase;
129
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700130 // Work around misconfigured servers which provide a gateway address that
131 // is unreachable with the provided netmask.
Paul Stewart53a30382012-04-26 09:06:59 -0700132 static bool FixGatewayReachability(IPAddress *local,
Paul Stewart49258292012-05-26 06:37:14 -0700133 IPAddress *peer,
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800134 IPAddress *gateway,
135 const IPAddress &trusted_ip);
Paul Stewart7cfca042011-12-08 14:18:17 -0800136 uint32 GetMetric(bool is_default);
Paul Stewart73fcc3f2013-02-25 12:16:53 -0800137 bool PinHostRoute(const IPAddress &trusted_ip, const IPAddress &gateway);
Paul Stewartdd60e452011-08-08 11:38:36 -0700138
Darin Petkov13e6d552012-05-09 14:22:23 +0200139 void OnRouteQueryResponse(int interface_index,
140 const RoutingTableEntry &entry);
141
142 void AttachBinder(Binder *binder);
143 void DetachBinder(Binder *binder);
144 void NotifyBindersOnDisconnect();
145
146 void OnLowerDisconnect();
147
Paul Stewart6f65c0b2012-09-11 14:57:32 -0700148 // Send our DNS configuration to the resolver.
149 void PushDNSConfig();
150
Darin Petkov13e6d552012-05-09 14:22:23 +0200151 base::WeakPtrFactory<Connection> weak_ptr_factory_;
152
Paul Stewartdd60e452011-08-08 11:38:36 -0700153 bool is_default_;
Paul Stewart4a6748d2012-07-17 14:31:36 -0700154 bool has_broadcast_domain_;
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800155 int routing_request_count_;
Paul Stewartdd60e452011-08-08 11:38:36 -0700156 int interface_index_;
157 const std::string interface_name_;
Paul Stewarte00600e2012-03-16 07:08:00 -0700158 Technology::Identifier technology_;
Paul Stewartdd60e452011-08-08 11:38:36 -0700159 std::vector<std::string> dns_servers_;
160 std::vector<std::string> dns_domain_search_;
Paul Stewartd62d6032012-09-11 11:35:49 -0700161 std::string dns_domain_name_;
Paul Stewart10241e32012-04-23 18:15:06 -0700162 std::string ipconfig_rpc_identifier_;
Paul Stewart4a6748d2012-07-17 14:31:36 -0700163 IPAddress local_;
164 IPAddress gateway_;
Paul Stewartdd60e452011-08-08 11:38:36 -0700165
Darin Petkov13e6d552012-05-09 14:22:23 +0200166 // A binder to a lower Connection that this Connection depends on, if any.
167 Binder lower_binder_;
168
169 // Binders to clients -- usually to upper connections or related services and
170 // devices.
171 std::deque<Binder *> binders_;
172
Paul Stewartbf667612012-06-29 14:49:54 -0700173 // Keep track of what sort of DNS timeout to use for this connection.
174 Resolver::TimeoutParameters dns_timeout_parameters_;
175
Paul Stewartdd60e452011-08-08 11:38:36 -0700176 // Store cached copies of singletons for speed/ease of testing
Paul Stewart9a908082011-08-31 12:18:48 -0700177 const DeviceInfo *device_info_;
Paul Stewartdd60e452011-08-08 11:38:36 -0700178 Resolver *resolver_;
179 RoutingTable *routing_table_;
180 RTNLHandler *rtnl_handler_;
181
182 DISALLOW_COPY_AND_ASSIGN(Connection);
183};
184
185} // namespace shill
186
187#endif // SHILL_CONNECTION_