Create ZRTP packet handler

This commit is contained in:
Aaro Altonen 2020-08-01 09:58:28 +03:00
parent 14ecd34fdd
commit 157b21a05c
4 changed files with 70 additions and 3 deletions

View File

@ -22,6 +22,16 @@ namespace uvg_rtp {
/* TODO: */
ssize_t get_msg(void *ptr, size_t len);
/* ZRTP packet handler is used after ZRTP state initialization has finished
* and media exchange has started. RTP packet dispatcher gives the packet
* to "zrtp_handler" which then checks whether the packet is a ZRTP packet
* or not and processes it accordingly.
*
* Return RTP_OK on success
* Return RTP_PKT_NOT_HANDLED if "buffer" does not contain a ZRTP message
* Return RTP_GENERIC_ERROR if "buffer" contains an invalid ZRTP message */
rtp_error_t zrtp_handler(ssize_t size, void *buffer);
private:
uint8_t *mem_;
size_t len_;

View File

@ -36,6 +36,8 @@ const int MAX_PACKET = 65536;
const int MAX_PAYLOAD = 1443;
typedef enum RTP_ERROR {
RTP_PKT_MODIFIED = 4, /* packet was modified by the layer (see src/pkt_dispatch.cc) */
RTP_PKT_NOT_HANDLED = 3, /* packet does not belong to this layer */
RTP_INTERRUPTED = 2,
RTP_NOT_READY = 1,
RTP_OK = 0,

View File

@ -216,4 +216,47 @@ ssize_t uvg_rtp::zrtp_msg::receiver::get_msg(void *ptr, size_t len)
memcpy(ptr, mem_, cpy_len);
return rlen_;
}
rtp_error_t uvg_rtp::zrtp_msg::receiver::zrtp_handler(ssize_t size, void *buffer)
{
zrtp_msg *msg = (zrtp_msg *)buffer;
/* not a ZRTP packet */
if (msg->header.version || msg->header.magic != ZRTP_HEADER_MAGIC || msg->magic != ZRTP_MSG_MAGIC)
return RTP_PKT_NOT_HANDLED;
switch (msg->msgblock) {
/* None of these messages should be received by this stream
* during this stage so return RTP_GENERIC_ERROR to indicate that the packet
* is invalid and that it should not be dispatched to other packet handlers */
case ZRTP_MSG_HELLO:
case ZRTP_MSG_HELLO_ACK:
case ZRTP_MSG_COMMIT:
case ZRTP_MSG_DH_PART1:
case ZRTP_MSG_DH_PART2:
case ZRTP_MSG_CONFIRM1:
case ZRTP_MSG_CONFIRM2:
case ZRTP_MSG_CONF2_ACK:
return RTP_GENERIC_ERROR;
case ZRTP_MSG_ERROR:
/* TODO: */
return RTP_OK;
case ZRTP_MSG_ERROR_ACK:
/* TODO: */
return RTP_OK;
case ZRTP_MSG_SAS_RELAY:
return RTP_OK;
case ZRTP_MSG_RELAY_ACK:
return RTP_OK;
case ZRTP_MSG_PING_ACK:
return RTP_OK;
/* TODO: goclear & co-opeartion with srtp */
}
}
#endif

View File

@ -52,7 +52,14 @@ std::vector<uvg_rtp::packet_handler>& uvg_rtp::pkt_dispatcher::get_handlers()
* For example, if runner detects an incoming ZRTP packet, that packet is immediately dispatched to the
* installed ZRTP handler if ZRTP has been enabled.
* Likewise, if RTP packet authentication has been enabled, runner validates the packet before passing
* it onto any other layer so all future work on the packet is not done in vain due to invalid data */
* it onto any other layer so all future work on the packet is not done in vain due to invalid data
*
* One piece of design choice that complicates the design of packet dispatcher a little is that the order
* of handlers is important. First handler must be ZRTP and then follows SRTP, RTP and finally media handlers.
* This requirement gives packet handler a clean and generic interface while giving a possibility to modify
* the packet in each of the called handlers if needed. For example SRTP handler verifies RTP authentication
* tag and decrypts the packet and RTP handler verifies the fields of the RTP packet and processes it into
* a more easily modifiable format for the media handler. */
static void runner(uvg_rtp::pkt_dispatcher *dispatcher, uvg_rtp::socket& socket)
{
int nread;
@ -90,13 +97,18 @@ static void runner(uvg_rtp::pkt_dispatcher *dispatcher, uvg_rtp::socket& socket)
switch ((ret = (*handler)(nread, recv_buffer))) {
/* packet was handled successfully or the packet was in some way corrupted */
case RTP_OK:
case RTP_GENERIC_ERROR:
break;
/* the received packet is not handled by the called handler */
/* the received packet is not handled at all or only partially by the called handler
* proceed to the next handler */
case RTP_PKT_NOT_HANDLED:
case RTP_PKT_MODIFIED:
continue;
case RTP_GENERIC_ERROR:
LOG_DEBUG("Received a corrputed packet!");
break;
default:
LOG_ERROR("Unknown error code from packet handler: %d", ret);
break;