Skip to content

Commit

Permalink
Merge pull request #10 from widgetii/locks_n_fill
Browse files Browse the repository at this point in the history
Fix race conditions in TCP streams and potential internal buffers overrun
  • Loading branch information
widgetii authored May 13, 2023
2 parents 4a73d94 + 91a5b91 commit 750fa54
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 4 deletions.
3 changes: 3 additions & 0 deletions include/smolrtsp/nal_transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,6 @@ int SmolRTSP_NalTransport_send_packet(
* usage.
*/
declImplExtern99(SmolRTSP_Droppable, SmolRTSP_NalTransport);

bool
SmolRTSP_NalTransport_is_full(SmolRTSP_NalTransport *self);
3 changes: 3 additions & 0 deletions include/smolrtsp/rtp_transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,6 @@ int SmolRTSP_RtpTransport_send_packet(
* usage.
*/
declImplExtern99(SmolRTSP_Droppable, SmolRTSP_RtpTransport);

bool
SmolRTSP_RtpTransport_is_full(SmolRTSP_RtpTransport *self);
8 changes: 5 additions & 3 deletions include/smolrtsp/transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
* @return -1 if an I/O error occurred and sets `errno` appropriately, 0 \
* on success. \
*/ \
vfunc99(int, transmit, VSelf99, SmolRTSP_IoVecSlice bufs)
vfunc99(int, transmit, VSelf99, SmolRTSP_IoVecSlice bufs) \
vfunc99(bool, is_full, VSelf99)

/**
* The superinterfaces of #SmolRTSP_Transport_IFACE.
Expand All @@ -51,8 +52,9 @@ interface99(SmolRTSP_Transport);
*
* @pre `w.self && w.vptr`
*/
SmolRTSP_Transport smolrtsp_transport_tcp(SmolRTSP_Writer w, uint8_t channel_id)
SMOLRTSP_PRIV_MUST_USE;
SmolRTSP_Transport smolrtsp_transport_tcp(
SmolRTSP_Writer w, uint8_t channel_id,
size_t max_buffer) SMOLRTSP_PRIV_MUST_USE;

/**
* Creates a new UDP transport.
Expand Down
15 changes: 15 additions & 0 deletions include/smolrtsp/writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@
*/ \
vfunc99(ssize_t, write, VSelf99, CharSlice99 data) \
\
/* \
* Lock writer to prevent race conditions on TCP interleaved channels \
*/ \
vfunc99(void, lock, VSelf99) \
\
/* \
* Unlock writer locked by `lock` \
*/ \
vfunc99(void, unlock, VSelf99) \
\
/* \
* Get current size of output buffer \
*/ \
vfunc99(size_t, filled, VSelf99) \
\
/* \
* Writes a formatted string into itself. \
* \
Expand Down
5 changes: 5 additions & 0 deletions src/nal_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ static void SmolRTSP_NalTransport_drop(VSelf) {

implExtern(SmolRTSP_Droppable, SmolRTSP_NalTransport);

bool
SmolRTSP_NalTransport_is_full(SmolRTSP_NalTransport *self) {
return SmolRTSP_RtpTransport_is_full(self->transport);
}

int SmolRTSP_NalTransport_send_packet(
SmolRTSP_NalTransport *self, SmolRTSP_RtpTimestamp ts,
SmolRTSP_NalUnit nalu) {
Expand Down
4 changes: 4 additions & 0 deletions src/rtp_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,7 @@ compute_timestamp(SmolRTSP_RtpTimestamp ts, uint32_t clock_rate) {

return 0;
}

bool SmolRTSP_RtpTransport_is_full(SmolRTSP_RtpTransport *self) {
return VCALL(self->transport, is_full);
}
15 changes: 14 additions & 1 deletion src/transport/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,21 @@
typedef struct {
SmolRTSP_Writer w;
int channel_id;
size_t max_buffer;
} SmolRTSP_TcpTransport;

declImpl(SmolRTSP_Transport, SmolRTSP_TcpTransport);

SmolRTSP_Transport
smolrtsp_transport_tcp(SmolRTSP_Writer w, uint8_t channel_id) {
smolrtsp_transport_tcp(SmolRTSP_Writer w, uint8_t channel_id, size_t max_buffer) {
assert(w.self && w.vptr);

SmolRTSP_TcpTransport *self = malloc(sizeof *self);
assert(self);

self->w = w;
self->channel_id = channel_id;
self->max_buffer = max_buffer;

return DYN(SmolRTSP_TcpTransport, SmolRTSP_Transport, self);
}
Expand All @@ -49,9 +51,11 @@ static int SmolRTSP_TcpTransport_transmit(VSelf, SmolRTSP_IoVecSlice bufs) {
const uint32_t header =
smolrtsp_interleaved_header(self->channel_id, htons(total_bytes));

VCALL(self->w, lock);
ssize_t ret =
VCALL(self->w, write, CharSlice99_new((char *)&header, sizeof header));
if (ret != sizeof header) {
VCALL(self->w, unlock);
return -1;
}

Expand All @@ -60,11 +64,20 @@ static int SmolRTSP_TcpTransport_transmit(VSelf, SmolRTSP_IoVecSlice bufs) {
CharSlice99_new(bufs.ptr[i].iov_base, bufs.ptr[i].iov_len);
ret = VCALL(self->w, write, vec);
if (ret != (ssize_t)vec.len) {
VCALL(self->w, unlock);
return -1;
}
}
VCALL(self->w, unlock);

return 0;
}

static bool SmolRTSP_TcpTransport_is_full(VSelf) {
VSELF(SmolRTSP_TcpTransport);
assert(self);

return VCALL(self->w, filled) > self->max_buffer;
}

impl(SmolRTSP_Transport, SmolRTSP_TcpTransport);
7 changes: 7 additions & 0 deletions src/transport/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ static int SmolRTSP_UdpTransport_transmit(VSelf, SmolRTSP_IoVecSlice bufs) {
return send_packet(self, msg);
}

static bool SmolRTSP_UdpTransport_is_full(VSelf) {
VSELF(SmolRTSP_UdpTransport);
(void)self;

return false;
}

impl(SmolRTSP_Transport, SmolRTSP_UdpTransport);

static int send_packet(SmolRTSP_UdpTransport *self, struct msghdr message) {
Expand Down
16 changes: 16 additions & 0 deletions src/writer/fd.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ static ssize_t FdWriter_write(VSelf, CharSlice99 data) {
return write(*self, data.ptr, data.len);
}

static void FdWriter_lock(VSelf) {
VSELF(FdWriter);
(void)self;
}

static void FdWriter_unlock(VSelf) {
VSELF(FdWriter);
(void)self;
}

static size_t FdWriter_filled(VSelf) {
VSELF(FdWriter);
(void)self;
return 0;
}

static int FdWriter_vwritef(VSelf, const char *restrict fmt, va_list ap) {
VSELF(FdWriter);

Expand Down
16 changes: 16 additions & 0 deletions src/writer/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ static ssize_t FileWriter_write(VSelf, CharSlice99 data) {
return ret;
}

static void FileWriter_lock(VSelf) {
VSELF(FileWriter);
(void)self;
}

static void FileWriter_unlock(VSelf) {
VSELF(FileWriter);
(void)self;
}

static size_t FileWriter_filled(VSelf) {
VSELF(FileWriter);
(void)self;
return 0;
}

static int FileWriter_vwritef(VSelf, const char *restrict fmt, va_list ap) {
VSELF(FileWriter);

Expand Down
16 changes: 16 additions & 0 deletions src/writer/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ static ssize_t StringWriter_write(VSelf, CharSlice99 data) {
return data.len;
}

static void StringWriter_lock(VSelf) {
VSELF(StringWriter);
(void)self;
}

static void StringWriter_unlock(VSelf) {
VSELF(StringWriter);
(void)self;
}

static size_t StringWriter_filled(VSelf) {
VSELF(StringWriter);
(void)self;
return 0;
}

static int StringWriter_vwritef(VSelf, const char *restrict fmt, va_list ap) {
VSELF(StringWriter);

Expand Down

0 comments on commit 750fa54

Please sign in to comment.