Add ability to bound the session to user-specificied address

This commit is contained in:
Aaro Altonen 2020-04-03 11:45:19 +03:00
parent 41132e6ffc
commit dff6094561
6 changed files with 68 additions and 5 deletions

View File

@ -40,6 +40,14 @@ kvz_rtp::session *kvz_rtp::context::create_session(std::string address)
return new kvz_rtp::session(address);
}
kvz_rtp::session *kvz_rtp::context::create_session(std::string remote_addr, std::string local_addr)
{
if (remote_addr == "" || local_addr == "")
return nullptr;
return new kvz_rtp::session(remote_addr, local_addr);
}
rtp_error_t kvz_rtp::context::destroy_session(kvz_rtp::session *session)
{
if (!session)

View File

@ -10,9 +10,13 @@ namespace kvz_rtp {
context();
~context();
/* Create new session if "addr" is unique or return pointer to previously created session */
/* Create a new session with remote participant */
kvz_rtp::session *create_session(std::string addr);
/* Create a new session with remote participant
* Bind ourselves to interface pointed to by "local_addr" */
kvz_rtp::session *create_session(std::string remote_addr, std::string local_addr);
/* Destroy session and all media streams
*
* Return RTP_INVALID_VALUE if "session" is nullptr

View File

@ -13,6 +13,7 @@ kvz_rtp::media_stream::media_stream(std::string addr, int src_port, int dst_port
{
fmt_ = fmt;
addr_ = addr;
laddr_ = "";
flags_ = flags;
src_port_ = src_port;
dst_port_ = dst_port;
@ -21,6 +22,16 @@ kvz_rtp::media_stream::media_stream(std::string addr, int src_port, int dst_port
ctx_config_.flags = flags;
}
kvz_rtp::media_stream::media_stream(
std::string remote_addr, std::string local_addr,
int src_port, int dst_port,
rtp_format_t fmt, int flags
):
media_stream(remote_addr, src_port, dst_port, fmt, flags)
{
laddr_ = local_addr;
}
kvz_rtp::media_stream::~media_stream()
{
receiver_->stop();
@ -47,8 +58,23 @@ rtp_error_t kvz_rtp::media_stream::init_connection()
LOG_ERROR("Failed to make the socket non-blocking!");
#endif
if ((ret = socket_.bind(AF_INET, INADDR_ANY, src_port_)) != RTP_OK)
return ret;
if (laddr_ != "") {
sockaddr_in bind_addr = socket_.create_sockaddr(AF_INET, laddr_, src_port_);
socket_t socket = socket_.get_raw_socket();
if (bind(socket, (struct sockaddr *)&bind_addr, sizeof(bind_addr)) == -1) {
#ifdef __linux__
LOG_ERROR("Bind failed: %s!", strerror(errno));
#else
LOG_ERROR("Bind failed!");
win_get_last_error();
#endif
return RTP_BIND_ERROR;
}
} else {
if ((ret = socket_.bind(AF_INET, INADDR_ANY, src_port_)) != RTP_OK)
return ret;
}
addr_out_ = socket_.create_sockaddr(AF_INET, addr_, dst_port_);
socket_.set_sockaddr(addr_out_);

View File

@ -15,6 +15,7 @@ namespace kvz_rtp {
class media_stream {
public:
media_stream(std::string addr, int src_port, int dst_port, rtp_format_t fmt, int flags);
media_stream(std::string remote_addr, std::string local_addr, int src_port, int dst_port, rtp_format_t fmt, int flags);
~media_stream();
/* Initialize traditional RTP session
@ -125,6 +126,7 @@ namespace kvz_rtp {
sockaddr_in addr_out_;
std::string addr_;
std::string laddr_;
int src_port_;
int dst_port_;
rtp_format_t fmt_;

View File

@ -5,10 +5,17 @@ kvz_rtp::session::session(std::string addr):
#ifdef __RTP_CRYPTO__
zrtp_(nullptr),
#endif
addr_(addr)
addr_(addr),
laddr_("")
{
}
kvz_rtp::session::session(std::string remote_addr, std::string local_addr):
session(remote_addr)
{
laddr_ = local_addr;
}
kvz_rtp::session::~session()
{
for (auto&i : streams_) {
@ -23,7 +30,19 @@ kvz_rtp::session::~session()
kvz_rtp::media_stream *kvz_rtp::session::create_stream(int r_port, int s_port, rtp_format_t fmt, int flags)
{
kvz_rtp::media_stream *stream = new kvz_rtp::media_stream(addr_, r_port, s_port, fmt, flags);
kvz_rtp::media_stream *stream = nullptr;
if (laddr_ == "")
stream = new kvz_rtp::media_stream(addr_, r_port, s_port, fmt, flags);
else
stream = new kvz_rtp::media_stream(addr_, laddr_, r_port, s_port, fmt, flags);
if (!stream) {
LOG_ERROR("Failed to create media stream for %s:%d -> %s:%d",
(laddr_ == "") ? "0.0.0.0" : laddr_.c_str(), s_port, addr_.c_str(), r_port
);
return nullptr;
}
#ifdef __RTP_CRYPTO__
int zrtp_flags = (RCE_SRTP | RCE_SRTP_KMNGMNT_ZRTP);

View File

@ -11,6 +11,7 @@ namespace kvz_rtp {
class session {
public:
session(std::string addr);
session(std::string remote_addr, std::string local_addr);
~session();
/* Create bidirectional media stream for media format "fmt"
@ -43,6 +44,9 @@ namespace kvz_rtp {
/* Each RTP multimedia session is always IP-specific */
std::string addr_;
/* If user so wishes, the session can be bound to a certain interface */
std::string laddr_;
/* All media streams of this session */
std::unordered_map<uint32_t, kvz_rtp::media_stream *> streams_;
};