diff options
Diffstat (limited to '')
-rw-r--r-- | include/osl/socket.h | 862 | ||||
-rw-r--r-- | include/osl/socket.hxx | 571 |
2 files changed, 1433 insertions, 0 deletions
diff --git a/include/osl/socket.h b/include/osl/socket.h new file mode 100644 index 000000000..7f87da312 --- /dev/null +++ b/include/osl/socket.h @@ -0,0 +1,862 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +/* + * This file is part of LibreOffice published API. + */ + +#ifndef INCLUDED_OSL_SOCKET_H +#define INCLUDED_OSL_SOCKET_H + +#include "rtl/ustring.h" +#include "osl/time.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* error returns */ +#define OSL_INADDR_NONE 0xffffffff +#define OSL_INVALID_PORT (-1) + +/**@{ begin section types +*/ + +/** + Opaque datatype SocketAddr. +*/ +typedef struct oslSocketAddrImpl * oslSocketAddr; + +/** + Represents the address-family of a socket +*/ +typedef enum { + osl_Socket_FamilyInet, /*!< IP (AF_INET) */ + osl_Socket_FamilyIpx, /*!< Novell IPX/SPX (AF_IPX) */ + osl_Socket_FamilyInvalid, /*!< always last entry in enum! */ + osl_Socket_Family_FORCE_EQUAL_SIZE = SAL_MAX_ENUM +} oslAddrFamily; + +/** + represent a specific protocol within an address-family +*/ +typedef enum { + osl_Socket_ProtocolIp, /*!< for all af_inet */ + osl_Socket_ProtocolIpx, /*!< af_ipx datagram sockets (IPX) */ + osl_Socket_ProtocolSpx, /*!< af_ipx seqpacket or stream for SPX */ + osl_Socket_ProtocolSpxII, /*!< af_ipx seqpacket or stream for SPX II */ + osl_Socket_ProtocolInvalid, /*!< always last entry in enum */ + osl_Socket_Protocol_FORCE_EQUAL_SIZE = SAL_MAX_ENUM +} oslProtocol; + +/** + Represents the type of a socket +*/ +typedef enum { + osl_Socket_TypeStream, /*!< stream socket */ + osl_Socket_TypeDgram, /*!< datagram socket */ + osl_Socket_TypeRaw, /*!< raw socket */ + osl_Socket_TypeRdm, /*!< connectionless, message-oriented, + reliably delivered message (RDM) + sockets */ + osl_Socket_TypeSeqPacket, /*!< connection-oriented and reliable + two-way transport of ordered byte + streams */ + osl_Socket_TypeInvalid, /*!< always last entry in enum */ + osl_Socket_Type_FORCE_EQUAL_SIZE = SAL_MAX_ENUM +} oslSocketType; + + +/** + Represents socket-options +*/ +typedef enum { + osl_Socket_OptionDebug, /*!< record debugging info */ + osl_Socket_OptionAcceptConn, /*!< listen for connection */ + osl_Socket_OptionReuseAddr, /*!< bind to address already in use */ + osl_Socket_OptionKeepAlive, /*!< use keep-alive */ + osl_Socket_OptionDontRoute, /*!< do not route packet, send direct to + interface addresses */ + osl_Socket_OptionBroadcast, /*!< send broadcast message */ + osl_Socket_OptionUseLoopback, /*!< socket receives copy of everything + sent on the socket */ + osl_Socket_OptionLinger, /*!< don't immediately close - "linger" + a while to allow for graceful + connection closure */ + osl_Socket_OptionOOBinLine, /*!< out-of-band (OOB) data placed in + normal input queue (i.e. OOB inline) */ + osl_Socket_OptionSndBuf, /*!< send buffer */ + osl_Socket_OptionRcvBuf, /*!< receive buffer */ + osl_Socket_OptionSndLowat, /*!< send "low-water" mark - amount of + available space in send buffer for + select() to return "writable" */ + osl_Socket_OptionRcvLowat, /*!< receive "low-water" mark - amount of + available space in receive buffer + for select() to receive "readable" */ + osl_Socket_OptionSndTimeo, /*!< send timeout */ + osl_Socket_OptionRcvTimeo, /*!< receive timeout */ + osl_Socket_OptionError, /*!< socket error */ + osl_Socket_OptionType, /*!< returns socket type (e.g. datagram, + stream). */ + osl_Socket_OptionTcpNoDelay, /*!< disable TCP Nagle algorithm */ + osl_Socket_OptionInvalid, /*!< always last entry in enum */ + osl_Socket_Option_FORCE_EQUAL_SIZE = SAL_MAX_ENUM +} oslSocketOption; + +/** + Represents the different socket-option levels +*/ +typedef enum { + osl_Socket_LevelSocket, + osl_Socket_LevelTcp, + osl_Socket_LevelInvalid, /*!< always last entry in enum */ + osl_Socket_Level_FORCE_EQUAL_SIZE = SAL_MAX_ENUM +} oslSocketOptionLevel; + +/** + Represents flags to be used with send/recv-calls. +*/ +typedef enum { + osl_Socket_MsgNormal, + osl_Socket_MsgOOB, + osl_Socket_MsgPeek, + osl_Socket_MsgDontRoute, + osl_Socket_MsgMaxIOVLen, + osl_Socket_MsgInvalid, /*!< always last entry in enum */ + osl_Socket_Msg_FORCE_EQUAL_SIZE = SAL_MAX_ENUM +} oslSocketMsgFlag; + +/** + Used by shutdown to denote which end of the socket to "close". +*/ +typedef enum { + osl_Socket_DirRead, + osl_Socket_DirWrite, + osl_Socket_DirReadWrite, + osl_Socket_DirInvalid, /*!< always last entry in enum */ + osl_Socket_Dir_FORCE_EQUAL_SIZE = SAL_MAX_ENUM +} oslSocketDirection; + +/** Describes the various error socket error conditions, which may + occur */ +typedef enum { + osl_Socket_E_None, /*!< no error */ + osl_Socket_E_NotSocket, /*!< Socket operation on non-socket */ + osl_Socket_E_DestAddrReq, /*!< Destination address required */ + osl_Socket_E_MsgSize, /*!< Message too long */ + osl_Socket_E_Prototype, /*!< Protocol wrong type for socket */ + osl_Socket_E_NoProtocol, /*!< Protocol not available */ + osl_Socket_E_ProtocolNoSupport, /*!< Protocol not supported */ + osl_Socket_E_TypeNoSupport, /*!< Socket type not supported */ + osl_Socket_E_OpNotSupport, /*!< Operation not supported on socket */ + osl_Socket_E_PfNoSupport, /*!< Protocol family not supported */ + osl_Socket_E_AfNoSupport, /*!< Address family not supported by */ + /*!< protocol family */ + osl_Socket_E_AddrInUse, /*!< Address already in use */ + osl_Socket_E_AddrNotAvail, /*!< Can't assign requested address */ + osl_Socket_E_NetDown, /*!< Network is down */ + osl_Socket_E_NetUnreachable, /*!< Network is unreachable */ + osl_Socket_E_NetReset, /*!< Network dropped connection because + of reset */ + osl_Socket_E_ConnAborted, /*!< Software caused connection abort */ + osl_Socket_E_ConnReset, /*!< Connection reset by peer */ + osl_Socket_E_NoBufferSpace, /*!< No buffer space available */ + osl_Socket_E_IsConnected, /*!< Socket is already connected */ + osl_Socket_E_NotConnected, /*!< Socket is not connected */ + osl_Socket_E_Shutdown, /*!< Can't send after socket shutdown */ + osl_Socket_E_TooManyRefs, /*!< Too many references: can't splice */ + osl_Socket_E_TimedOut, /*!< Connection timed out */ + osl_Socket_E_ConnRefused, /*!< Connection refused */ + osl_Socket_E_HostDown, /*!< Host is down */ + osl_Socket_E_HostUnreachable, /*!< No route to host */ + osl_Socket_E_WouldBlock, /*!< call would block on non-blocking socket */ + osl_Socket_E_Already, /*!< operation already in progress */ + osl_Socket_E_InProgress, /*!< operation now in progress */ + osl_Socket_E_InvalidError, /*!< unmapped error: always last entry in enum */ + osl_Socket_E_FORCE_EQUAL_SIZE = SAL_MAX_ENUM +} oslSocketError; + +/** Common return codes of socket related functions. + */ +typedef enum { + osl_Socket_Ok, /*!< successful completion */ + osl_Socket_Error, /*!< error occurred, check + osl_getLastSocketError() for details */ + osl_Socket_TimedOut, /*!< blocking operation timed out */ + osl_Socket_Interrupted, /*!< blocking operation was interrupted */ + osl_Socket_InProgress, /*!< nonblocking operation is in progress */ + osl_Socket_FORCE_EQUAL_SIZE = SAL_MAX_ENUM +} oslSocketResult; + +typedef sal_uInt8 oslSocketIpxNetNumber[4]; +typedef sal_uInt8 oslSocketIpxNodeNumber[6]; + +/**@} end section types +*/ + +/**@{ begin section oslSocket +*/ + +typedef struct oslSocketImpl * oslSocket; + +/** Create a socket of the specified Family and Type. The semantic of + the Protocol parameter depends on the given family and type. + + @returns 0 if socket could not be created, otherwise you get a handle + to the allocated socket-datastructure. +*/ +SAL_DLLPUBLIC oslSocket SAL_CALL osl_createSocket( + oslAddrFamily Family, + oslSocketType Type, + oslProtocol Protocol); + +/** increases the refcount of the socket handle by one + */ +SAL_DLLPUBLIC void SAL_CALL osl_acquireSocket(oslSocket Socket); + +/** decreases the refcount of the socket handle by one. + + If the refcount drops to zero, the underlying socket handle + is destroyed and becomes invalid. + */ +SAL_DLLPUBLIC void SAL_CALL osl_releaseSocket(oslSocket Socket); + +/** Retrieves the Address of the local end of the socket. + Note that a socket must be bound or connected before + a valid address can be returned. + + @returns 0 if socket-address could not be created, otherwise you get + the created Socket-Address. +*/ +SAL_DLLPUBLIC oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket Socket); + +/** Retrieves the Address of the remote end of the socket. + Note that a socket must be connected before + a valid address can be returned. + @retval 0 if socket-address could not be created, otherwise you get + the created Socket-Address. +*/ +SAL_DLLPUBLIC oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket Socket); + +/** Binds the given address to the socket. + @param[in] Socket + @param[in] Addr + @retval sal_False if the bind failed + @retval sal_True if bind is successful + @see osl_getLastSocketError() +*/ +SAL_DLLPUBLIC sal_Bool SAL_CALL osl_bindAddrToSocket( + oslSocket Socket, + oslSocketAddr Addr); + +/** Connects the socket to the given address. + + @param[in] Socket a bound socket. + @param[in] Addr the peer address. + @param pTimeout Timeout value or NULL for blocking. + + @retval osl_Socket_Ok on successful connection, + @retval osl_Socket_TimedOut if operation timed out, + @retval osl_Socket_Interrupted if operation was interrupted + @retval osl_Socket_Error if the connection failed. +*/ +SAL_DLLPUBLIC oslSocketResult SAL_CALL osl_connectSocketTo( + oslSocket Socket, + oslSocketAddr Addr, + const TimeValue* pTimeout); + + +/** Prepares the socket to act as an acceptor of incoming connections. + You should call "listen" before you use "accept". + @param[in] Socket The socket to listen on. + @param[in] MaxPendingConnections denotes the length of the queue of + pending connections for this socket. If MaxPendingConnections is + -1, the systems default value will be used (Usually 5). + @retval sal_False if the listen failed. +*/ +SAL_DLLPUBLIC sal_Bool SAL_CALL osl_listenOnSocket( + oslSocket Socket, + sal_Int32 MaxPendingConnections); + + +/** Waits for an ingoing connection on the socket. + This call blocks if there is no incoming connection present. + @param[in] Socket The socket to accept the connection on. + @param[in] pAddr if pAddr is != 0, the peers address is returned. + @retval 0 if the accept-call failed, otherwise you get a socket + representing the new connection. +*/ +SAL_DLLPUBLIC oslSocket SAL_CALL osl_acceptConnectionOnSocket( + oslSocket Socket, + oslSocketAddr* pAddr); + +/** Tries to receive BytesToRead data from the connected socket, + if no error occurs. Note that incomplete recvs due to + packet boundaries may occur. + + @param[in] Socket A connected socket to be used to listen on. + @param[out] pBuffer Points to a buffer that will be filled with the received + data. + @param[in] BytesToRead The number of bytes to read. pBuffer must have at least + this size. + @param[in] Flag Modifier for the call. Valid values are: + osl_Socket_MsgNormal + osl_Socket_MsgOOB + osl_Socket_MsgPeek + osl_Socket_MsgDontRoute + osl_Socket_MsgMaxIOVLen + + @return the number of received bytes. +*/ +SAL_DLLPUBLIC sal_Int32 SAL_CALL osl_receiveSocket( + oslSocket Socket, + void* pBuffer, + sal_uInt32 BytesToRead, + oslSocketMsgFlag Flag); + +/** Tries to receives BufferSize data from the (usually unconnected) + (datagram-)socket, if no error occurs. + + @param[in] Socket A bound socket to be used to listen for a datagram. + @param[out] SenderAddr A pointer to a created oslSocketAddr handle + or to a null handle. After the call, it will contain the constructed + oslSocketAddr of the datagrams sender. If pSenderAddr itself is 0, + it is ignored. + @param[out] pBuffer Points to a buffer that will be filled with the received + datagram. + @param[in] BufferSize The size of pBuffer. + @param[in] Flag Modifier for the call. Valid values are: + osl_Socket_MsgNormal + osl_Socket_MsgOOB + osl_Socket_MsgPeek + osl_Socket_MsgDontRoute + osl_Socket_MsgMaxIOVLen + + @return the number of received bytes. +*/ +SAL_DLLPUBLIC sal_Int32 SAL_CALL osl_receiveFromSocket( + oslSocket Socket, + oslSocketAddr SenderAddr, + void* pBuffer, + sal_uInt32 BufferSize, + oslSocketMsgFlag Flag); + +/** Tries to send BytesToSend data from the connected socket, + if no error occurs. + + @param[in] Socket A connected socket. + @param[in] pBuffer Points to a buffer that contains the send-data. + @param[in] BytesToSend The number of bytes to send. pBuffer must have at least + this size. + @param[in] Flag Modifier for the call. Valid values are: + @li osl_Socket_MsgNormal + @li osl_Socket_MsgOOB + @li osl_Socket_MsgPeek + @li osl_Socket_MsgDontRoute + @li osl_Socket_MsgMaxIOVLen + + @return the number of transferred bytes. +*/ +SAL_DLLPUBLIC sal_Int32 SAL_CALL osl_sendSocket( + oslSocket Socket, + const void* pBuffer, + sal_uInt32 BytesToSend, + oslSocketMsgFlag Flag); + +/** Tries to send one datagram with BytesToSend data to the given ReceiverAddr + via the (implicitly unconnected) datagram-socket. + Since there is only sent one packet, the function sends the data always complete + even with incomplete packet boundaries. + + @param[in] Socket A bound or unbound socket. Socket will be bound + after a successful call. + + @param[in] ReceiverAddr An initialized oslSocketAddress that contains + the destination address for this send. + + @param[in] pBuffer Points to a buffer that contains the send-data. + @param[in] BytesToSend The number of bytes to send. pBuffer must have at least + this size. + @param[in] Flag + @parblock + Modifier for the call. Valid values are: + @li osl_Socket_MsgNormal + @li osl_Socket_MsgOOB + @li osl_Socket_MsgPeek + @li osl_Socket_MsgDontRoute + @li osl_Socket_MsgMaxIOVLen + @endparblock + + @return the number of transferred bytes. +*/ +SAL_DLLPUBLIC sal_Int32 SAL_CALL osl_sendToSocket( + oslSocket Socket, + oslSocketAddr ReceiverAddr, + const void* pBuffer, + sal_uInt32 BytesToSend, + oslSocketMsgFlag Flag); + +/** Checks if read operations will block. + + You can specify a timeout-value in seconds/microseconds that denotes + how long the operation will block if the Socket is not ready. + + @param Socket the Socket to perform the operation on. + @param pTimeout if NULL, the operation will block without a timeout. + + @retval sal_True if read operations (recv, recvFrom, accept) on the Socket + will NOT block; + @retval sal_False if it would block or if an error occurred. +*/ +SAL_DLLPUBLIC sal_Bool SAL_CALL osl_isReceiveReady( + oslSocket Socket, + const TimeValue* pTimeout); + +/** Checks if send operations will block. + You can specify a timeout-value in seconds/microseconds that denotes + how long the operation will block if the Socket is not ready. + + @param Socket the Socket to perform the operation on. + @param pTimeout if NULL, the operation will block without a timeout. Otherwise + the time define by timeout value. + + @retval sal_True if send operations (send, sendTo) on the Socket + will NOT block + @retval sal_False if it would block or if an error occurred. +*/ +SAL_DLLPUBLIC sal_Bool SAL_CALL osl_isSendReady( + oslSocket Socket, + const TimeValue* pTimeout); + +/** Checks if a request for out-of-band data will block. + You can specify a timeout-value in seconds/microseconds that denotes + how long the operation will block if the Socket has no pending OOB data. + + @param Socket the Socket to perform the operation on. + @param pTimeout if NULL, the operation will block without a timeout. + + @retval sal_True if OOB-request operations (recv with appropriate flags) + on the Socket will NOT block + @retval sal_False if it would block or if an error occurred. +*/ +SAL_DLLPUBLIC sal_Bool SAL_CALL osl_isExceptionPending( + oslSocket Socket, + const TimeValue* pTimeout); + +/** Shuts down communication on a connected socket. + @param[in] Socket the Socket to perform the operation on. + @param[in] Direction + @parblock + Direction denotes which end of the socket should be closed: + @li osl_Socket_DirRead - closes read operations. + @li osl_Socket_DirReadWrite - closes write operations. + @li osl_Socket_DirWrite - closes read and write operations. + @endparblock + + @retval sal_True if the socket could be closed down. +*/ +SAL_DLLPUBLIC sal_Bool SAL_CALL osl_shutdownSocket( + oslSocket Socket, + oslSocketDirection Direction); + +/** Retrieves attributes associated with the socket. + + @param Socket is the socket to query. + @param Level + @parblock + Selects the level for which an option should be queried. + Valid values are: + @li osl_sol_socket - Socket Level + @li osl_sol_tcp - Level of Transmission Control Protocol + @endparblock + + @param Option + @parblock + Denotes the option to query. Valid values (depending on the Level) are: + @li osl_Socket_Option_Debug - (sal_Bool) Socket debug flag 1 = enabled, 0 = disabled. + @li osl_Socket_OptionAcceptConn + @li osl_Socket_OptionReuseAddr - (sal_Bool) Allows the socket to be bound to an address that is + already in use. 1 = multiple bound allowed, 0 = no multiple bounds allowed + @li osl_Socket_OptionKeepAlive (sal_Bool) Keepalive packets are sent by the underlying socket. + 1 = enabled, 0 = disabled + @li osl_Socket_OptionDontRoute - (sal_Bool) Do not route: send directly to interface. + 1 = do not route , 0 = routing possible + @li osl_Socket_OptionBroadcast - (sal_Bool) Transmission of broadcast messages are allowed on the socket. + 1 = transmission allowed, 0 = transmission disallowed + @li osl_Socket_OptionUseLoopback + @li osl_Socket_OptionLinger (sal_Int32) Linger on close if unsent data is present. + 0 = linger is off, > 0 = timeout in seconds. + @li osl_Socket_OptionOOBinLine + @li osl_Socket_OptionSndBuf (sal_Int32) Size of the send buffer in bytes. Data is sent after + SndTimeo or when the buffer is full. This allows faster writing to the socket. + @li osl_Socket_OptionRcvBuf (sal_Int32) Size of the receive buffer in bytes. Data is sent after + SndTimeo or when the buffer is full. This allows faster writing to the socket and larger packet sizes. + @li osl_Socket_OptionSndLowat + @li osl_Socket_OptionRcvLowat + @li osl_Socket_OptionSndTimeo (sal_Int32) Data is sent after this timeout. This allows gathering + of data to send larger packages but increases latency times. + @li osl_Socket_OptionRcvTimeo + @li osl_Socket_OptionError + @li osl_Socket_OptionType + @li osl_Socket_OptionTcpNoDelay Disables the Nagle algorithm for send coalescing. (Do not + collect data until a packet is full, instead send immediately. This increases network traffic + but might improve latency-times.) + 1 = disables the algorithm, 0 = keeps it enabled. + + If not above mentioned otherwise, the options are only valid for level osl_Socket_LevelSocket. + @endparblock + @param pBuffer Pointer to a buffer large enough to take the desired attribute-value. + @param BufferLen contains the length of the Buffer. + + @return -1 if an error occurred or else the size of the data copied into pBuffer. + + @see osl_setSocketOption() +*/ +SAL_DLLPUBLIC sal_Int32 SAL_CALL osl_getSocketOption( + oslSocket Socket, + oslSocketOptionLevel Level, + oslSocketOption Option, + void* pBuffer, + sal_uInt32 BufferLen); + +/** Sets the sockets attributes. + + @param Socket is the socket to modify. + @param Level + @parblock + selects the level for which an option should be changed. + Valid values are: + @li osl_sol_socket - Socket Level + @li osl_sol_tcp - Level of Transmission Control Protocol + @endparblock + @param Option denotes the option to modify. See osl_setSocketOption() for more + details. + @param pBuffer Pointer to a Buffer which contains the attribute-value. + @param BufferLen contains the length of the Buffer. + + @retval True if the option could be changed. +*/ +SAL_DLLPUBLIC sal_Bool SAL_CALL osl_setSocketOption( + oslSocket Socket, + oslSocketOptionLevel Level, + oslSocketOption Option, + void* pBuffer, + sal_uInt32 BufferLen); + +/** Enables/disables non-blocking-mode of the socket. + + @param Socket Change mode for this socket. + @param On sal_True enables non-blocking mode, sal_False disables non-blocking mode. + + @retval sal_True if mode could be changed. +*/ +SAL_DLLPUBLIC sal_Bool SAL_CALL osl_enableNonBlockingMode( + oslSocket Socket, + sal_Bool On); + + +/** Query state of non-blocking-mode of the socket. + + @param Socket Query mode for this socket. + + @retval True if non-blocking-mode is enabled. +*/ +SAL_DLLPUBLIC sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket Socket); + +/** Queries the socket for its type. + + @param[in] Socket The socket to query. + + @retval osl_Socket_TypeStream + @retval osl_Socket_TypeDgram + @retval osl_Socket_TypeRaw + @retval osl_Socket_TypeRdm + @retval osl_Socket_TypeSeqPacket + @retval osl_invalid_SocketType if an error occurred +*/ +SAL_DLLPUBLIC oslSocketType SAL_CALL osl_getSocketType(oslSocket Socket); + +/** returns a string which describes the last socket error. + + @param[in] Socket The socket to query. + @param[out] strError The string that receives the error message. +*/ +SAL_DLLPUBLIC void SAL_CALL osl_getLastSocketErrorDescription( + oslSocket Socket, + rtl_uString **strError); + +/** Returns a constant describing the last error for the socket system. + + @retval osl_Socket_E_NONE if no error occurred + @retval osl_invalid_SocketError if an unknown (unmapped) + error occurred, otherwise an enum describing the error. +*/ +SAL_DLLPUBLIC oslSocketError SAL_CALL osl_getLastSocketError( + oslSocket Socket); + +/** Closes the socket terminating any ongoing dataflow. + + @param[in] Socket The socket to close. + */ +SAL_DLLPUBLIC void SAL_CALL osl_closeSocket(oslSocket Socket); + + +/** Retrieves n bytes from the stream and copies them into pBuffer. + The function avoids incomplete reads due to packet boundaries. + + @param[in] Socket The socket to read from. + @param[out] pBuffer receives the read data. + @param[out] nSize the number of bytes to read. pBuffer must be large enough + to hold the n bytes! + + @return the number of read bytes. The number will only be smaller than + n if an exceptional condition (e.g. connection closed) occurs. +*/ +SAL_DLLPUBLIC sal_Int32 SAL_CALL osl_readSocket( + oslSocket Socket, + void *pBuffer, + sal_Int32 nSize); + + +/** Writes n bytes from pBuffer to the stream. The method avoids + incomplete writes due to packet boundaries. + + @param[out] Socket The socket to write to. + @param[in] pBuffer contains the data to be written. + @param[in] nSize the number of bytes to write. + + @return the number of written bytes. The number will only be smaller than + nSize if an exceptional condition (e.g. connection closed) occurs. +*/ +SAL_DLLPUBLIC sal_Int32 SAL_CALL osl_writeSocket( + oslSocket Socket, + const void *pBuffer, + sal_Int32 nSize); + +/**@} end section oslSocket +*/ +/**@{ begin section oslSocketAddr +*/ + +/** Creates a socket-address for the given family. + @param Family If family == osl_Socket_FamilyInet the address is + set to INADDR_ANY port 0. + @return 0 if address could not be created. +*/ +SAL_DLLPUBLIC oslSocketAddr SAL_CALL osl_createEmptySocketAddr( + oslAddrFamily Family); + + +/** Creates a new SocketAddress and fills it from Addr. +*/ +SAL_DLLPUBLIC oslSocketAddr SAL_CALL osl_copySocketAddr( + oslSocketAddr Addr); + +/** Compares the values of two SocketAddresses. + @retval sal_True if both addresses denote the same socket address. + @retval sal_False if both addresses do not denote the same socket address. +*/ +SAL_DLLPUBLIC sal_Bool SAL_CALL osl_isEqualSocketAddr( + oslSocketAddr Addr1, oslSocketAddr Addr2); + +/** Uses the systems name-service interface to find an address for strHostname. + @param[in] strHostname The name for which you search for an address. + @return The desired address if one could be found, otherwise 0. + Don't forget to destroy the address if you don't need it any longer. +*/ +SAL_DLLPUBLIC oslSocketAddr SAL_CALL osl_resolveHostname( + rtl_uString *strHostname); + +/** Create an internet address usable for sending broadcast datagrams. + To limit the broadcast to your subnet, pass your hosts IP address + in dotted decimal notation as first argument. + @see osl_sendToSocket() + @see oslSocketAddr + @param[in] strDottedAddr dotted decimal internet address, may be 0. + @param[in] Port port number in host byte order. + @retval 0 if address could not be created. +*/ +SAL_DLLPUBLIC oslSocketAddr SAL_CALL osl_createInetBroadcastAddr( + rtl_uString *strDottedAddr, sal_Int32 Port); + + +/** Create an internet-address, consisting of host address and port. + We interpret strDottedAddr as a dotted-decimal inet-addr + (e.g. "141.99.128.50"). + @param[in] strDottedAddr String with dotted address. + @param[in] Port portnumber in host byte order. + @retval 0 if address could not be created. +*/ +SAL_DLLPUBLIC oslSocketAddr SAL_CALL osl_createInetSocketAddr ( + rtl_uString *strDottedAddr, sal_Int32 Port); + + +/** Frees all resources allocated by Addr. The handle Addr must not + be used after the call anymore. +*/ +SAL_DLLPUBLIC void SAL_CALL osl_destroySocketAddr( + oslSocketAddr Addr); + +/** Looks up the port-number designated to the specified service/protocol-pair. + (e.g. "ftp" "tcp"). + @retval OSL_INVALID_PORT if no appropriate entry was found, otherwise the port-number. +*/ +SAL_DLLPUBLIC sal_Int32 SAL_CALL osl_getServicePort( + rtl_uString *strServicename, rtl_uString *strProtocol); + + + +/** Retrieves the address-family from the Addr. + @return the family of the socket-address. + In case of an unknown family you get osl_Socket_FamilyInvalid. +*/ +SAL_DLLPUBLIC oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr( + oslSocketAddr Addr); + + +/** Retrieves the internet port-number of Addr. + @return the port-number of the address in host-byte order. If Addr + is not an address of type osl_Socket_FamilyInet, it returns OSL_INVALID_PORT +*/ +SAL_DLLPUBLIC sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr( + oslSocketAddr Addr); + + +/** Sets the Port of Addr. + @param[in] Addr the SocketAddr to perform the operation on. + @param[in] Port is expected in host byte-order. + @retval sal_False if Addr is not an inet-addr. +*/ +SAL_DLLPUBLIC sal_Bool SAL_CALL osl_setInetPortOfSocketAddr( + oslSocketAddr Addr, sal_Int32 Port); + + +/** Returns the hostname represented by Addr. + @param[in] Addr The socket address from which to extract the hostname. + @param[out] strHostname The hostname represented by the address. If + there is no hostname to be found, it returns 0. +*/ +SAL_DLLPUBLIC oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr( + oslSocketAddr Addr, rtl_uString **strHostname); + + +/** Gets the address in dotted decimal format. + + @param[in] Addr The socket address from which to extract the dotted decimal address. + @param[out] strDottedInetAddr Contains the dotted decimal address + (e.g. 141.99.20.34) represented by the address. + + @retval If the address is invalid or not of type osl_Socket_FamilyInet, it returns 0. + @retval osl_Socket_Ok + @retval osl_Socket_Error +*/ +SAL_DLLPUBLIC oslSocketResult SAL_CALL osl_getDottedInetAddrOfSocketAddr( + oslSocketAddr Addr, rtl_uString **strDottedInetAddr); + +/** Sets the addr field in the struct sockaddr with pByteSeq. pByteSeq must be in network byte order. + */ +SAL_DLLPUBLIC oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( + oslSocketAddr Addr, sal_Sequence *pByteSeq ); + +/** Returns the addr field in the struct sockaddr. + @param[in] Addr The socket address from which to extract the ipaddress. + @param[out] ppByteSeq After the call, *ppByteSeq contains the ipaddress + in network byte order. *ppByteSeq may be 0 in case of an invalid socket handle. + @retval osl_Socket_Ok + @retval osl_Socket_Error + */ +SAL_DLLPUBLIC oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( + oslSocketAddr Addr, sal_Sequence **ppByteSeq ); + +/* + Opaque datatype HostAddr. +*/ +typedef struct oslHostAddrImpl * oslHostAddr; + + +/** Create an oslHostAddr from given hostname and socket address. + @param[in] strHostname The hostname to be stored. + @param[in] Addr The socket address to be stored. + @return The created address or 0 upon failure. +*/ +SAL_DLLPUBLIC oslHostAddr SAL_CALL osl_createHostAddr( + rtl_uString *strHostname, const oslSocketAddr Addr); + + +/** Create an oslHostAddr by resolving the given strHostname. + Successful name resolution should result in the fully qualified + domain name (FQDN) and its address as hostname and socket address + members of the resulting oslHostAddr. + @param[in] strHostname The hostname to be resolved. + @return The resulting address or 0 upon failure. +*/ +SAL_DLLPUBLIC oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *strHostname); + + +/** Create an oslHostAddr by reverse resolution of the given Addr. + Successful name resolution should result in the fully qualified + domain name (FQDN) and its address as hostname and socket address + members of the resulting oslHostAddr. + @param[in] Addr The socket address to be reverse resolved. + @return The resulting address or 0 upon failure. +*/ +SAL_DLLPUBLIC oslHostAddr SAL_CALL osl_createHostAddrByAddr(const oslSocketAddr Addr); + + +/** Create a copy of the given Addr. + @return The copied address or 0 upon failure. +*/ +SAL_DLLPUBLIC oslHostAddr SAL_CALL osl_copyHostAddr(const oslHostAddr Addr); + + +/** Frees all resources allocated by Addr. The handle Addr must not + be used after the call anymore. +*/ +SAL_DLLPUBLIC void SAL_CALL osl_destroyHostAddr(oslHostAddr Addr); + + +/** Get the hostname member of Addr. + @return The hostname or 0 upon failure. +*/ +SAL_DLLPUBLIC void SAL_CALL osl_getHostnameOfHostAddr(const oslHostAddr Addr, rtl_uString **strHostname); + + +/** Get the socket address member of Addr. + @return The socket address or 0 upon failure. +*/ +SAL_DLLPUBLIC oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr(const oslHostAddr Addr); + +/** Retrieve this machines hostname (NOT the FQDN) + @param strLocalHostname out-parameter. The string that receives the local host name. + @retval sal_True upon success + @retval sal_False +*/ +SAL_DLLPUBLIC oslSocketResult SAL_CALL osl_getLocalHostname(rtl_uString **strLocalHostname); + + +/**@} end section oslHostAddr +*/ + +#ifdef __cplusplus +} +#endif + +#endif // INCLUDED_OSL_SOCKET_H + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/osl/socket.hxx b/include/osl/socket.hxx new file mode 100644 index 000000000..78d410e99 --- /dev/null +++ b/include/osl/socket.hxx @@ -0,0 +1,571 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +/* + * This file is part of LibreOffice published API. + */ + +#ifndef INCLUDED_OSL_SOCKET_HXX +#define INCLUDED_OSL_SOCKET_HXX + +#include "osl/socket_decl.hxx" + +namespace osl +{ + + inline SocketAddr::SocketAddr() + : m_handle( osl_createEmptySocketAddr( osl_Socket_FamilyInet ) ) + {} + + + inline SocketAddr::SocketAddr(const SocketAddr& Addr) + : m_handle( osl_copySocketAddr( Addr.m_handle ) ) + { + } + +#if defined LIBO_INTERNAL_ONLY + SocketAddr::SocketAddr(SocketAddr && other) noexcept : m_handle(other.m_handle) { + other.m_handle = nullptr; + } +#endif + + inline SocketAddr::SocketAddr(oslSocketAddr Addr) + : m_handle( osl_copySocketAddr( Addr ) ) + { + } + + + inline SocketAddr::SocketAddr(oslSocketAddr Addr, __osl_socket_NoCopy ) + : m_handle( Addr ) + { + } + + + inline SocketAddr::SocketAddr( const ::rtl::OUString& strAddrOrHostName, sal_Int32 nPort) + : m_handle( osl_createInetSocketAddr( strAddrOrHostName.pData, nPort ) ) + { + if(! m_handle ) + { + m_handle = osl_resolveHostname(strAddrOrHostName.pData); + + // host found? + if(m_handle) + { + osl_setInetPortOfSocketAddr(m_handle, nPort); + } + else + { + osl_destroySocketAddr( m_handle ); + m_handle = NULL; + } + } + } + + + inline SocketAddr::~SocketAddr() + { + if( m_handle ) + osl_destroySocketAddr( m_handle ); + } + + + inline ::rtl::OUString SocketAddr::getHostname( oslSocketResult *pResult ) const + { + ::rtl::OUString hostname; + oslSocketResult result = osl_getHostnameOfSocketAddr( m_handle, &(hostname.pData) ); + if( pResult ) + *pResult = result; + return hostname; + } + + + inline sal_Int32 SAL_CALL SocketAddr::getPort() const + { + return osl_getInetPortOfSocketAddr(m_handle); + } + + + inline bool SAL_CALL SocketAddr::setPort( sal_Int32 nPort ) + { + return osl_setInetPortOfSocketAddr(m_handle, nPort ); + } + + inline bool SAL_CALL SocketAddr::setHostname( const ::rtl::OUString &sDottedIpOrHostname ) + { + *this = SocketAddr( sDottedIpOrHostname , getPort() ); + return is(); + } + + + inline bool SAL_CALL SocketAddr::setAddr( const ::rtl::ByteSequence & address ) + { + return osl_setAddrOfSocketAddr( m_handle, address.getHandle() ) + == osl_Socket_Ok; + } + + inline ::rtl::ByteSequence SAL_CALL SocketAddr::getAddr( oslSocketResult *pResult ) const + { + ::rtl::ByteSequence sequence; + oslSocketResult result = osl_getAddrOfSocketAddr( m_handle, reinterpret_cast<sal_Sequence **>(&sequence) ); + if( pResult ) + *pResult = result; + return sequence; + } + + + inline SocketAddr & SAL_CALL SocketAddr::operator= (oslSocketAddr Addr) + { + oslSocketAddr pNewAddr = osl_copySocketAddr( Addr ); + if( m_handle ) + osl_destroySocketAddr( m_handle ); + m_handle = pNewAddr; + return *this; + } + + + inline SocketAddr & SAL_CALL SocketAddr::operator= (const SocketAddr& Addr) + { + *this = Addr.getHandle(); + return *this; + } + +#if defined LIBO_INTERNAL_ONLY + SocketAddr & SocketAddr::operator =(SocketAddr && other) noexcept { + if (m_handle != nullptr) { + osl_destroySocketAddr(m_handle); + } + m_handle = other.m_handle; + other.m_handle = nullptr; + return *this; + } +#endif + + inline SocketAddr & SAL_CALL SocketAddr::assign( oslSocketAddr Addr, __osl_socket_NoCopy ) + { + if( m_handle ) + osl_destroySocketAddr( m_handle ); + m_handle = Addr; + return *this; + } + + + inline bool SAL_CALL SocketAddr::operator== (oslSocketAddr Addr) const + { + return osl_isEqualSocketAddr( m_handle, Addr ); + } + + inline oslSocketAddr SocketAddr::getHandle() const + { + return m_handle; + } + + + inline bool SocketAddr::is() const + { + return m_handle != NULL; + } + + inline ::rtl::OUString SAL_CALL SocketAddr::getLocalHostname( oslSocketResult *pResult ) + { + ::rtl::OUString hostname; + oslSocketResult result = osl_getLocalHostname( &(hostname.pData) ); + if(pResult ) + *pResult = result; + return hostname; + } + + inline void SAL_CALL SocketAddr::resolveHostname( + const ::rtl::OUString & strHostName, SocketAddr &Addr) + { + Addr = SocketAddr( osl_resolveHostname( strHostName.pData ) , SAL_NO_COPY ); + } + + inline sal_Int32 SAL_CALL SocketAddr::getServicePort( + const ::rtl::OUString& strServiceName, + const ::rtl::OUString & strProtocolName ) + { + return osl_getServicePort( strServiceName.pData, strProtocolName.pData ); + } + + + inline Socket::Socket(oslSocketType Type, + oslAddrFamily Family, + oslProtocol Protocol) + : m_handle( osl_createSocket(Family, Type, Protocol) ) + {} + + + inline Socket::Socket( oslSocket socketHandle, __sal_NoAcquire ) + : m_handle( socketHandle ) + {} + + + inline Socket::Socket( oslSocket socketHandle ) + : m_handle( socketHandle ) + { + osl_acquireSocket( m_handle ); + } + + + inline Socket::Socket( const Socket & socket ) + : m_handle( socket.getHandle() ) + { + osl_acquireSocket( m_handle ); + } + + + inline Socket::~Socket() + { + osl_releaseSocket( m_handle ); + } + + + inline Socket& Socket::operator= ( oslSocket socketHandle) + { + osl_acquireSocket( socketHandle ); + osl_releaseSocket( m_handle ); + m_handle = socketHandle; + return *this; + } + + + inline Socket& Socket::operator= (const Socket& sock) + { + *this = sock.getHandle(); + return *this; + } + + + inline bool Socket::operator==( const Socket& rSocket ) const + { + return m_handle == rSocket.getHandle(); + } + + + inline bool Socket::operator==( const oslSocket socketHandle ) const + { + return m_handle == socketHandle; + } + + + inline void Socket::shutdown( oslSocketDirection Direction ) + { + osl_shutdownSocket( m_handle , Direction ); + } + + + inline void Socket::close() + { + osl_closeSocket( m_handle ); + } + + + inline void Socket::getLocalAddr( SocketAddr & addr) const + { + addr.assign( osl_getLocalAddrOfSocket( m_handle ) , SAL_NO_COPY ); + } + + + inline sal_Int32 Socket::getLocalPort() const + { + SocketAddr addr( NULL ); + getLocalAddr( addr ); + return addr.getPort(); + } + + + inline ::rtl::OUString Socket::getLocalHost() const + { + SocketAddr addr( NULL ); + getLocalAddr( addr ); + return addr.getHostname(); + } + + + inline void Socket::getPeerAddr( SocketAddr &addr ) const + { + addr.assign( osl_getPeerAddrOfSocket( m_handle ), SAL_NO_COPY ); + } + + + inline sal_Int32 Socket::getPeerPort() const + { + SocketAddr addr( NULL ); + getPeerAddr( addr ); + return addr.getPort(); + } + + + inline ::rtl::OUString Socket::getPeerHost() const + { + SocketAddr addr( NULL ); + getPeerAddr( addr ); + return addr.getHostname(); + } + + + inline bool Socket::bind(const SocketAddr& LocalInterface) + { + return osl_bindAddrToSocket( m_handle , LocalInterface.getHandle() ); + } + + + inline bool Socket::isRecvReady(const TimeValue *pTimeout ) const + { + return osl_isReceiveReady( m_handle , pTimeout ); + } + + + inline bool Socket::isSendReady(const TimeValue *pTimeout ) const + { + return osl_isSendReady( m_handle, pTimeout ); + } + + + inline bool Socket::isExceptionPending(const TimeValue *pTimeout ) const + { + return osl_isExceptionPending( m_handle, pTimeout ); + } + + + inline oslSocketType Socket::getType() const + { + return osl_getSocketType( m_handle ); + } + + + inline sal_Int32 Socket::getOption( + oslSocketOption Option, + void* pBuffer, + sal_uInt32 BufferLen, + oslSocketOptionLevel Level) const + { + return osl_getSocketOption( m_handle, Level, Option, pBuffer , BufferLen ); + } + + + inline bool Socket::setOption( oslSocketOption Option, + void* pBuffer, + sal_uInt32 BufferLen, + oslSocketOptionLevel Level ) const + { + return osl_setSocketOption( m_handle, Level, Option , pBuffer, BufferLen ); + } + + + inline bool Socket::setOption( oslSocketOption option, sal_Int32 nValue ) + { + return setOption( option, &nValue, sizeof( nValue ) ); + } + + + inline sal_Int32 Socket::getOption( oslSocketOption option ) const + { + sal_Int32 n; + getOption( option, &n, sizeof( n ) ); + return n; + } + + + inline bool Socket::enableNonBlockingMode( bool bNonBlockingMode) + { + return osl_enableNonBlockingMode( m_handle , bNonBlockingMode ); + } + + + inline bool Socket::isNonBlockingMode() const + { + return osl_isNonBlockingMode( m_handle ); + } + + + inline void SAL_CALL Socket::clearError() const + { + sal_Int32 err = 0; + getOption(osl_Socket_OptionError, &err, sizeof(err)); + } + + + inline oslSocketError Socket::getError() const + { + return osl_getLastSocketError( m_handle ); + } + + + inline ::rtl::OUString Socket::getErrorAsString( ) const + { + ::rtl::OUString error; + osl_getLastSocketErrorDescription( m_handle, &(error.pData) ); + return error; + } + + + inline oslSocket Socket::getHandle() const + { + return m_handle; + } + + + inline StreamSocket::StreamSocket(oslAddrFamily Family, + oslProtocol Protocol, + oslSocketType Type ) + : Socket( Type, Family, Protocol ) + {} + + + inline StreamSocket::StreamSocket( oslSocket socketHandle, __sal_NoAcquire noacquire ) + : Socket( socketHandle, noacquire ) + {} + + + inline StreamSocket::StreamSocket( oslSocket socketHandle ) + : Socket( socketHandle ) + {} + + + inline sal_Int32 StreamSocket::read(void* pBuffer, sal_uInt32 n) + { + return osl_readSocket( m_handle, pBuffer, n ); + } + + + inline sal_Int32 StreamSocket::write(const void* pBuffer, sal_uInt32 n) + { + return osl_writeSocket( m_handle, pBuffer, n ); + } + + + inline sal_Int32 StreamSocket::recv(void* pBuffer, + sal_uInt32 BytesToRead, + oslSocketMsgFlag Flag) + { + return osl_receiveSocket( m_handle, pBuffer,BytesToRead, Flag ); + } + + + inline sal_Int32 StreamSocket::send(const void* pBuffer, + sal_uInt32 BytesToSend, + oslSocketMsgFlag Flag) + { + return osl_sendSocket( m_handle, pBuffer, BytesToSend, Flag ); + } + + + inline ConnectorSocket::ConnectorSocket(oslAddrFamily Family, + oslProtocol Protocol, + oslSocketType Type) + : StreamSocket( Family, Protocol ,Type ) + {} + + + inline oslSocketResult ConnectorSocket::connect( const SocketAddr& TargetHost, + const TimeValue* pTimeout ) + { + return osl_connectSocketTo( m_handle , TargetHost.getHandle(), pTimeout ); + } + + + inline AcceptorSocket::AcceptorSocket(oslAddrFamily Family , + oslProtocol Protocol , + oslSocketType Type ) + : Socket( Type, Family, Protocol ) + {} + + + inline bool AcceptorSocket::listen(sal_Int32 MaxPendingConnections) + { + return osl_listenOnSocket( m_handle, MaxPendingConnections ); + } + + + inline oslSocketResult AcceptorSocket::acceptConnection( StreamSocket& Connection) + { + oslSocket o = osl_acceptConnectionOnSocket( m_handle, NULL ); + oslSocketResult status = osl_Socket_Ok; + if( o ) + { + Connection = StreamSocket( o , SAL_NO_ACQUIRE ); + } + else + { + Connection = StreamSocket(); + status = osl_Socket_Error; + } + return status; + } + + + inline oslSocketResult AcceptorSocket::acceptConnection( + StreamSocket& Connection, SocketAddr & PeerAddr) + { + // TODO change in/OUT parameter + oslSocket o = osl_acceptConnectionOnSocket( + m_handle, reinterpret_cast<oslSocketAddr *>(&PeerAddr)); + oslSocketResult status = osl_Socket_Ok; + if( o ) + { + Connection = StreamSocket( o , SAL_NO_ACQUIRE ); + } + else + { + Connection = StreamSocket(); + status = osl_Socket_Error; + } + return status; + } + + + inline DatagramSocket::DatagramSocket(oslAddrFamily Family, + oslProtocol Protocol, + oslSocketType Type) + : Socket( Type, Family, Protocol ) + {} + + + inline sal_Int32 DatagramSocket::recvFrom(void* pBuffer, + sal_uInt32 BufferSize, + SocketAddr* pSenderAddr, + oslSocketMsgFlag Flag ) + { + sal_Int32 nByteRead; + if( pSenderAddr ) + { + // TODO : correct the out-parameter pSenderAddr outparameter + nByteRead = osl_receiveFromSocket( m_handle, pSenderAddr->getHandle() , pBuffer, + BufferSize, Flag); + } + else + { + nByteRead = osl_receiveFromSocket( m_handle, NULL , pBuffer , BufferSize , Flag ); + } + return nByteRead; + } + + + inline sal_Int32 DatagramSocket::sendTo( const SocketAddr& ReceiverAddr, + const void* pBuffer, + sal_uInt32 BufferSize, + oslSocketMsgFlag Flag ) + { + return osl_sendToSocket( m_handle, ReceiverAddr.getHandle(), pBuffer, BufferSize, Flag ); + } +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |