|
|
/* * $Id: tdsocket_h.html,v 1.6 2001/11/30 14:02:34 dreibh Exp $ * * SCTP implementation according to RFC 2960. * Copyright (C) 1999-2001 by Thomas Dreibholz * * Realized in co-operation between Siemens AG * and University of Essen, Institute of Computer Networking Technology. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * There are two mailinglists available at www.sctp.de which should be used for * any discussion related to this implementation. * * Contact: discussion@sctp.de * dreibh@exp-math.uni-essen.de * * Purpose: Socket Implementation * */ #ifndef TDSOCKET_H #define TDSOCKET_H #include "tdsystem.h" #include "internetaddress.h" #include "internetflow.h" #include "ext_socket.h" #include <fcntl.h> namespace Coral { /** * UDP header size. */ const cardinal UDPHeaderSize = 8; /** * IPv4 header size. */ const cardinal IPv4HeaderSize = 20; /** * IPv6 header size. */ const cardinal IPv6HeaderSize = 40; /** * This class manages a socket. IPv6 support is automatically available, * when supported by the system. * * @short Socket * @author Thomas Dreibholz (dreibh@exp-math.uni-essen.de) * @version 1.0 */ class Socket { // ====== Definitions ==================================================== public: enum SocketCommunicationDomain { UndefinedSocketCommunicationDomain = -1, IP = 255, IPv4 = AF_INET, // Do not use IPv4/IPv6, IPv6 = AF_INET6, // use IP instead! Unix = AF_UNIX }; enum SocketType { UndefinedSocketType = -1, UDP = SOCK_DGRAM, Datagram = SOCK_DGRAM, TCP = SOCK_STREAM, Stream = SOCK_STREAM, Raw = SOCK_RAW, RDM = SOCK_RDM, SeqPacket = SOCK_SEQPACKET }; enum SocketProtocol { UndefinedSocketProtocol = -1, Default = 0, ICMPv4 = IPPROTO_ICMP, ICMPv6 = IPPROTO_ICMPV6, SCTP = IPPROTO_SCTP }; enum GetSocketAddressFlags { GLAF_HideLoopback = (1 << 0), GLAF_HideLinkLocal = (1 << 1), GLAF_HideSiteLocal = (1 << 2), GLAF_HideLocal = GLAF_HideLoopback|GLAF_HideLinkLocal|GLAF_HideSiteLocal, GLAF_HideAnycast = (1 << 3), GLAF_HideMulticast = (1 << 4), GLAF_HideBroadcast = (1 << 5), GLAF_HideReserved = (1 << 6), GLAF_Default = GLAF_HideLoopback|GLAF_HideLinkLocal|GLAF_HideBroadcast|GLAF_HideMulticast|GLAF_HideAnycast }; // ====== Constructor/Destructor ========================================= /** * Constructor. */ Socket(); /** * Constructor for a new socket. For automatic usage of IPv6 when available, * set communication domain to IP. Use IPv4/IPv6 only if a special * protocol version is necessary! * The creation success can be checked using ready() method. * * @param communicationDomain Communication domain (e.g. IP). * @param socketType Socket type (e.g. TCP, UDP). * @param socketProtocol Socket protocol (e.g. Default). * * @see ready */ Socket(const integer communicationDomain, const integer socketType, const integer socketProtocol = Default); /** * Destructor. */ ~Socket(); // ====== Create/close socket ============================================ /** * Close existing socket and create new socket. For automatic usage of * IPv6 when available, set communication domain to IP. * Use IPv4/IPv6 only if a special protocol version is necessary! * * @param communicationDomain Communication domain (e.g. IP). * @param socketType Socket type (e.g. TCP, UDP). * @param socketProtocol Socket protocol (e.g. Default). * @return true, if creation was sucessful; false otherwise. */ bool create(const integer communicationDomain = IP, const integer socketType = TCP, const integer socketProtocol = Default); /** * Close socket. */ void close(); /** * Shutdown full-duplex connection partial or completely. * SHUT_RD - further receives will be disallowed. * SHUT_WR - further sends will be disallowed. * SHUT_RDWR - further sends and receives will be disallowed. * * @param shutdownLevel SHUT_RD, SHUT_WR, SHUT_RDWR. */ void shutdown(const cardinal shutdownLevel); // ====== Statistics functions =========================================== /** * Get number of bytes sent. * * @return Number of bytes sent. */ inline card64 getBytesSent() const; /** * Get number of bytes received. * * @return Number of bytes received. */ inline card64 getBytesReceived() const; /** * Reset number of bytes sent. */ inline void resetBytesSent(); /** * Reset number of bytes received. */ inline void resetBytesReceived(); // ====== Socket control functions ======================================= /** * Check, if socket is ready. * * @return true, if socket is ready; false otherwise. */ inline bool ready() const; /** * Bind socket to given address. If address is null address, then * INADDR_ANY and an automatically selected port will be used. * * @param address Socket address. * @return true on success; false otherwise. */ bool bind(const SocketAddress& address = InternetAddress()); /** * Bind socket to one or more given addresses. If no addresses are given, * INADDR_ANY and an automatically selected port will be used. * * @param addressArray Array of socket addresses. * @param addresses Number of addresses. * @return true on success; false otherwise. */ bool bindx(const SocketAddress** addressArray = NULL, const cardinal addresses = 0, const integer flags = 0); /** * Set socket to listen mode with given backlog (queue length for sockets * waiting for acception). * * @param backlog Backlog. * @return true on success; false otherwise. */ bool listen(const cardinal backlog = 5); /** * Accept a connection. * * @param address Reference to store SocketAddress object to with peer's address to (NULL to skip). * @return New socket. */ Socket* accept(SocketAddress** address = NULL); /** * Connect socket to given address. A value for traffic class is supported * if the connection is an IPv6 connection; otherwise it is ignored. * * @param address Address. * @param trafficClass Traffic class of the connection (IPv6 only!) * @return true on success; false otherwise. */ bool connect(const SocketAddress& address, const card8 trafficClass = 0); // ====== Error code ===================================================== /** * Get last error code. It will be reset to 0 after copying. * * @return Last error code. */ inline integer getLastError(); // ====== Socket options ================================================= /** * Get socket option (wrapper for getsockopt()); * * @param level Level (e.g. SOL_SOCKET). * @param optionNumber Option (e.g. SO_REUSEADDR). * @param optionValue Memory to store option got from getsockopt(). * @param optionLength Memory with size of option memory. * @return Result from getsockopt(). */ inline integer getSocketOption(const cardinal level, const cardinal optionNumber, void* optionValue, socklen_t* optionLength); /** * Get SO_LINGER option of socket. * * @return SO_LINGER value. */ cardinal getSoLinger(); /** * Get SO_REUSEADDR option of socket. * * @return SO_REUSEADDR value. */ bool getSoReuseAddress(); /** * Get SO_BROADCAST option of socket. * * @return SO_BROADCAST value. */ bool getSoBroadcast(); /** * Get TCP_NODELAY option of socket. * * @return TCP_NODELAY value. */ bool getTCPNoDelay(); /** * Check, if blocking mode is on. * * @return true, if blocking mode is on; false otherwise. */ bool getBlockingMode(); /** * Get socket option (wrapper for getsockopt()); * * @param level Level (e.g. SOL_SOCKET). * @param optionNumber Option (e.g. SO_REUSEADDR). * @param optionValue Memory with option. * @param optionLength Length of option memory. * @return Result from setsockopt(). */ inline integer setSocketOption(const cardinal level, const cardinal optionNumber, const void* optionValue, const socklen_t optionLength); /** * Set SO_LINGER option of socket. * * @param on true to set linger on; false otherwise. * @param linger SO_LINGER in seconds. * @return true for success; false otherwise. */ bool setSoLinger(const bool on, const cardinal linger); /** * Set SO_REUSEADDR option of socket. * * @param on true to set SO_REUSEADDR on; false otherwise. * @return true for success; false otherwise. */ bool setSoReuseAddress(const bool on); /** * Set SO_BROADCAST option of socket. * * @param on true to set SO_BROADCAST on; false otherwise. * @return true for success; false otherwise. */ bool setSoBroadcast(const bool on); /** * Set TCP_NODELAY option of socket. * * @param on true to set TCP_NODELAY on; false otherwise. * @return true for success; false otherwise. */ bool setTCPNoDelay(const bool on); /** * Set blocking mode. * * @param on True to set blocking mode, false to unset. * @param true for success; false otherwise. * @return true for success; false otherwise. */ bool setBlockingMode(const bool on); // ====== Get flow label/traffic class =================================== /** * Get flow label of the connection. * * @return Flow label of the connection or 0, if there is no flow label. * * @see connect */ inline card32 getSendFlowLabel() const; /** * Get traffic class of the connection. * * @return Traffic class of the connection or 0, if there is no traffic class. * * @see connect */ inline card8 getSendTrafficClass() const; /** * Get last received flow label. * * @return Last received flow label or 0, if there is no flow label. */ inline card32 getReceivedFlowLabel() const; /** * Get last received traffic class. * * @return Last received traffic class or 0, if there is no traffic class. */ inline card8 getReceivedTrafficClass() const; // ====== I/O functions ================================================== /** * Wrapper for send(). * send() will set the packet's traffic class, if trafficClass is not 0. * In this case, the packet will be sent by sendto() to the destination * address, the socket is connected to! * * @param buffer Buffer with data to send. * @param length Length of data to send. * @param flags Flags for sendto(). * @param trafficClass Traffic class for packet. * @return Bytes sent or error code < 0. */ ssize_t send(const void* buffer, const size_t length, const cardinal flags = 0, const card8 trafficClass = 0x00); /** * Wrapper for sendto(). * sendto() will set the packet's traffic class, if trafficClass is not 0. * * @param buffer Buffer with data to send. * @param length Length of data to send. * @param flags Flags for sendto(). * @param receiver Address of receiver. * @param trafficClass Traffic class for packet. * @return Bytes sent or error code < 0. */ ssize_t sendTo(const void* buffer, const size_t length, const cardinal flags, const SocketAddress& receiver, const card8 trafficClass = 0x00); /** * Wrapper for sendmsg(). * * @param msg Message. * @param flags Flags. * @param trafficClass Traffic class for packet. * @return Result of sendmsg() call. */ ssize_t sendMsg(const struct msghdr* msg, const cardinal flags, const card8 trafficClass = 0x00); /** * Wrapper for write(). * * @param buffer Buffer with data to write * @param length Length of data to write * @return Bytes sent or error code < 0. */ inline ssize_t write(const void* buffer, const size_t length); /** * Wrapper for recv(). * * @param buffer Buffer to read data to. * @param length Maximum length of data to be received. * @param flags Flags for recv(). * @return Bytes read or error code < 0. */ inline ssize_t receive(void* buffer, const size_t length, const cardinal flags = 0); /** * Wrapper for recvfrom(). * * @param buffer Buffer to receive data to. * @param length Maximum length of data to be received. * @param sender Address to store sender's address. * @param flags Flags for recvfrom(). * @return Bytes received or error code < 0. */ ssize_t receiveFrom(void* buffer, const size_t length, SocketAddress& sender, const cardinal flags = 0); /** * Wrapper for recvmsg(). * * @param msg Message. * @param flags Flags. * @param internalCall Internal usage only; set to false. * @return Result of recvmsg() call. */ ssize_t receiveMsg(struct msghdr* msg, const cardinal flags, const bool internalCall = false); /** * Wrapper for read(). * * @param buffer Buffer to read data to. * @param length Maximum length of data to be received. * @return Bytes read or error code < 0. */ inline ssize_t read(void* buffer, const size_t length); /** * Wrapper for fcntl(). * * @param cmd Command. * @param arg Argument. * @return Result of fcntl() call. */ inline integer fcntl(const integer cmd, long arg); /** * Wrapper for fcntl(). * * @param cmd Command. * @param arg Argument. * @param lock Lock. * @return Result of fcntl() call. */ inline integer fcntl(const integer cmd, long arg, struct flock* lock); /** * Wrapper for ioctl(). * * @param request Request. * @param argp Argument. * @return Result of ioctl() call. */ inline integer ioctl(const integer request, const void* argp); // ====== Get address ==================================================== /** * Get the socket's address. Note: A socket has to be bound to an address * and port or connected to a peer first to let the socket have an address! * * @param address Reference to SocketAddress to write address to. * @return true, if call was successful; false otherwise. * * @see bind * @see connect * @see getPeerAddress */ bool getSocketAddress(SocketAddress& address) const; /** * Get the peer's address. Note: A socket has to be connected to a peer * first to get a peer address! * * @param address Reference to SocketAddress to write address to. * @return true, if call was successful; false otherwise. * * @see bind * @see connect * @see getSocketAddress */ bool getPeerAddress(SocketAddress& address) const; // ====== Multicast functions ============================================ /** * Add multicast membership. * * @param address Multicast address. * @param interface Interface name. * @return true for success; false otherwise. */ inline bool addMulticastMembership(const SocketAddress& address, const char* interface = NULL); /** * Drop multicast membership. * * @param address Multicast address. * @param interface Interface name. * @return true for success; false otherwise. */ inline bool dropMulticastMembership(const SocketAddress& address, const char* interface = NULL); /** * Get multicast loop mode. * * @return true if multicast loop is enabled, false otherwise. */ bool getMulticastLoop(); /** * Set multicast loop mode. * * @param on true to enable, false to disable. * @return true for success; false otherwise. */ bool setMulticastLoop(const bool on); /** * Get multicast TTL. * * @return Multicast TTL. */ card8 getMulticastTTL(); /** * Set multicast TTL. * * @param ttl TTL. * @return true for success; false otherwise. */ bool setMulticastTTL(const card8 ttl); // ====== IPv6 flow functions ============================================ /** * Allocate a new flow to a given destination. A InternetFlow object is * returned, the value flow.getFlowLabel() will not be 0, if the allocFlow() * call was successful. * * @param address Address of the destination. * @param flowLabel Flowlabel; 0 for random value. * @param shareLevel Share level for flow label. * @return InternetFlow. */ InternetFlow allocFlow(const InternetAddress& address, const card32 flowLabel = 0, const card8 shareLevel = 2); /** * Free a flow. * * @param flow Flow to be freed. */ void freeFlow(InternetFlow& flow); /** * Renew a flow label allocation with given expires and linger * (default 6) values. The expires value gives the seconds to go * until the flow label expires, the linger value gives the timeout in * seconds the freed flow label cannot be allocated again. * * @param flow Flow to be renewed. * @param expires Seconds until the flow label expires. * @param linger Linger (default 6). * @return true on success; false otherwise. */ bool renewFlow(InternetFlow& flow, const cardinal expires, const cardinal linger = 6); /** * Renew current flow's flow label allocation with given expires and linger * (default 6) values. * * @param expires Seconds until the flow label expires. * @param linger Linger (default 6). * @return true on success; false otherwise. */ bool renewFlow(const cardinal expires, const cardinal linger = 6); // ====== Bind pair of internet sockets ================================== /** * Bind a pair of internet sockets to a given address and port number * x and x + 1. x will be a random number, if given port number is 0. * * @param senderSocket First socket. * @param receiverSocket Second socket. * @param receiver Address (e.g ipv6-localhost:0) or NULL for Any address. */ static bool bindInternetSocketPair(Socket& senderSocket, Socket& receiverSocket, const InternetAddress& receiver = InternetAddress()); // ====== Get system's socket descriptor ================================= /** * Get system's socket descriptor. * Warning: It is not recommended to manipulate the socket directly. * Use Socket's methods instead. * * @return Socket descriptor. */ inline int getSystemSocketDescriptor() const; // ====== Obtaining Local addresses ====================================== /** * Get list of all local addresses (IPv4 and IPv6 are currently supported). * The resulting list has to be deallocated using SocketAddress::deleteAddressList(). * * @param addressList Reference to store address list to. * @param numberOfNets Reference to store number of addresses to. * @param flags Flags. * @return true for success; false otherwise. * * @see SocketAddress#deleteAddressList */ static bool getLocalAddressList(SocketAddress**& addressList, cardinal& numberOfNets, const cardinal flags = GLAF_Default); // ====== Constants ====================================================== /** * Minimum port number for bind()'s automatic port selection. * * @see bind */ static const cardinal MinAutoSelectPort = 16384; /** * Maximum port number for bind()'s automatic port selection. * * @see bind */ static const cardinal MaxAutoSelectPort = 61000; // ====== Private data =================================================== protected: friend class TrafficShaper; void init(); bool setTypeOfService(const card8 trafficClass); ssize_t recvFrom(int fd, void* buf, const size_t len, const integer flags, struct sockaddr* addr, socklen_t* addrlen); bool multicastMembership(const SocketAddress& address, const char* interface, const bool add); card64 BytesSent; card64 BytesReceived; card32 SendFlow; card32 ReceivedFlow; cardinal Backlog; integer LastError; int SocketDescriptor; sockaddr* Destination; integer CommunicationDomain; integer Type; integer Protocol; }; } #include "tdsocket.icc" #endif
Generated by: dreibh@kappes on Fri Nov 30 14:03:21 2001, using kdoc 2.0a53. |