blob: 21b13f23ab6e5e493419084fae6e664d106fb8a1 [file] [log] [blame]
Alexander Afanasyeva9034b02014-01-26 18:32:02 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#ifndef NFD_FACE_TCP_FACE_HPP
8#define NFD_FACE_TCP_FACE_HPP
9
10#include "stream-face.hpp"
11
Alexander Afanasyev18bbf812014-01-29 01:40:23 -080012namespace nfd
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080013{
14
15/**
16 * \brief Implementation of Face abstraction that uses TCP
17 * as underlying transport mechanism
18 */
19class TcpFace : public StreamFace<boost::asio::ip::tcp>
20{
21public:
Alexander Afanasyevd32cb962014-01-28 12:43:47 -080022 typedef boost::asio::ip::tcp protocol;
23
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010024 explicit
Junxiao Shi8c8d2182014-01-30 22:33:00 -070025 TcpFace(const shared_ptr<protocol::socket>& socket);
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080026};
27
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080028//
29
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080030/**
31 * \brief Implementation of Face abstraction that uses TCP
32 * as underlying transport mechanism and is used for
33 * local communication (can enable LocalControlHeader)
34 */
35class TcpLocalFace : public StreamFace<boost::asio::ip::tcp, LocalFace>
36{
37public:
38 typedef boost::asio::ip::tcp protocol;
39
40 explicit
41 TcpLocalFace(const shared_ptr<protocol::socket>& socket);
42};
43
Alexander Afanasyev232c9872014-02-20 17:33:00 -080044//
45
46inline bool
47is_loopback(const boost::asio::ip::address& address)
48{
49#if BOOST_VERSION < 104700
50 if (address.is_v4())
51 {
52 return (address.to_v4().to_ulong() & 0xFF000000) == 0x7F000000;
53 }
54 else
55 {
56 boost::asio::ip::address_v6::bytes_type v6_addr = address.to_v6().to_bytes();
57 return ((v6_addr[0] == 0) && (v6_addr[1] == 0)
58 && (v6_addr[2] == 0) && (v6_addr[3] == 0)
59 && (v6_addr[4] == 0) && (v6_addr[5] == 0)
60 && (v6_addr[6] == 0) && (v6_addr[7] == 0)
61 && (v6_addr[8] == 0) && (v6_addr[9] == 0)
62 && (v6_addr[10] == 0) && (v6_addr[11] == 0)
63 && (v6_addr[12] == 0) && (v6_addr[13] == 0)
64 && (v6_addr[14] == 0) && (v6_addr[15] == 1));
65 }
66#else
67 return address.is_loopback();
68#endif
69}
70
71/** \brief Class validating use of TcpLocalFace
72 */
73template<>
74struct StreamFaceValidator<boost::asio::ip::tcp, LocalFace>
75{
76 /** Check that local endpoint is loopback
77 *
78 * @throws Face::Error if validation failed
79 */
80 static void
81 validateSocket(boost::asio::ip::tcp::socket& socket)
82 {
83 if (!is_loopback(socket.local_endpoint().address()) ||
84 !is_loopback(socket.remote_endpoint().address()))
85 {
86 throw Face::Error("TcpLocalFace can be created only on loopback interface");
87 }
88 }
89};
90
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080091
Alexander Afanasyev18bbf812014-01-29 01:40:23 -080092} // namespace nfd
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080093
94#endif // NFD_FACE_TCP_FACE_HPP