| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #pragma once |
| |
| #include "result.h" |
| |
| #include <netinet/in.h> |
| |
| #include <stdint.h> |
| #include <string> |
| |
| class Address; |
| class Message; |
| |
| class Socket { |
| public: |
| enum class Domain { |
| IpV4, |
| IpV6, |
| Packet, |
| }; |
| |
| enum class Type { |
| Stream, // A streaming protocol, use this with Infer for TCP |
| Datagram, // A datagram protocol, use this with Infer for UDP |
| Raw, // A raw socket |
| }; |
| enum class Protocol { |
| Infer, // Infer the protocol from the type, such as TCP for Stream |
| Ip, // Internet Protocol for raw sockets |
| IcmpV6, // ICMPv6 control protocol for Raw sockets |
| EthIpV6, // Ethernet packets containing IPV6, for packet sockets |
| }; |
| |
| // Construct an empty socket object, next use open() to start using it |
| Socket(); |
| // Move construct a socket, The constructed socket will be in the same state |
| // that |other| is. After this |other| will be in an undefined state and |
| // should no longer be used. |
| Socket(Socket&& other) noexcept; |
| ~Socket(); |
| |
| // Move the |other| socket object into this one. If this object has an open |
| // socket it will be closed first. After that this object will have the |
| // same state that |other| did. |other| will be left in an undefined state |
| // and should not be used. |
| Socket& operator=(Socket&& other) noexcept; |
| |
| int get() const { return mSocket; } |
| |
| Result open(int domain, int type, int protocol); |
| |
| /** Options, these must be called between open and bind **/ |
| |
| // Bind to a specific interface regardless of the address that the socket |
| // is going to bind to. |
| Result setInterface(const std::string& interface); |
| |
| // Set the hop limit for multicast traffic on the socket. Each router hop |
| // decreases this value by one, when it reaches zero the packet is |
| // discarded. |
| Result setMulticastHopLimit(int hopLimit); |
| |
| // Set the hop limit for unicast traffic on the socket. Each router hop |
| // decreases this value by one, when it reaches zero the packet is |
| // discarded. |
| Result setUnicastHopLimit(int hopLimit); |
| |
| // Configure the socket to be transparent. This allows packets sent to have |
| // a source address that is different from the network interface's source |
| // address. |
| Result setTransparent(bool transparent); |
| |
| /** Binding **/ |
| |
| Result bind(const Address& address); |
| |
| /** Sending and receiving **/ |
| |
| Result receive(Message* receivingMessage); |
| Result receiveFrom(Message* receivingMessage, Address* from); |
| |
| Result send(const void* data, size_t size); |
| |
| // Send a packet to a specific |destination| of any address type. |
| Result sendTo(const sockaddr& destination, |
| size_t destinationSize, |
| const void* data, |
| size_t size); |
| // Convenience function to send to a specific IPv6 address. |
| Result sendTo(const in6_addr& destination, const void* data, size_t size); |
| // Convenience method to use sendTo with a more specific sockaddr struct |
| // without having to specify the size or do the casting. |
| template<typename T> |
| Result sendTo(const T& destination, const void* data, size_t size) { |
| return sendTo(*reinterpret_cast<const sockaddr*>(&destination), |
| sizeof(destination), |
| data, |
| size); |
| } |
| |
| // Send a packet with a specific source IPv6 address to a given |
| // |destination|. Rewriting the source in this manner usually requires root. |
| Result sendFrom(const in6_addr& fromAddress, |
| const sockaddr& destination, |
| size_t destinationSize, |
| const void* data, |
| size_t size); |
| Result sendFrom(const in6_addr& fromAddress, |
| const in6_addr& destination, |
| const void* data, |
| size_t size); |
| // Convenience method to use sendFrom with a more specific sockaddr struct |
| // without having to specify the size or do the casting. |
| template<typename T> |
| Result sendFrom(const in6_addr& fromAddress, |
| const T& destination, |
| const void* data, |
| size_t size) { |
| return sendFrom(fromAddress, |
| *reinterpret_cast<const sockaddr*>(&destination), |
| sizeof(destination), |
| data, |
| size); |
| } |
| |
| private: |
| // No copy construction or assignment allowed, support move semantics only |
| Socket(const Socket&); |
| Socket& operator=(const Socket&); |
| |
| enum class State { |
| New, |
| Open, |
| Bound, |
| Moved, |
| Destructed, |
| }; |
| |
| State mState; |
| int mSocket; |
| }; |
| |