connection.h revision 6c72c972614285b2c01fb38afb2ffe06484a544a
1c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart// Use of this source code is governed by a BSD-style license that can be
3dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart// found in the LICENSE file.
4dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
5dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart#ifndef SHILL_CONNECTION_
6dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart#define SHILL_CONNECTION_
7dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
813e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov#include <deque>
9dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart#include <string>
10dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart#include <vector>
11dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
12dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart#include <base/memory/ref_counted.h>
1313e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov#include <base/memory/weak_ptr.h>
14dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart#include <gtest/gtest_prod.h>  // for FRIEND_TEST
15dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
164a6748d492214afcb7c484668fa8cfd3ad963f10Paul Stewart#include "shill/ip_address.h"
17e93b038972d43fd703b3c68603fb4d02bec6504ePaul Stewart#include "shill/ipconfig.h"
18dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart#include "shill/refptr_types.h"
19e00600e1ec769b3acf0709e843c1f0ae73bd2fdbPaul Stewart#include "shill/technology.h"
20dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
21dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewartnamespace shill {
22dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
239a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewartclass DeviceInfo;
2413e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkovclass RTNLHandler;
25dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewartclass Resolver;
26dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewartclass RoutingTable;
2713e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkovstruct RoutingTableEntry;
28dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
29dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart// The Conneciton maintains the implemented state of an IPConfig, e.g,
30dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart// the IP address, routing table and DNS table entries.
31dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewartclass Connection : public base::RefCounted<Connection> {
32dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart public:
3313e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  // Clients can instantiate and use Binder to bind to a Connection and get
3413e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  // notified when the bound Connection disconnects. Note that the client's
3513e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  // disconnect callback will be executed at most once, and only if the bound
3613e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  // Connection is destroyed or signals disconnect. The Binder unbinds itself
3713e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  // from the underlying Connection when the Binder instance is destructed.
3813e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  class Binder {
3913e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov   public:
4013e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov    Binder(const std::string &name, const base::Closure &disconnect_callback);
4113e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov    ~Binder();
4213e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
43ef1f9fec08b3a251a84ae3e4ef7ef15fdc2a1544Darin Petkov    // Binds to |to_connection|. Unbinds the previous bound connection, if
4413e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov    // any. Pass NULL to just unbind this Binder.
45ef1f9fec08b3a251a84ae3e4ef7ef15fdc2a1544Darin Petkov    void Attach(const ConnectionRefPtr &to_connection);
4613e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
475eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov    const std::string &name() const { return name_; }
4813e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov    bool IsBound() const { return connection_ != NULL; }
49ef1f9fec08b3a251a84ae3e4ef7ef15fdc2a1544Darin Petkov    ConnectionRefPtr connection() const { return connection_.get(); }
5013e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
5113e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov   private:
5213e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov    friend class Connection;
5313e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov    FRIEND_TEST(ConnectionTest, Binder);
5413e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
5513e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov    // Invoked by |connection_|.
5613e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov    void OnDisconnect();
5713e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
5813e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov    const std::string name_;
59ef1f9fec08b3a251a84ae3e4ef7ef15fdc2a1544Darin Petkov    base::WeakPtr<Connection> connection_;
6013e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov    const base::Closure client_disconnect_callback_;
6113e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
6213e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov    DISALLOW_COPY_AND_ASSIGN(Binder);
6313e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  };
6413e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
659a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  Connection(int interface_index,
669a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart             const std::string &interface_name,
67e00600e1ec769b3acf0709e843c1f0ae73bd2fdbPaul Stewart             Technology::Identifier technology_,
689a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart             const DeviceInfo *device_info);
69dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
70dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  // Add the contents of an IPConfig reference to the list of managed state.
71dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  // This will replace all previous state for this address family.
72c1dec4d5cad7c6ee2cd8dbc4f47e4d30403dcca1Paul Stewart  virtual void UpdateFromIPConfig(const IPConfigRefPtr &config);
73dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
74dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  // Sets the current connection as "default", i.e., routes and DNS entries
75dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  // should be used by all system components that don't select explicitly.
76c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart  virtual bool is_default() const { return is_default_; }
77c1dec4d5cad7c6ee2cd8dbc4f47e4d30403dcca1Paul Stewart  virtual void SetIsDefault(bool is_default);
78dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
79c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart  virtual const std::string &interface_name() const { return interface_name_; }
804a6748d492214afcb7c484668fa8cfd3ad963f10Paul Stewart  virtual int interface_index() const { return interface_index_; }
81c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart  virtual const std::vector<std::string> &dns_servers() const {
82c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart    return dns_servers_;
83c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart  }
84c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart
8510241e32c136ba99e7533ca1370e2e8eca241b7cPaul Stewart  virtual const std::string &ipconfig_rpc_identifier() const {
8610241e32c136ba99e7533ca1370e2e8eca241b7cPaul Stewart    return ipconfig_rpc_identifier_;
8710241e32c136ba99e7533ca1370e2e8eca241b7cPaul Stewart  }
8810241e32c136ba99e7533ca1370e2e8eca241b7cPaul Stewart
89c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart  // Request to accept traffic routed to this connection even if it is not
90c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart  // the default.  This request is ref-counted so the caller must call
91c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart  // ReleaseRouting() when they no longer need this facility.
92c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart  virtual void RequestRouting();
93c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart  virtual void ReleaseRouting();
94be5f5b341ba4b85d45ffb6c0430ef5ab84c7b961Paul Stewart
95f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart  // Request a host route through this connection.
96f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart  virtual bool RequestHostRoute(const IPAddress &destination);
97f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart
986c72c972614285b2c01fb38afb2ffe06484a544aPaul Stewart  virtual const IPAddress &local() const { return local_; }
996c72c972614285b2c01fb38afb2ffe06484a544aPaul Stewart  virtual const IPAddress &gateway() const { return gateway_; }
1006c72c972614285b2c01fb38afb2ffe06484a544aPaul Stewart
10113e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov protected:
10213e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  friend class base::RefCounted<Connection>;
10313e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
10413e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  virtual ~Connection();
1054a6748d492214afcb7c484668fa8cfd3ad963f10Paul Stewart  virtual bool CreateGatewayRoute();
10613e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
107dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart private:
108dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  friend class ConnectionTest;
109dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  FRIEND_TEST(ConnectionTest, AddConfig);
11013e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  FRIEND_TEST(ConnectionTest, Binder);
11113e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  FRIEND_TEST(ConnectionTest, Binders);
112dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  FRIEND_TEST(ConnectionTest, Destructor);
11353a303873f9a89ff0121777476d33afc9b77b987Paul Stewart  FRIEND_TEST(ConnectionTest, FixGatewayReachability);
1145b7ba8c2e9e5ab5e67c68d0cde963141beb501d8Paul Stewart  FRIEND_TEST(ConnectionTest, InitState);
11513e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  FRIEND_TEST(ConnectionTest, OnRouteQueryResponse);
11613e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  FRIEND_TEST(ConnectionTest, RequestHostRoute);
1175eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov  FRIEND_TEST(VPNServiceTest, OnConnectionDisconnected);
118dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
119dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  static const uint32 kDefaultMetric;
1207cfca0467e47aa91b485c485b92befb33a1fd61fPaul Stewart  static const uint32 kNonDefaultMetricBase;
1217cfca0467e47aa91b485c485b92befb33a1fd61fPaul Stewart
1225b7ba8c2e9e5ab5e67c68d0cde963141beb501d8Paul Stewart  // Work around misconfigured servers which provide a gateway address that
1235b7ba8c2e9e5ab5e67c68d0cde963141beb501d8Paul Stewart  // is unreachable with the provided netmask.
12453a303873f9a89ff0121777476d33afc9b77b987Paul Stewart  static bool FixGatewayReachability(IPAddress *local,
1254925829bd8be852a625086e3628a2fb89286ddd8Paul Stewart                                     IPAddress *peer,
1264925829bd8be852a625086e3628a2fb89286ddd8Paul Stewart                                     const IPAddress &gateway);
1277cfca0467e47aa91b485c485b92befb33a1fd61fPaul Stewart  uint32 GetMetric(bool is_default);
128e93b038972d43fd703b3c68603fb4d02bec6504ePaul Stewart  bool PinHostRoute(const IPConfig::Properties &config);
129dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
13013e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  void OnRouteQueryResponse(int interface_index,
13113e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov                            const RoutingTableEntry &entry);
13213e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
13313e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  void AttachBinder(Binder *binder);
13413e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  void DetachBinder(Binder *binder);
13513e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  void NotifyBindersOnDisconnect();
13613e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
13713e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  void OnLowerDisconnect();
13813e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
13913e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  base::WeakPtrFactory<Connection> weak_ptr_factory_;
14013e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
141dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  bool is_default_;
1424a6748d492214afcb7c484668fa8cfd3ad963f10Paul Stewart  bool has_broadcast_domain_;
143c8f4bef3c2a277d052f96ae06e67d3e7ab44a592Paul Stewart  int routing_request_count_;
144dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  int interface_index_;
145dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  const std::string interface_name_;
146e00600e1ec769b3acf0709e843c1f0ae73bd2fdbPaul Stewart  Technology::Identifier technology_;
147dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  std::vector<std::string> dns_servers_;
148dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  std::vector<std::string> dns_domain_search_;
14910241e32c136ba99e7533ca1370e2e8eca241b7cPaul Stewart  std::string ipconfig_rpc_identifier_;
1504a6748d492214afcb7c484668fa8cfd3ad963f10Paul Stewart  IPAddress local_;
1514a6748d492214afcb7c484668fa8cfd3ad963f10Paul Stewart  IPAddress gateway_;
152dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
15313e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  // A binder to a lower Connection that this Connection depends on, if any.
15413e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  Binder lower_binder_;
15513e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
15613e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  // Binders to clients -- usually to upper connections or related services and
15713e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  // devices.
15813e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov  std::deque<Binder *> binders_;
15913e6d55b9dd86148ae68588f367c48e81ad33b74Darin Petkov
160dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  // Store cached copies of singletons for speed/ease of testing
1619a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  const DeviceInfo *device_info_;
162dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  Resolver *resolver_;
163dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  RoutingTable *routing_table_;
164dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  RTNLHandler *rtnl_handler_;
165dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
166dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart  DISALLOW_COPY_AND_ASSIGN(Connection);
167dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart};
168dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
169dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart}  // namespace shill
170dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart
171dd60e4549cc8898f7f517283eacc58f67570bd1fPaul Stewart#endif  // SHILL_CONNECTION_
172