2019-06-13 10:02:06 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
#include <winsock2.h>
|
2019-11-13 06:08:52 +00:00
|
|
|
#include <mswsock.h>
|
2019-07-15 08:49:24 +00:00
|
|
|
#include <inaddr.h>
|
2019-06-13 10:02:06 +00:00
|
|
|
#else
|
|
|
|
|
#include <netinet/ip.h>
|
|
|
|
|
#include <arpa/inet.h>
|
2019-07-18 08:55:21 +00:00
|
|
|
#include <sys/uio.h>
|
2019-06-13 10:02:06 +00:00
|
|
|
#endif
|
|
|
|
|
|
2019-06-18 08:18:33 +00:00
|
|
|
#include <vector>
|
2019-06-20 06:25:01 +00:00
|
|
|
#include <string>
|
2019-06-18 08:18:33 +00:00
|
|
|
|
2020-01-22 08:57:40 +00:00
|
|
|
#include "srtp.hh"
|
2019-06-13 10:02:06 +00:00
|
|
|
#include "util.hh"
|
|
|
|
|
|
2020-04-27 11:07:24 +00:00
|
|
|
namespace uvg_rtp {
|
2019-06-13 10:02:06 +00:00
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
2019-07-15 08:49:24 +00:00
|
|
|
typedef unsigned socklen_t;
|
2019-10-02 08:41:06 +00:00
|
|
|
typedef TRANSMIT_PACKETS_ELEMENT vecio_buf;
|
2019-06-13 10:02:06 +00:00
|
|
|
#else
|
2019-10-02 08:41:06 +00:00
|
|
|
typedef mmsghdr vecio_buf;
|
2019-06-13 10:02:06 +00:00
|
|
|
#endif
|
|
|
|
|
|
2019-07-18 08:55:21 +00:00
|
|
|
const int MAX_BUFFER_COUNT = 256;
|
|
|
|
|
|
2019-06-13 10:02:06 +00:00
|
|
|
class socket {
|
|
|
|
|
public:
|
2020-05-28 09:24:18 +00:00
|
|
|
socket(int flags);
|
2019-06-13 10:02:06 +00:00
|
|
|
~socket();
|
|
|
|
|
|
2019-06-18 08:18:33 +00:00
|
|
|
/* Create socket using "family", "type" and "protocol"
|
|
|
|
|
*
|
|
|
|
|
* NOTE: Only family AF_INET (ie. IPv4) is supported
|
|
|
|
|
*
|
|
|
|
|
* Return RTP_OK on success
|
|
|
|
|
* return RTP_SOCKET_ERROR if creating the socket failed */
|
2019-06-13 10:02:06 +00:00
|
|
|
rtp_error_t init(short family, int type, int protocol);
|
|
|
|
|
|
2019-06-18 08:18:33 +00:00
|
|
|
/* Same as bind(2), assigns an address for the underlying socket object
|
|
|
|
|
*
|
|
|
|
|
* Return RTP_OK on success
|
|
|
|
|
* Return RTP_BIND_ERROR if the bind failed */
|
2019-06-13 10:02:06 +00:00
|
|
|
rtp_error_t bind(short family, unsigned host, short port);
|
|
|
|
|
|
2019-06-18 08:18:33 +00:00
|
|
|
/* Same as setsockopt(2), used to manipulate the underlying socket object
|
|
|
|
|
*
|
|
|
|
|
* Return RTP_OK on success
|
|
|
|
|
* Return RTP_GENERIC_ERROR if setsockopt failed */
|
2019-06-13 10:02:06 +00:00
|
|
|
rtp_error_t setsockopt(int level, int optname, const void *optval, socklen_t optlen);
|
|
|
|
|
|
2019-06-18 08:18:33 +00:00
|
|
|
/* Same as send(2), send message to remote using "flags"
|
|
|
|
|
* This function uses the internal addr_ object as remote address so it MUST be set
|
|
|
|
|
*
|
2019-07-18 08:55:21 +00:00
|
|
|
* It is possible to combine multiple buffers and send them as one RTP frame by calling
|
|
|
|
|
* the sendto() with a vector containing the buffers and their lengths
|
|
|
|
|
*
|
2019-06-19 06:26:04 +00:00
|
|
|
* Write the amount of bytes sent to "bytes_sent" if it's not NULL
|
|
|
|
|
*
|
2019-06-18 08:18:33 +00:00
|
|
|
* Return RTP_OK on success and write the amount of bytes sent to "bytes_sent"
|
|
|
|
|
* Return RTP_SEND_ERROR on error and set "bytes_sent" to -1 */
|
2019-06-19 06:16:57 +00:00
|
|
|
rtp_error_t sendto(uint8_t *buf, size_t buf_len, int flags);
|
2019-06-13 10:02:06 +00:00
|
|
|
rtp_error_t sendto(uint8_t *buf, size_t buf_len, int flags, int *bytes_sent);
|
2019-07-18 08:55:21 +00:00
|
|
|
rtp_error_t sendto(std::vector<std::pair<size_t, uint8_t *>> buffers, int flags);
|
|
|
|
|
rtp_error_t sendto(std::vector<std::pair<size_t, uint8_t *>> buffers, int flags, int *bytes_sent);
|
2019-06-13 10:02:06 +00:00
|
|
|
|
2019-06-19 06:16:57 +00:00
|
|
|
/* Same as sendto() but the remote address given as parameter */
|
|
|
|
|
rtp_error_t sendto(sockaddr_in& addr, uint8_t *buf, size_t buf_len, int flags);
|
2019-06-18 08:26:46 +00:00
|
|
|
rtp_error_t sendto(sockaddr_in& addr, uint8_t *buf, size_t buf_len, int flags, int *bytes_sent);
|
2019-07-18 08:55:21 +00:00
|
|
|
rtp_error_t sendto(sockaddr_in& addr, std::vector<std::pair<size_t, uint8_t *>> buffers, int flags);
|
|
|
|
|
rtp_error_t sendto(sockaddr_in& addr, std::vector<std::pair<size_t, uint8_t *>> buffers, int flags, int *bytes_sent);
|
2019-06-18 08:26:46 +00:00
|
|
|
|
2020-01-10 06:21:25 +00:00
|
|
|
/* Special sendto() function, used to send multiple UDP packets with one system call
|
2019-10-02 08:41:06 +00:00
|
|
|
* Internally it uses sendmmsg(2) (Linux) or TransmitPackets (Windows)
|
|
|
|
|
*
|
|
|
|
|
* Return RTP_OK on success
|
|
|
|
|
* Return RTP_INVALID_VALUE if one of the parameters is invalid
|
|
|
|
|
* Return RTP_SEND_ERROR if sendmmsg/TransmitPackets failed */
|
|
|
|
|
rtp_error_t send_vecio(vecio_buf *buffers, size_t nbuffers, int flags);
|
|
|
|
|
|
2020-01-10 06:21:25 +00:00
|
|
|
/* Special recv() function, used to receive multiple UDP packets with one system call
|
|
|
|
|
* Internally it uses recvmmsg(2) (Linux).
|
|
|
|
|
*
|
|
|
|
|
* TODO what about windows?
|
|
|
|
|
*
|
|
|
|
|
* Parameter "nread" is used to indicate how many packet were read from the OS.
|
|
|
|
|
* It may differ from "nbuffers"
|
|
|
|
|
*
|
|
|
|
|
* Return RTP_OK on success
|
|
|
|
|
* Return RTP_INVALID_VALUE if one of the parameters is invalid
|
|
|
|
|
* Return RTP_SEND_ERROR if sendmmsg/TransmitPackets failed */
|
|
|
|
|
rtp_error_t recv_vecio(vecio_buf *buffers, size_t nbuffers, int flags, int *nread);
|
|
|
|
|
|
|
|
|
|
/* Same as recv(2), receives a message from socket (remote address not known)
|
|
|
|
|
*
|
|
|
|
|
* Write the amount of bytes read to "bytes_read" if it's not NULL
|
|
|
|
|
*
|
|
|
|
|
* Return RTP_OK on success and write the amount of bytes received to "bytes_read"
|
|
|
|
|
* Return RTP_INTERRUPTED if the call was interrupted due to timeout and set "bytes_sent" to 0
|
|
|
|
|
* Return RTP_GENERIC_ERROR on error and set "bytes_sent" to -1 */
|
|
|
|
|
rtp_error_t recv(uint8_t *buf, size_t buf_len, int flags);
|
|
|
|
|
rtp_error_t recv(uint8_t *buf, size_t buf_len, int flags, int *bytes_read);
|
|
|
|
|
|
2019-06-18 08:18:33 +00:00
|
|
|
/* Same as recvfrom(2), receives a message from remote
|
|
|
|
|
*
|
2019-06-19 06:26:04 +00:00
|
|
|
* Write the sender address to "sender" if it's not NULL
|
|
|
|
|
* Write the amount of bytes read to "bytes_read" if it's not NULL
|
2019-06-18 08:18:33 +00:00
|
|
|
*
|
|
|
|
|
* Return RTP_OK on success and write the amount of bytes sent to "bytes_sent"
|
|
|
|
|
* Return RTP_INTERRUPTED if the call was interrupted due to timeout and set "bytes_sent" to 0
|
|
|
|
|
* Return RTP_GENERIC_ERROR on error and set "bytes_sent" to -1 */
|
2019-06-19 06:26:04 +00:00
|
|
|
rtp_error_t recvfrom(uint8_t *buf, size_t buf_len, int flags, sockaddr_in *sender, int *bytes_read);
|
|
|
|
|
rtp_error_t recvfrom(uint8_t *buf, size_t buf_len, int flags, sockaddr_in *sender);
|
2019-06-13 10:02:06 +00:00
|
|
|
rtp_error_t recvfrom(uint8_t *buf, size_t buf_len, int flags, int *bytes_read);
|
2019-06-19 06:26:04 +00:00
|
|
|
rtp_error_t recvfrom(uint8_t *buf, size_t buf_len, int flags);
|
2019-06-13 10:02:06 +00:00
|
|
|
|
2019-06-18 08:18:33 +00:00
|
|
|
/* Create sockaddr_in object using the provided information
|
|
|
|
|
* NOTE: "family" must be AF_INET */
|
|
|
|
|
sockaddr_in create_sockaddr(short family, unsigned host, short port);
|
2019-06-13 10:02:06 +00:00
|
|
|
|
2019-06-18 08:18:33 +00:00
|
|
|
/* Create sockaddr_in object using the provided information
|
|
|
|
|
* NOTE: "family" must be AF_INET */
|
2019-06-13 10:02:06 +00:00
|
|
|
sockaddr_in create_sockaddr(short family, std::string host, short port);
|
|
|
|
|
|
2019-07-15 05:04:24 +00:00
|
|
|
/* Get reference to the actual socket object */
|
|
|
|
|
socket_t& get_raw_socket();
|
2019-06-13 10:02:06 +00:00
|
|
|
|
2019-06-18 08:18:33 +00:00
|
|
|
/* Initialize the private "addr_" object with "addr"
|
|
|
|
|
* This is used when calling send() */
|
2019-06-13 10:02:06 +00:00
|
|
|
void set_sockaddr(sockaddr_in addr);
|
|
|
|
|
|
2020-02-25 07:48:02 +00:00
|
|
|
/* TODO: */
|
2020-04-27 11:07:24 +00:00
|
|
|
void set_srtp(uvg_rtp::srtp *srtp);
|
2020-02-25 07:48:02 +00:00
|
|
|
|
2020-02-07 10:22:58 +00:00
|
|
|
/* Get the out address for the socket if it exists */
|
|
|
|
|
sockaddr_in& get_out_address();
|
|
|
|
|
|
2019-06-13 10:02:06 +00:00
|
|
|
private:
|
2019-06-18 08:26:46 +00:00
|
|
|
/* helper function for sending UPD packets, see documentation for sendto() above */
|
|
|
|
|
rtp_error_t __sendto(sockaddr_in& addr, uint8_t *buf, size_t buf_len, int flags, int *bytes_sent);
|
2020-01-10 06:21:25 +00:00
|
|
|
rtp_error_t __recv(uint8_t *buf, size_t buf_len, int flags, int *bytes_read);
|
2019-06-19 06:26:04 +00:00
|
|
|
rtp_error_t __recvfrom(uint8_t *buf, size_t buf_len, int flags, sockaddr_in *sender, int *bytes_read);
|
2019-06-18 08:26:46 +00:00
|
|
|
|
2019-07-18 08:55:21 +00:00
|
|
|
/* __sendtov() does the same as __sendto but it combines multiple buffers into one frame and sends them */
|
|
|
|
|
rtp_error_t __sendtov(sockaddr_in& addr, std::vector<std::pair<size_t, uint8_t *>> buffers, int flags, int *bytes_sent);
|
|
|
|
|
|
2019-06-13 10:02:06 +00:00
|
|
|
socket_t socket_;
|
|
|
|
|
sockaddr_in addr_;
|
2020-04-27 11:07:24 +00:00
|
|
|
uvg_rtp::srtp *srtp_;
|
2020-05-28 09:24:18 +00:00
|
|
|
int flags_;
|
2019-07-18 08:55:21 +00:00
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
2019-08-12 07:03:16 +00:00
|
|
|
WSABUF buffers_[MAX_BUFFER_COUNT];
|
2019-07-18 08:55:21 +00:00
|
|
|
#else
|
2019-08-12 07:03:16 +00:00
|
|
|
struct mmsghdr header_;
|
|
|
|
|
struct iovec chunks_[MAX_BUFFER_COUNT];
|
2019-07-18 08:55:21 +00:00
|
|
|
#endif
|
2019-06-13 10:02:06 +00:00
|
|
|
};
|
|
|
|
|
};
|