|
|
// ########################################################################## // #### #### // #### RTP Audio Server Project #### // #### ============================ #### // #### #### // #### Socket #### // #### #### // #### Version 1.00 -- February 04, 2001 #### // #### #### // #### Copyright (C) 1999 Thomas Dreibholz #### // #### 2000 Universität Bonn, Abt. IV #### // #### 2001 EMail: Dreibholz@bigfoot.com #### // #### WWW: http://www.bigfoot.com/~dreibholz #### // #### #### // ########################################################################## #ifndef SOCKETCLASS_H #define SOCKETCLASS_H #include "system.h" #include "internetaddress.h" #include "internetflow.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 (Dreibholz@bigfoot.com) * @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 }; // ====== 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 SocketCommunicationDomain communicationDomain, const SocketType socketType, const SocketProtocol socketProtocol = Default); /** * Destructor. */ virtual ~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 SocketCommunicationDomain communicationDomain = IP, const SocketType socketType = TCP, const SocketProtocol 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()); /** * 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. * * @return New socket. */ Socket* accept(); /** * 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) const; /** * Get SO_LINGER option of socket. * * @return SO_LINGER value. */ cardinal getSoLinger() const; /** * Get SO_REUSEADDR option of socket. * * @return SO_REUSEADDR value. */ bool getSoReuseAddress() const; /** * Get SO_BROADCAST option of socket. * * @return SO_BROADCAST value. */ bool getSoBroadcast() const; /** * Get TCP_NODELAY option of socket. * * @return TCP_NODELAY value. */ bool getTCPNoDelay() const; /** * 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. */ void setSoLinger(const bool on, const cardinal linger); /** * Set SO_REUSEADDR option of socket. * * @param on true to set SO_REUSEADDR on; false otherwise. */ void setSoReuseAddress(const bool on); /** * Set SO_BROADCAST option of socket. * * @param on true to set SO_BROADCAST on; false otherwise. */ void setSoBroadcast(const bool on); /** * Set TCP_NODELAY option of socket. * * @param on true to set TCP_NODELAY on; false otherwise. */ void setTCPNoDelay(const bool on); /** * Set blocking mode. * * @param on True to set blocking mode, false to unset. */ void 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 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. * @return Bytes sent or error code < 0. */ virtual ssize_t sendTo(const void* buffer, const size_t length, const cardinal flags, const SocketAddress& receiver, const card8 trafficClass = 0); /** * 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. */ virtual ssize_t send(const void* buffer, const size_t length, const cardinal flags = 0, const card8 trafficClass = 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. */ virtual ssize_t receiveFrom(void* buffer, const size_t length, SocketAddress& sender, const cardinal flags = 0); /** * 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. */ virtual ssize_t receive(void* buffer, const size_t length, const cardinal flags = 0); /** * 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. */ virtual ssize_t read(void* buffer, const size_t length); /** * Wrapper for write(). * * @param buffer Buffer with data to write * @param length Length of data to write * @return Bytes sent or error code < 0. */ virtual ssize_t write(const 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, const long arg = 0); /** * 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; // ====== 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 = IPV6_FL_S_PROCESS); /** * 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()); // ====== Traffic shaper methods ========================================= /** * Set traffic constraint to given byte rate. Packets exceeding the given * constraint will be dropped. Note: This functionality has to be * implemented by subclasses! * * @param trafficClass Traffic class. * @param bandwidth Bandwidth. * @param bufferDelay Maximum buffer delay in microseconds. */ virtual void setTrafficConstraint(const card8 trafficClass, const card64 bandwidth, const double bufferDelay); /** * Flush traffic shaper buffer. Note: This functionality has to be * implemented by subclasses! */ virtual void flush(); // ====== 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; // ====== 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 = 65535; // ====== Private data =================================================== protected: friend class TrafficShaper; void init(); bool setTOS(const card8 trafficClass); ssize_t recvFrom(int fd, void* buf, const size_t len, const integer flags, struct sockaddr* addr, size_t* addrlen); card64 BytesSent; card64 BytesReceived; card32 SendFlow; card32 ReceivedFlow; cardinal Backlog; cardinal LastError; int SocketDescriptor; sockaddr* Destination; SocketCommunicationDomain CommunicationDomain; SocketType Type; SocketProtocol Protocol; }; } #include "socket.icc" #endif
Generated by: viper@odin on Sun Feb 4 18:54:51 2001, using kdoc 2.0a22. |