common: Move all binding to socket

This commit is contained in:
Joni Räsänen 2022-08-23 18:06:26 +03:00
parent 1c9dcd2aad
commit ec2e341ca5
3 changed files with 92 additions and 33 deletions

View File

@ -77,6 +77,7 @@ namespace uvgrtp {
* Return RTP_OK on success
* Return RTP_BIND_ERROR if the bind failed */
rtp_error_t bind(short family, unsigned host, short port);
rtp_error_t bind(sockaddr_in& local_address);
/* Same as setsockopt(2), used to manipulate the underlying socket object
*
@ -134,11 +135,13 @@ namespace uvgrtp {
/* Create sockaddr_in object using the provided information
* NOTE: "family" must be AF_INET */
sockaddr_in create_sockaddr(short family, unsigned host, short port);
sockaddr_in create_sockaddr(short family, unsigned host, short port) const;
/* Create sockaddr_in object using the provided information
* NOTE: "family" must be AF_INET */
sockaddr_in create_sockaddr(short family, std::string host, short port);
sockaddr_in create_sockaddr(short family, std::string host, short port) const;
std::string get_socket_path_string() const;
/* Get reference to the actual socket object */
socket_t& get_raw_socket();
@ -160,6 +163,9 @@ namespace uvgrtp {
rtp_error_t install_handler(void *arg, packet_handler_vec handler);
private:
std::string sockaddr_to_string(const sockaddr_in& addr) const;
/* 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 send_flags, int *bytes_sent);
rtp_error_t __recv(uint8_t *buf, size_t buf_len, int recv_flags, int *bytes_read);
@ -170,7 +176,8 @@ namespace uvgrtp {
rtp_error_t __sendtov(sockaddr_in& addr, uvgrtp::pkt_vec& buffers, int send_flags, int *bytes_sent);
socket_t socket_;
sockaddr_in addr_;
sockaddr_in remote_address_;
sockaddr_in local_address_;
int rce_flags_;
/* __sendto() calls these handlers in order before sending the packet */

View File

@ -100,31 +100,41 @@ rtp_error_t uvgrtp::media_stream::init_connection()
UVG_LOG_ERROR("Failed to make the socket non-blocking!");
#endif
// no reason to fail sending even if binding fails so we set remote address first
remote_sockaddr_ = socket_->create_sockaddr(AF_INET, remote_address_, dst_port_);
socket_->set_sockaddr(remote_sockaddr_);
if (local_address_ != "") {
sockaddr_in bind_addr = socket_->create_sockaddr(AF_INET, local_address_, src_port_);
socket_t socket = socket_->get_raw_socket();
if (bind(socket, (struct sockaddr *)&bind_addr, sizeof(bind_addr)) == -1) {
if ((ret = socket_->bind(bind_addr)) != RTP_OK)
{
log_platform_error("bind(2) failed");
return RTP_BIND_ERROR;
}
} else {
if ((ret = socket_->bind(AF_INET, INADDR_ANY, src_port_)) != RTP_OK)
return ret;
}
}
else
{
if ((ret = socket_->bind(AF_INET, INADDR_ANY, src_port_)) != RTP_OK)
{
log_platform_error("bind(2) to any failed");
return ret;
}
}
/* Set the default UDP send/recv buffer sizes to 4MB as on Windows
* the default size is way too small for a larger video conference */
int buf_size = 4 * 1024 * 1024;
if ((ret = socket_->setsockopt(SOL_SOCKET, SO_SNDBUF, (const char *)&buf_size, sizeof(int))) != RTP_OK)
if ((ret = socket_->setsockopt(SOL_SOCKET, SO_SNDBUF, (const char*)&buf_size, sizeof(int))) != RTP_OK)
{
return ret;
}
if ((ret = socket_->setsockopt(SOL_SOCKET, SO_RCVBUF, (const char *)&buf_size, sizeof(int))) != RTP_OK)
if ((ret = socket_->setsockopt(SOL_SOCKET, SO_RCVBUF, (const char*)&buf_size, sizeof(int))) != RTP_OK)
{
return ret;
remote_sockaddr_ = socket_->create_sockaddr(AF_INET, remote_address_, dst_port_);
socket_->set_sockaddr(remote_sockaddr_);
}
return ret;
}

View File

@ -30,7 +30,8 @@ using namespace mingw;
uvgrtp::socket::socket(int rce_flags):
socket_(-1),
rce_flags_(rce_flags)
rce_flags_(rce_flags),
local_address_()
{}
uvgrtp::socket::~socket()
@ -81,23 +82,30 @@ rtp_error_t uvgrtp::socket::setsockopt(int level, int optname, const void *optva
rtp_error_t uvgrtp::socket::bind(short family, unsigned host, short port)
{
assert(family == AF_INET);
local_address_ = create_sockaddr(family, host, port);
return bind(local_address_);
}
sockaddr_in addr = create_sockaddr(family, host, port);
rtp_error_t uvgrtp::socket::bind(sockaddr_in& local_address)
{
local_address_ = local_address;
if (::bind(socket_, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
UVG_LOG_DEBUG("Binding to address %s", sockaddr_to_string(local_address_).c_str());
if (::bind(socket_, (struct sockaddr*)&local_address_, sizeof(local_address_)) < 0) {
#ifdef _WIN32
win_get_last_error();
#else
fprintf(stderr, "%s\n", strerror(errno));
#endif
UVG_LOG_ERROR("Binding to port %u failed!", port);
UVG_LOG_ERROR("Binding to port %u failed!", local_address_.sin_port);
return RTP_BIND_ERROR;
}
return RTP_OK;
}
sockaddr_in uvgrtp::socket::create_sockaddr(short family, unsigned host, short port)
sockaddr_in uvgrtp::socket::create_sockaddr(short family, unsigned host, short port) const
{
assert(family == AF_INET);
@ -112,7 +120,7 @@ sockaddr_in uvgrtp::socket::create_sockaddr(short family, unsigned host, short p
return addr;
}
sockaddr_in uvgrtp::socket::create_sockaddr(short family, std::string host, short port)
sockaddr_in uvgrtp::socket::create_sockaddr(short family, std::string host, short port) const
{
assert(family == AF_INET);
@ -127,9 +135,38 @@ sockaddr_in uvgrtp::socket::create_sockaddr(short family, std::string host, shor
return addr;
}
std::string uvgrtp::socket::get_socket_path_string() const
{
return sockaddr_to_string(local_address_) + " -> " + sockaddr_to_string(remote_address_);
}
std::string uvgrtp::socket::sockaddr_to_string(const sockaddr_in& addr) const
{
char* c_string = new char[INET_ADDRSTRLEN];
memset(c_string, 0, INET_ADDRSTRLEN);
switch (addr.sin_family)
{
case AF_INET:
{
inet_ntop(AF_INET, &addr.sin_addr, c_string, INET_ADDRSTRLEN);
break;
}
case AF_INET6:
{
inet_ntop(AF_INET6, &addr.sin_addr, c_string, INET_ADDRSTRLEN);
break;
}
}
std::string string(c_string);
string.append(":" + std::to_string(ntohs(addr.sin_port)));
return string;
}
void uvgrtp::socket::set_sockaddr(sockaddr_in addr)
{
addr_ = addr;
remote_address_ = addr;
}
socket_t& uvgrtp::socket::get_raw_socket()
@ -137,7 +174,6 @@ socket_t& uvgrtp::socket::get_raw_socket()
return socket_;
}
rtp_error_t uvgrtp::socket::install_handler(void *arg, packet_handler_vec handler)
{
if (!handler)
@ -158,7 +194,7 @@ rtp_error_t uvgrtp::socket::__sendto(sockaddr_in& addr, uint8_t *buf, size_t buf
int nsend = 0;
#ifndef _WIN32
if ((nsend = ::sendto(socket_, buf, buf_len, send_flags, (const struct sockaddr *)&addr, sizeof(addr_))) == -1) {
if ((nsend = ::sendto(socket_, buf, buf_len, send_flags, (const struct sockaddr *)&addr, sizeof(addr))) == -1) {
UVG_LOG_ERROR("Failed to send data: %s", strerror(errno));
if (bytes_sent)
@ -172,9 +208,11 @@ rtp_error_t uvgrtp::socket::__sendto(sockaddr_in& addr, uint8_t *buf, size_t buf
data_buf.buf = (char *)buf;
data_buf.len = (ULONG)buf_len;
if (WSASendTo(socket_, &data_buf, 1, &sent_bytes, send_flags, (const struct sockaddr *)&addr, sizeof(addr_), nullptr, nullptr) == -1) {
if (WSASendTo(socket_, &data_buf, 1, &sent_bytes, send_flags, (const struct sockaddr *)&addr, sizeof(addr), nullptr, nullptr) == -1) {
win_get_last_error();
UVG_LOG_ERROR("Failed to send to %s", sockaddr_to_string(addr).c_str());
if (bytes_sent)
*bytes_sent = -1;
return RTP_SEND_ERROR;
@ -194,12 +232,12 @@ rtp_error_t uvgrtp::socket::__sendto(sockaddr_in& addr, uint8_t *buf, size_t buf
rtp_error_t uvgrtp::socket::sendto(uint8_t *buf, size_t buf_len, int send_flags)
{
return __sendto(addr_, buf, buf_len, send_flags, nullptr);
return __sendto(remote_address_, buf, buf_len, send_flags, nullptr);
}
rtp_error_t uvgrtp::socket::sendto(uint8_t *buf, size_t buf_len, int send_flags, int *bytes_sent)
{
return __sendto(addr_, buf, buf_len, send_flags, bytes_sent);
return __sendto(remote_address_, buf, buf_len, send_flags, bytes_sent);
}
rtp_error_t uvgrtp::socket::sendto(sockaddr_in& addr, uint8_t *buf, size_t buf_len, int send_flags, int *bytes_sent)
@ -257,9 +295,11 @@ rtp_error_t uvgrtp::socket::__sendtov(
}
if (WSASendTo(socket_, buffers_, (DWORD)buffers.size(), &sent_bytes, send_flags,
(SOCKADDR *)&addr, sizeof(addr_), nullptr, nullptr) == -1) {
(SOCKADDR *)&addr, sizeof(addr), nullptr, nullptr) == -1) {
win_get_last_error();
UVG_LOG_ERROR("Failed to send to %s", sockaddr_to_string(addr).c_str());
set_bytes(bytes_sent, -1);
return RTP_SEND_ERROR;
}
@ -286,7 +326,7 @@ rtp_error_t uvgrtp::socket::sendto(buf_vec& buffers, int send_flags)
}
}
return __sendtov(addr_, buffers, send_flags, nullptr);
return __sendtov(remote_address_, buffers, send_flags, nullptr);
}
rtp_error_t uvgrtp::socket::sendto(buf_vec& buffers, int send_flags, int *bytes_sent)
@ -300,7 +340,7 @@ rtp_error_t uvgrtp::socket::sendto(buf_vec& buffers, int send_flags, int *bytes_
}
}
return __sendtov(addr_, buffers, send_flags, bytes_sent);
return __sendtov(remote_address_, buffers, send_flags, bytes_sent);
}
rtp_error_t uvgrtp::socket::sendto(sockaddr_in& addr, buf_vec& buffers, int send_flags)
@ -408,7 +448,7 @@ send_:
&sent_bytes,
send_flags,
(SOCKADDR *)&addr,
sizeof(addr_),
sizeof(addr),
nullptr,
nullptr
);
@ -425,6 +465,8 @@ send_:
{
UVG_LOG_DEBUG("WSASendTo failed with error %li", error);
log_platform_error("WSASendTo() failed");
UVG_LOG_ERROR("Failed to send to %s", sockaddr_to_string(addr).c_str());
}
set_bytes(bytes_sent, -1);
@ -454,7 +496,7 @@ rtp_error_t uvgrtp::socket::sendto(pkt_vec& buffers, int send_flags)
}
}
return __sendtov(addr_, buffers, send_flags, nullptr);
return __sendtov(remote_address_, buffers, send_flags, nullptr);
}
rtp_error_t uvgrtp::socket::sendto(pkt_vec& buffers, int send_flags, int *bytes_sent)
@ -470,7 +512,7 @@ rtp_error_t uvgrtp::socket::sendto(pkt_vec& buffers, int send_flags, int *bytes_
}
}
return __sendtov(addr_, buffers, send_flags, bytes_sent);
return __sendtov(remote_address_, buffers, send_flags, bytes_sent);
}
rtp_error_t uvgrtp::socket::sendto(sockaddr_in& addr, pkt_vec& buffers, int send_flags)
@ -642,5 +684,5 @@ rtp_error_t uvgrtp::socket::recvfrom(uint8_t *buf, size_t buf_len, int recv_flag
sockaddr_in& uvgrtp::socket::get_out_address()
{
return addr_;
return remote_address_;
}