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