• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include "result.h"
19 
20 #include <netinet/in.h>
21 
22 #include <stdint.h>
23 #include <string>
24 
25 class Address;
26 class Message;
27 
28 class Socket {
29 public:
30     enum class Domain {
31         IpV4,
32         IpV6,
33         Packet,
34     };
35 
36     enum class Type {
37         Stream,   // A streaming protocol, use this with Infer for TCP
38         Datagram, // A datagram protocol, use this with Infer for UDP
39         Raw,      // A raw socket
40     };
41     enum class Protocol {
42         Infer,    // Infer the protocol from the type, such as TCP for Stream
43         Ip,       // Internet Protocol for raw sockets
44         IcmpV6,   // ICMPv6 control protocol for Raw sockets
45         EthIpV6,  // Ethernet packets containing IPV6, for packet sockets
46     };
47 
48     // Construct an empty socket object, next use open() to start using it
49     Socket();
50     // Move construct a socket, The constructed socket will be in the same state
51     // that |other| is. After this |other| will be in an undefined state and
52     // should no longer be used.
53     Socket(Socket&& other) noexcept;
54     ~Socket();
55 
56     // Move the |other| socket object into this one. If this object has an open
57     // socket it will be closed first. After that this object will have the
58     // same state that |other| did. |other| will be left in an undefined state
59     // and should not be used.
60     Socket& operator=(Socket&& other) noexcept;
61 
get()62     int get() const { return mSocket; }
63 
64     Result open(int domain, int type, int protocol);
65 
66     /** Options, these must be called between open and bind **/
67 
68     // Bind to a specific interface regardless of the address that the socket
69     // is going to bind to.
70     Result setInterface(const std::string& interface);
71 
72     // Set the hop limit for multicast traffic on the socket. Each router hop
73     // decreases this value by one, when it reaches zero the packet is
74     // discarded.
75     Result setMulticastHopLimit(int hopLimit);
76 
77     // Set the hop limit for unicast traffic on the socket. Each router hop
78     // decreases this value by one, when it reaches zero the packet is
79     // discarded.
80     Result setUnicastHopLimit(int hopLimit);
81 
82     // Configure the socket to be transparent. This allows packets sent to have
83     // a source address that is different from the network interface's source
84     // address.
85     Result setTransparent(bool transparent);
86 
87     /** Binding **/
88 
89     Result bind(const Address& address);
90 
91     /** Sending and receiving **/
92 
93     Result receive(Message* receivingMessage);
94     Result receiveFrom(Message* receivingMessage, Address* from);
95 
96     Result send(const void* data, size_t size);
97 
98     // Send a packet to a specific |destination| of any address type.
99     Result sendTo(const sockaddr& destination,
100                   size_t destinationSize,
101                   const void* data,
102                   size_t size);
103     // Convenience function to send to a specific IPv6 address.
104     Result sendTo(const in6_addr& destination, const void* data, size_t size);
105     // Convenience method to use sendTo with a more specific sockaddr struct
106     // without having to specify the size or do the casting.
107     template<typename T>
sendTo(const T & destination,const void * data,size_t size)108     Result sendTo(const T& destination, const void* data, size_t size) {
109         return sendTo(*reinterpret_cast<const sockaddr*>(&destination),
110                       sizeof(destination),
111                       data,
112                       size);
113     }
114 
115     // Send a packet with a specific source IPv6 address to a given
116     // |destination|. Rewriting the source in this manner usually requires root.
117     Result sendFrom(const in6_addr& fromAddress,
118                     const sockaddr& destination,
119                     size_t destinationSize,
120                     const void* data,
121                     size_t size);
122     Result sendFrom(const in6_addr& fromAddress,
123                     const in6_addr& destination,
124                     const void* data,
125                     size_t size);
126     // Convenience method to use sendFrom with a more specific sockaddr struct
127     // without having to specify the size or do the casting.
128     template<typename T>
sendFrom(const in6_addr & fromAddress,const T & destination,const void * data,size_t size)129     Result sendFrom(const in6_addr& fromAddress,
130                     const T& destination,
131                     const void* data,
132                     size_t size) {
133         return sendFrom(fromAddress,
134                         *reinterpret_cast<const sockaddr*>(&destination),
135                         sizeof(destination),
136                         data,
137                         size);
138     }
139 
140 private:
141     // No copy construction or assignment allowed, support move semantics only
142     Socket(const Socket&);
143     Socket& operator=(const Socket&);
144 
145     enum class State {
146         New,
147         Open,
148         Bound,
149         Moved,
150         Destructed,
151     };
152 
153     State mState;
154     int mSocket;
155 };
156 
157