The authentication tag for each packet is stored inside the active
transaction and they are destroyed when the transaction is deallocated.
This way neither Socket nor SRTP needs to worry about (de)allocation
of those tags.
The authentication tag occupies the last slot in the pkt_vec structure
of each packet so it's easily accessible for the security layer when
calculating the checksum and guaranteed to be there if
RCE_SRTP_AUTHENTICATE_RTP has been provided.
Move frame queue to Media object and implement the generic push API
using a frame queue
This change temporarily disable the fragmentation of generic frames
Introduce buf_vec and pkt_vec structures which enable cross-platform
scatter/gather I/O. This supersedes the previous Linux-only mmsghdr
hack. Buf_vec contains buffers of a single RTP frame
whereas pkt_vec contains multiple buf_vec structures that are sent
all at once when flush_queue() is called.
From now on all media formats should use frame queue to implement
RTP frame sending. This is because internally the frame queue
updates RTP header information and it can inject additional fields
to the RTP frame such as an authentication tag.
uvgRTP can install handler f.ex. for collecting RTCP sender statistics
information or to install SRTP encryption handler.
This way these unrelated objects don't have to be passed to src/socket.cc
and it will only contain code pertaining to actual socket operations
This kind of functionality is now provided by RTP packet dispatcher
for receive-functionality and similar kind of send functionality
is implemented very soon
Some packet handlers (such as RTCP) may need access to the parent
object or they may require some additional data from outside the
packet handler that is required when processing the packet.
Having a 1100 lines long file is not manageable so split RTCP
code into different files by packet type and leave all the
session-related code to src/rtcp.cc
Because most packet handlers do not require the raw UDP datagram
received through the socket, it makes little sense to relay those
parameters to them.
Additionally, there's a clear distinction between crafting
an RTP frame and operating on it so having one handler type
for both operations is not the best design choice.
Thus the packet handlers are divided into primary and auxiliary
handlers. Primary handlers are responsible for creating a packet
that the auxiliary handlers can operate on and auxiliary handlers
are responsible for doing all other operations on the packet such as
gathering sessions statistic information or decrypting the packet.
RTCP is used to gather session statistics and detect SSRC collisions
so all packets should be relayd to the RTCP layer for monitoring
even if RTCP packets are not being sent.
If RTCP Sender/Receiver reports are needed, RCE_RTCP should be given
when creating a media stream.
Indicate to the main thread through a mutex that the packet dispatcher
object can be destroyed. If this is not done, there's race condition
that can result into a segmentation fault as the dispatcher object
could be destroyed before it stops running.
Packet dispatcher does not need to store the socket because it
is passed to the actual runner when the packet dispatcher is started.
This also fixes a bug where the socket's destructor is called right
after the packet dispatcher's constructor
Remove the old generic interface and replace it with the push_frame()
implemented in some previous commit and with the new packet handler
implemented in this commit.
All media formats that do not require extra processing (such as Opus)
should use the generic interface.
Deprecate the old sender/receiver architecture from vanilla uvgRTP
and start using RTP packet dispatcher for incoming frames and Media
object for outgoing frames.
When a complete RTP frame has been received, the packet handler
must return the frame to RTP packet dispatcher which then returns
the frame to user either through frame queue or receive hook
Media is the base class from which all other media formats inherit
the common operations.
Media object contains two push_frame()s: one for normal pointers and
one for smart pointers. It also contains a packet handler which is
called by the RTP packet dispatcher when a UDP datagram is received.
All media formats must implement packet_handler() and __push_frame()
methods. If the media media format does not require any extra processing
(such as Opus), it can directly use the Media object and its implementation
of __push_frame() and packet_handler().
Media object implements the generic interface which supports sending
any kind of data and a uvgRTP-specific way of fragmenting/reconstructing
generic RTP frames which can be enabled with RCE_FRAGMENT_GENERIC.
Only RTP context and socketa are needed for the operations performed
by the frame queue so passing them to a constructor is much simpler
than passing sender to every function call and accessing the
context/socket through that.
Packet dispatcher is responsible for doing receive-related socket operations
and dispatching the received UDP datagram to the installed packet handlers.
Packet dispatcher goes through all installed handlers until a suitable
handler for the packet is found.
By default authentication is disabled for RTP but in can be enabled
by giving RCE_SRTP_AUTHENTICATE_RTP when creating a media stream.
When security layer gets a packet, outgoing or incoming, it will add
an authentication tag to the packet or verify the tag, respectively.
This implementation is not perfect. The largest issue is
that there is no proper packet dispatcher so late ZRTP packets
can cause some real trouble.
This and a few other issues will be addresses later on when the
architecture of packet reception and the whole socket layer is improved.
Store the size to context because different streams may have different
maximum payload sizes. For example, an SRTP stream with RTP authentication
enabled has a smaller payload size than a normal RTP stream.
uvgRTP can install handler f.ex. for collecting RTCP sender statistics
information or to install SRTP encryption handler.
This way these unrelated objects don't have to be passed to src/socket.cc
and it will only contain code pertaining to actual socket operations
This kind of functionality is now provided by RTP packet dispatcher
for receive-functionality and similar kind of send functionality
is implemented very soon
Some packet handlers (such as RTCP) may need access to the parent
object or they may require some additional data from outside the
packet handler that is required when processing the packet.
Having a 1100 lines long file is not manageable so split RTCP
code into different files by packet type and leave all the
session-related code to src/rtcp.cc
Because most packet handlers do not require the raw UDP datagram
received through the socket, it makes little sense to relay those
parameters to them.
Additionally, there's a clear distinction between crafting
an RTP frame and operating on it so having one handler type
for both operations is not the best design choice.
Thus the packet handlers are divided into primary and auxiliary
handlers. Primary handlers are responsible for creating a packet
that the auxiliary handlers can operate on and auxiliary handlers
are responsible for doing all other operations on the packet such as
gathering sessions statistic information or decrypting the packet.
RTCP is used to gather session statistics and detect SSRC collisions
so all packets should be relayd to the RTCP layer for monitoring
even if RTCP packets are not being sent.
If RTCP Sender/Receiver reports are needed, RCE_RTCP should be given
when creating a media stream.
Indicate to the main thread through a mutex that the packet dispatcher
object can be destroyed. If this is not done, there's race condition
that can result into a segmentation fault as the dispatcher object
could be destroyed before it stops running.
Packet dispatcher does not need to store the socket because it
is passed to the actual runner when the packet dispatcher is started.
This also fixes a bug where the socket's destructor is called right
after the packet dispatcher's constructor
Remove the old generic interface and replace it with the push_frame()
implemented in some previous commit and with the new packet handler
implemented in this commit.
All media formats that do not require extra processing (such as Opus)
should use the generic interface.
Deprecate the old sender/receiver architecture from vanilla uvgRTP
and start using RTP packet dispatcher for incoming frames and Media
object for outgoing frames.
When a complete RTP frame has been received, the packet handler
must return the frame to RTP packet dispatcher which then returns
the frame to user either through frame queue or receive hook
Media is the base class from which all other media formats inherit
the common operations.
Media object contains two push_frame()s: one for normal pointers and
one for smart pointers. It also contains a packet handler which is
called by the RTP packet dispatcher when a UDP datagram is received.
All media formats must implement packet_handler() and __push_frame()
methods. If the media media format does not require any extra processing
(such as Opus), it can directly use the Media object and its implementation
of __push_frame() and packet_handler().
Media object implements the generic interface which supports sending
any kind of data and a uvgRTP-specific way of fragmenting/reconstructing
generic RTP frames which can be enabled with RCE_FRAGMENT_GENERIC.
Only RTP context and socketa are needed for the operations performed
by the frame queue so passing them to a constructor is much simpler
than passing sender to every function call and accessing the
context/socket through that.
Packet dispatcher is responsible for doing receive-related socket operations
and dispatching the received UDP datagram to the installed packet handlers.
Packet dispatcher goes through all installed handlers until a suitable
handler for the packet is found.
By default authentication is disabled for RTP but in can be enabled
by giving RCE_SRTP_AUTHENTICATE_RTP when creating a media stream.
When security layer gets a packet, outgoing or incoming, it will add
an authentication tag to the packet or verify the tag, respectively.
This implementation is not perfect. The largest issue is
that there is no proper packet dispatcher so late ZRTP packets
can cause some real trouble.
This and a few other issues will be addresses later on when the
architecture of packet reception and the whole socket layer is improved.
Store the size to context because different streams may have different
maximum payload sizes. For example, an SRTP stream with RTP authentication
enabled has a smaller payload size than a normal RTP stream.
This may be useful in situations where a user wishes to join a
conference call but does not wish to send any data only receiver or
vice versa.
This unidirectionality will also dictate the role for the media_stream's
RTCP object
Instead of using uvgRTP's internal RTP timestamps, let user specify
timestamp for the media when push_frame() is called.
Instead of propagating the timestamp through the send stack, store
the timestamp value temporarily to the RTP context of the media
stream and reset it after push_frame() is done.
User should not mix and match uvgRTP's internal RTP timestamps with
custom timestamps so either all of the calls or none of the calls should
given a timestamp to push_frame().
Custom timestamps should be increased in accordance with the media clock
rate, otherwise problems may occur with media reception.
Instead of blocking until the library is destroyed, add ability
to block at most N milliseconds before returning.
The code returns early if a frame is received within the specified
timeframe but will block at most "timeout "milliseconds
Because the architecture has changed a bit, the context is initialized
only after add_srtp_ctx() has been called to prevent the user from
sending unencrypted messages.
Remove old context configuration flags that are no longer used,
convert configure_ctx() to work as a handler for all RCC_* flags
and use default values in sender/receiver/queue during initialization
This flag indicates to kvzRTP that the input data given to push_frame()
is writable and the encryption can be done in-place.
By default kvzRTP assumes that the input cannot be modified and creates
a copy of the input data.
Having separate enums for general configuration and media configuration
might be too confusing given that they are passed to kvzRTP using same
variable and the configuration values must not clash with each other
so the second enum's values would have to start from RCE_LAST which
might look weird