Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
PRRT
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
37
Issues
37
List
Boards
Labels
Service Desk
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
LARN
PRRT
Commits
89e337a9
Commit
89e337a9
authored
Dec 19, 2017
by
Andreas Schmidt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for delivery rate estimation.
parent
21857f60
Pipeline
#1761
failed with stages
in 1 minute and 8 seconds
Changes
32
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
494 additions
and
103 deletions
+494
-103
prrt/cprrt.pxd
prrt/cprrt.pxd
+2
-1
prrt/proto/CMakeLists.txt
prrt/proto/CMakeLists.txt
+9
-8
prrt/proto/applicationConstraints.h
prrt/proto/applicationConstraints.h
+1
-1
prrt/proto/block.c
prrt/proto/block.c
+1
-1
prrt/proto/block.h
prrt/proto/block.h
+1
-1
prrt/proto/channelStateInformation.c
prrt/proto/channelStateInformation.c
+11
-0
prrt/proto/channelStateInformation.h
prrt/proto/channelStateInformation.h
+4
-1
prrt/proto/clock.h
prrt/proto/clock.h
+1
-1
prrt/proto/processes/dataReceiver.c
prrt/proto/processes/dataReceiver.c
+37
-13
prrt/proto/processes/dataReceiver.h
prrt/proto/processes/dataReceiver.h
+9
-0
prrt/proto/processes/dataTransmitter.c
prrt/proto/processes/dataTransmitter.c
+2
-2
prrt/proto/processes/feedbackReceiver.c
prrt/proto/processes/feedbackReceiver.c
+4
-0
prrt/proto/receiver.c
prrt/proto/receiver.c
+184
-24
prrt/proto/receiver.h
prrt/proto/receiver.h
+43
-5
prrt/proto/socket.c
prrt/proto/socket.c
+9
-3
prrt/proto/socket.h
prrt/proto/socket.h
+3
-2
prrt/proto/stores/dataPacketStore.c
prrt/proto/stores/dataPacketStore.c
+1
-1
prrt/proto/stores/deliveredPacketTable.c
prrt/proto/stores/deliveredPacketTable.c
+0
-1
prrt/proto/stores/deliveredPacketTable.h
prrt/proto/stores/deliveredPacketTable.h
+1
-1
prrt/proto/stores/inFlightPacketStore.c
prrt/proto/stores/inFlightPacketStore.c
+61
-0
prrt/proto/stores/inFlightPacketStore.h
prrt/proto/stores/inFlightPacketStore.h
+21
-0
prrt/proto/stores/packetDeliveryStore.c
prrt/proto/stores/packetDeliveryStore.c
+1
-1
prrt/proto/stores/packetTimeoutTable.h
prrt/proto/stores/packetTimeoutTable.h
+1
-1
prrt/proto/stores/receptionTable.h
prrt/proto/stores/receptionTable.h
+1
-1
prrt/proto/stores/repairBlockStore.h
prrt/proto/stores/repairBlockStore.h
+1
-1
prrt/proto/types/packet.c
prrt/proto/types/packet.c
+37
-14
prrt/proto/types/packet.h
prrt/proto/types/packet.h
+32
-13
prrt/proto/types/packetTimeout.h
prrt/proto/types/packetTimeout.h
+1
-1
prrt/prrt.pyx
prrt/prrt.pyx
+10
-1
prrt/util/dbg.h
prrt/util/dbg.h
+3
-2
tests/PrrtBlock_tests.cpp
tests/PrrtBlock_tests.cpp
+1
-1
tests/delivered_packet_table_tests.cpp
tests/delivered_packet_table_tests.cpp
+1
-1
No files found.
prrt/cprrt.pxd
View file @
89e337a9
...
...
@@ -71,7 +71,7 @@ cdef extern from "proto/block.h":
ctypedef
prrtBlock
PrrtBlock
cdef
extern
from
"proto/packet.h"
:
cdef
extern
from
"proto/
types/
packet.h"
:
cdef
struct
prrtPacket
:
uint8_t
type_priority
;
uint8_t
index
;
...
...
@@ -145,6 +145,7 @@ cdef extern from "proto/socket.h":
bint
PrrtSocket_uses_thread_pinning
(
PrrtSocket
*
socket
)
uint32_t
PrrtSocket_get_rtt
(
PrrtSocket
*
socket
)
float
PrrtSocket_get_plr
(
PrrtSocket
*
socket
)
uint32_t
PrrtSocket_get_delivery_rate
(
PrrtSocket
*
socket
)
bint
PrrtSocket_enable_thread_pinning
(
PrrtSocket
*
socket
)
cdef
extern
from
"proto/stores/packetDeliveryStore.h"
:
...
...
prrt/proto/CMakeLists.txt
View file @
89e337a9
...
...
@@ -3,22 +3,23 @@ add_library(PRRT ../defines.h
channelStateInformation.c channelStateInformation.h
clock.c clock.h
codingParams.c codingParams.h
packet.c packet.h
receiver.c receiver.h
socket.c socket.h
../xlap/xlap.c ../xlap/xlap.h
applicationConstraints.c applicationConstraints.h
vdmcode/block_code.c vdmcode/block_code.h
stores/deliveredPacketTable.c stores/deliveredPacketTable.h
types/lossStatistics.c types/lossStatistics.h
processes/dataReceiver.c processes/dataReceiver.h
processes/feedbackReceiver.c processes/feedbackReceiver.h
processes/dataTransmitter.c processes/dataTransmitter.h
stores/repairBlockStore.c stores/repairBlockStore.h
stores/packetTimeoutTable.c stores/packetTimeoutTable.h
stores/dataPacketStore.c stores/dataPacketStore.h
types/packetTimeout.c types/packetTimeout.h
stores/deliveredPacketTable.c stores/deliveredPacketTable.h
stores/inFlightPacketStore.c stores/inFlightPacketStore.h
stores/packetTimeoutTable.c stores/packetTimeoutTable.h
stores/packetDeliveryStore.c stores/packetDeliveryStore.h
stores/receptionTable.c stores/receptionTable.h
)
stores/receptionTable.c stores/receptionTable.h
stores/repairBlockStore.c stores/repairBlockStore.h
types/packetTimeout.c types/packetTimeout.h
types/lossStatistics.c types/lossStatistics.h
types/packet.c types/packet.h
vdmcode/block_code.c vdmcode/block_code.h
)
target_link_libraries
(
PRRT rt
)
prrt/proto/applicationConstraints.h
View file @
89e337a9
#ifndef PRRT_NETWORKCONTRAINTS_H
#define PRRT_NETWORKCONTRAINTS_H
#include "packet.h"
#include "
types/
packet.h"
typedef
struct
applicationConstraints
{
prrtTimedelta_t
targetDelay_us
;
...
...
prrt/proto/block.c
View file @
89e337a9
...
...
@@ -3,7 +3,7 @@
#include "../util/list.h"
#include "../util/dbg.h"
#include "../util/common.h"
#include "packet.h"
#include "
types/
packet.h"
#include "block.h"
static
void
gather_redundancy_packets
(
const
PrrtBlock
*
block_ptr
,
gf
*
const
*
fec
,
int16_t
*
idx_p
)
...
...
prrt/proto/block.h
View file @
89e337a9
...
...
@@ -3,7 +3,7 @@
#include <stdbool.h>
#include "codingParams.h"
#include "packet.h"
#include "
types/
packet.h"
#include "../util/list.h"
#include "vdmcode/block_code.h"
...
...
prrt/proto/channelStateInformation.c
View file @
89e337a9
...
...
@@ -14,6 +14,7 @@ PrrtChannelStateInformation * PrrtChannelStateInformation_create()
csi
->
rtprop
=
TIMESTAMP_SPACE
;
csi
->
rtprop_filter_length_us
=
2
*
1000
*
1000
;
// 2 seconds
csi
->
deliveryRate
=
0
;
return
csi
;
error:
...
...
@@ -41,6 +42,12 @@ void PrrtChannelStateInformation_update_plr(PrrtChannelStateInformation *csi, pr
}
void
PrrtChannelStateInformation_update_delivery_rate
(
PrrtChannelStateInformation
*
csi
,
prrtDeliveryRate_t
rate
)
{
pthread_mutex_lock
(
&
csi
->
lock
);
csi
->
deliveryRate
=
rate
;
pthread_mutex_unlock
(
&
csi
->
lock
);
}
prrtTimedelta_t
PrrtChannelStateInformation_get_rtprop
(
PrrtChannelStateInformation
*
csi
)
{
pthread_mutex_lock
(
&
csi
->
lock
);
...
...
@@ -61,3 +68,7 @@ bool PrrtChannelStateInformation_destroy(PrrtChannelStateInformation *csi)
prrtPacketLossRate_t
PrrtChannelStateInformation_get_plr
(
PrrtChannelStateInformation
*
csi
)
{
return
csi
->
plr
;
}
prrtDeliveryRate_t
PrrtChannelStateInformation_get_delivery_rate
(
PrrtChannelStateInformation
*
csi
)
{
return
csi
->
deliveryRate
;
}
\ No newline at end of file
prrt/proto/channelStateInformation.h
View file @
89e337a9
...
...
@@ -2,7 +2,7 @@
#define PRRT_CHANNELSTATEINFORMATION_H
#include <stdbool.h>
#include "packet.h"
#include "
types/
packet.h"
typedef
struct
prrtChannelStateInformation
{
pthread_mutex_t
lock
;
...
...
@@ -11,14 +11,17 @@ typedef struct prrtChannelStateInformation {
prrtTimedelta_t
rtprop_filter_length_us
;
bool
rtprop_expired
;
prrtPacketLossRate_t
plr
;
prrtDeliveryRate_t
deliveryRate
;
}
PrrtChannelStateInformation
;
PrrtChannelStateInformation
*
PrrtChannelStateInformation_create
(
void
);
void
PrrtChannelStateInformation_update_rtprop
(
PrrtChannelStateInformation
*
csi
,
prrtTimedelta_t
rtprop
);
prrtTimedelta_t
PrrtChannelStateInformation_get_rtprop
(
PrrtChannelStateInformation
*
csi
);
prrtDeliveryRate_t
PrrtChannelStateInformation_get_delivery_rate
(
PrrtChannelStateInformation
*
csi
);
prrtPacketLossRate_t
PrrtChannelStateInformation_get_plr
(
PrrtChannelStateInformation
*
csi
);
void
PrrtChannelStateInformation_update_plr
(
PrrtChannelStateInformation
*
csi
,
prrtSequenceNumber_t
erasures
,
prrtSequenceNumber_t
packets
);
void
PrrtChannelStateInformation_update_delivery_rate
(
PrrtChannelStateInformation
*
csi
,
prrtDeliveryRate_t
rate
);
bool
PrrtChannelStateInformation_destroy
(
PrrtChannelStateInformation
*
csi
);
void
PrrtChannelStateInformation_print
(
PrrtChannelStateInformation
*
csi
);
...
...
prrt/proto/clock.h
View file @
89e337a9
#ifndef PRRT_CLOCK_H
#define PRRT_CLOCK_H
#include "packet.h"
#include "
types/
packet.h"
#include <stdint.h>
#include <stdbool.h>
...
...
prrt/proto/processes/dataReceiver.c
View file @
89e337a9
...
...
@@ -50,7 +50,25 @@ static void decode_block(PrrtSocket *sock_ptr, PrrtBlock *block) {
PERROR
(
"Decoding failed.%s"
,
""
)
}
static
bool
send_feedback
(
PrrtSocket
*
sock_ptr
,
struct
sockaddr_in
remote
)
{
static
bool
send_feedback
(
PrrtSocket
*
sock_ptr
,
struct
sockaddr_in
remote
,
prrtSequenceNumber_t
seqno
,
prrtTimestamp_t
receiveStamp
,
prrtTimestamp_t
sentTimestamp
,
prrtPacketType_t
type
)
{
enum
XlapTimestampPacketKind
kind
=
ts_data_packet
;
if
(
type
==
PACKET_TYPE_DATA
)
{
kind
=
ts_data_packet
;
}
else
if
(
type
==
PACKET_TYPE_REDUNDANCY
)
{
kind
=
ts_redundancy_packet
;
}
debug
(
DEBUG_FEEDBACK
,
"Send feedback %d %d"
,
type
,
seqno
);
XlapTimeStampCycle
(
sock_ptr
,
kind
,
seqno
,
SendFeedbackStart
);
prrtFeedback_t
feedback
=
{
.
seqNo
=
seqno
,
.
type
=
type
,
.
receivedTime
=
receiveStamp
,
.
sentTime
=
sentTimestamp
};
uint16_t
remote_port
=
ntohs
(
remote
.
sin_port
);
char
*
remote_host
=
inet_ntoa
(
remote
.
sin_addr
);
...
...
@@ -72,7 +90,8 @@ static bool send_feedback(PrrtSocket *sock_ptr, struct sockaddr_in remote) {
PrrtPacket
*
feedback_pkt_ptr
=
PrrtPacket_create_feedback_packet
(
0
,
sock_ptr
->
sequenceNumberFeedback
++
,
group_RTT
,
stats
.
gapLength
,
stats
.
gapCount
,
stats
.
burstLength
,
stats
.
burstCount
,
forwardTripTime
,
stats
.
erasureCount
,
stats
.
packetCount
);
stats
.
erasureCount
,
stats
.
packetCount
,
feedback
.
seqNo
,
feedback
.
type
);
prrtPacketLength_t
length
=
PrrtPacket_size
(
feedback_pkt_ptr
);
void
*
buf
=
calloc
(
1
,
length
);
check_mem
(
buf
);
...
...
@@ -84,6 +103,7 @@ static bool send_feedback(PrrtSocket *sock_ptr, struct sockaddr_in remote) {
free
(
buf
);
PrrtPacket_destroy
(
feedback_pkt_ptr
);
XlapTimeStampCycle
(
sock_ptr
,
kind
,
seqno
,
SendFeedbackEnd
);
return
true
;
...
...
@@ -98,11 +118,12 @@ static bool is_timeout(prrtTimestamp_t now, prrtTimestamp_t to) {
return
false
;
}
static
void
handle_data_packet
(
PrrtSocket
*
sock_ptr
,
PrrtPacket
*
packet
,
struct
sockaddr_in
remote
)
{
static
void
handle_data_packet
(
PrrtSocket
*
sock_ptr
,
PrrtPacket
*
packet
)
{
PrrtPacketDataPayload
*
payload
=
packet
->
payload
;
prrtTimestamp_t
data
Timestamp
=
payload
->
timestamp
;
sock_ptr
->
lastSentTimestamp
=
data
Timestamp
;
PrrtClock_update
(
&
sock_ptr
->
clock
,
data
Timestamp
,
payload
->
groupRTprop_us
);
prrtTimestamp_t
sent
Timestamp
=
payload
->
timestamp
;
sock_ptr
->
lastSentTimestamp
=
sent
Timestamp
;
PrrtClock_update
(
&
sock_ptr
->
clock
,
sent
Timestamp
,
payload
->
groupRTprop_us
);
PrrtPacketTimeout
*
packetTimeout
=
PrrtPacketTimeout_create
(
packet
);
check
(
PrrtPacketTimeoutTable_insert
(
sock_ptr
->
packetTimeoutTable
,
packetTimeout
),
"Could not insert data packet."
);
...
...
@@ -110,14 +131,9 @@ static void handle_data_packet(PrrtSocket *sock_ptr, PrrtPacket *packet, struct
prrtSequenceNumber_t
seqno
=
packet
->
sequenceNumber
;
PrrtReceptionTable_mark_received
(
sock_ptr
->
dataReceptionTable
,
seqno
);
XlapTimeStampCycle
(
sock_ptr
,
ts_data_packet
,
seqno
,
SendFeedbackStart
);
check
(
send_feedback
(
sock_ptr
,
remote
),
"Sending feedback failed."
);
XlapTimeStampCycle
(
sock_ptr
,
ts_data_packet
,
seqno
,
SendFeedbackEnd
);
prrtTimestamp_t
now
=
PrrtClock_get_prrt_time_us
(
&
sock_ptr
->
clock
);
if
(
is_timeout
(
now
,
payload
->
packetTimeout_us
))
{
PrrtDeliveredPacketTable_test_set_is_number_relevant
(
sock_ptr
->
deliveredPacketTable
,
packet
->
sequenceNumber
);
// TODO: note this as loss
PrrtPacket_destroy
(
packet
);
debug
(
DEBUG_RECEIVER
,
"timeout data packet %u (%lu > %lu)"
,
seqno
,
(
unsigned
long
)
now
,
(
unsigned
long
)
payload
->
packetTimeout_us
);
...
...
@@ -247,7 +263,8 @@ void *receive_data_loop(void *ptr) {
receive_from_socket
(
sock_ptr
,
buffer
,
&
n
,
&
remote
,
&
addrlen
,
&
packet_recv_stamp
);
debug
(
DEBUG_HARDSTAMPING
,
"Packet TS:
\t
%ld.%09ld; Who? %s"
,
(
long
)
packet_recv_stamp
.
tv_sec
,
packet_recv_stamp
.
tv_nsec
,
inet_ntoa
(
remote
.
sin_addr
));
sock_ptr
->
lastReceivedTimestamp
=
PrrtClock_TimespecToPrrtTimestamp
(
packet_recv_stamp
);
prrtTimestamp_t
prrt_recv_timestamp
=
PrrtClock_TimespecToPrrtTimestamp
(
packet_recv_stamp
);
sock_ptr
->
lastReceivedTimestamp
=
prrt_recv_timestamp
;
XlapTimeStampClock
(
&
tsph1
,
ts_any_packet
,
0
,
LinkReceive
);
XlapTimeStampCycle
(
&
tsph1
,
ts_any_packet
,
0
,
LinkReceive
);
...
...
@@ -263,11 +280,15 @@ void *receive_data_loop(void *ptr) {
prrtPacketType_t
packetType
=
PrrtPacket_type
(
packet
);
debug
(
DEBUG_DATARECEIVER
,
"received packet %d:%u"
,
(
int
)
packetType
,
seqno
);
enum
XlapTimestampPacketKind
kind
=
ts_any_packet
;
prrtTimestamp_t
sentTimestamp
;
if
(
packetType
==
PACKET_TYPE_DATA
)
{
kind
=
ts_data_packet
;
sentTimestamp
=
PrrtPacket_get_data_timestamp
(
packet
);
}
else
if
(
packetType
==
PACKET_TYPE_REDUNDANCY
)
{
kind
=
ts_redundancy_packet
;
sentTimestamp
=
PrrtPacket_get_redundancy_timestamp
(
packet
);
}
if
(
packetType
==
PACKET_TYPE_DATA
||
packetType
==
PACKET_TYPE_REDUNDANCY
)
{
XlapTimeStampValue
(
sock_ptr
,
kind
,
seqno
,
ChannelReceive
,
packet_recv_stamp
);
...
...
@@ -277,8 +298,11 @@ void *receive_data_loop(void *ptr) {
XlapTimestampPlaceholderUse
(
sock_ptr
,
kind
,
seqno
,
&
tsph3
);
XlapTimeStampCycle
(
sock_ptr
,
kind
,
seqno
,
HandlePacketStart
);
send_feedback
(
sock_ptr
,
remote
,
seqno
,
prrt_recv_timestamp
,
sentTimestamp
,
packetType
);
if
(
packetType
==
PACKET_TYPE_DATA
)
{
handle_data_packet
(
sock_ptr
,
packet
,
remote
);
handle_data_packet
(
sock_ptr
,
packet
);
}
else
if
(
packetType
==
PACKET_TYPE_REDUNDANCY
)
{
handle_redundancy_packet
(
sock_ptr
,
packet
);
}
else
{
...
...
prrt/proto/processes/dataReceiver.h
View file @
89e337a9
#ifndef PRRT_DATA_RECEIVER_H
#define PRRT_DATA_RECEIVER_H
#include "../types/packet.h"
typedef
struct
prrtFeedback
{
prrtSequenceNumber_t
seqNo
;
prrtPacketType_t
type
;
prrtTimestamp_t
sentTime
;
prrtTimestamp_t
receivedTime
;
}
prrtFeedback_t
;
void
*
receive_data_loop
(
void
*
ptr
);
#endif //PRRT_DATA_RECEIVER_H
prrt/proto/processes/dataTransmitter.c
View file @
89e337a9
...
...
@@ -95,6 +95,8 @@ static bool send_packet(PrrtSocket *sock_ptr, PrrtPacket *packet) {
send_to_socket
(
sock_ptr
,
sock_ptr
->
receiver
,
buf
,
length
,
&
timestamp
);
XlapTimeStampValue
(
sock_ptr
,
ts_data_packet
,
packet
->
sequenceNumber
,
ChannelTransmit
,
timestamp
);
PrrtReceiver_add_outstanding_packet_state
(
sock_ptr
->
receiver
,
packet
,
PrrtClock_TimespecToPrrtTimestamp
(
timestamp
));
switch
(
PrrtPacket_type
(
packet
))
{
case
PACKET_TYPE_DATA
:
XlapTimeStampClock
(
sock_ptr
,
ts_data_packet
,
packet
->
sequenceNumber
,
LinkTransmitEnd
);
...
...
@@ -111,8 +113,6 @@ static bool send_packet(PrrtSocket *sock_ptr, PrrtPacket *packet) {
default:
;
}
PrrtPacket_destroy
(
packet
);
return
true
;
error:
...
...
prrt/proto/processes/feedbackReceiver.c
View file @
89e337a9
...
...
@@ -40,6 +40,10 @@ static void handle_feedback(PrrtSocket *prrtSocket, const size_t length)
PrrtPacketFeedbackPayload
*
feedbackPayload
=
(
PrrtPacketFeedbackPayload
*
)
prrtPacket
->
payload
;
prrtTimestamp_t
forwardTripTimestamp
=
feedbackPayload
->
forwardTripTimestamp_us
;
PrrtReceiver_updateAndGenerateRateSample
(
prrtSocket
->
receiver
,
feedbackPayload
->
ackSequenceNumber
,
feedbackPayload
->
ackPacketType
,
receiveTime
);
PrrtChannelStateInformation_update_delivery_rate
(
prrtSocket
->
receiver
->
csi
,
prrtSocket
->
receiver
->
rateSample
->
delivery_rate
);
PrrtChannelStateInformation_update_rtprop
(
prrtSocket
->
receiver
->
csi
,
(
prrtTimedelta_t
)
(
receiveTime
-
forwardTripTimestamp
));
PrrtChannelStateInformation_update_plr
(
prrtSocket
->
receiver
->
csi
,
feedbackPayload
->
erasureCount
,
feedbackPayload
->
packetCount
);
...
...
prrt/proto/receiver.c
View file @
89e337a9
#include <malloc.h>
#include "../xlap/xlap.h"
#include "../util/common.h"
#include "../util/dbg.h"
#include "stores/inFlightPacketStore.h"
#include "receiver.h"
PrrtReceiver
*
PrrtReceiver_create
(
const
char
*
host
,
uint16_t
port
)
{
PrrtReceiver
*
PrrtReceiver_create
(
const
char
*
host
,
uint16_t
port
)
{
PrrtReceiver
*
recv
=
calloc
(
1
,
sizeof
(
PrrtReceiver
));
check_mem
(
recv
);
recv
->
host_name
=
strdup
(
host
);
check_mem
(
recv
->
host_name
);
check_mem
(
recv
->
host_name
);
recv
->
port
=
port
;
struct
addrinfo
*
info
;
struct
addrinfo
hints
;
char
portstr
[
sizeof
(
port
)
*
8
+
1
];
snprintf
(
portstr
,
sizeof
(
portstr
),
"%u"
,
(
unsigned
int
)
port
);
memset
(
&
hints
,
0x0
,
sizeof
(
hints
));
hints
.
ai_family
=
AF_INET
;
hints
.
ai_socktype
=
SOCK_DGRAM
;
check
(
0
==
getaddrinfo
(
host
,
portstr
,
&
hints
,
&
info
),
"getaddrinfo"
);
PrrtRateSample
*
rateSample
=
calloc
(
1
,
sizeof
(
PrrtRateSample
));
check_mem
(
rateSample
);
recv
->
rateSample
=
rateSample
;
recv
->
ai
=
info
;
recv
->
csi
=
PrrtChannelStateInformation_create
();
PrrtPacketTracking
*
packetTracking
=
calloc
(
1
,
sizeof
(
PrrtPacketTracking
));
check_mem
(
packetTracking
);
recv
->
packetTracking
=
packetTracking
;
recv
->
csi
=
PrrtChannelStateInformation_create
();
recv
->
dataPacketStates
=
PrrtInFlightPacketStore_create
();
recv
->
redundancyPacketStates
=
PrrtInFlightPacketStore_create
();
struct
addrinfo
*
info
;
struct
addrinfo
hints
;
char
portstr
[
sizeof
(
port
)
*
8
+
1
];
snprintf
(
portstr
,
sizeof
(
portstr
),
"%u"
,
(
unsigned
int
)
port
);
memset
(
&
hints
,
0x0
,
sizeof
(
hints
));
hints
.
ai_family
=
AF_INET
;
hints
.
ai_socktype
=
SOCK_DGRAM
;
check
(
0
==
getaddrinfo
(
host
,
portstr
,
&
hints
,
&
info
),
"getaddrinfo"
);
recv
->
ai
=
info
;
check
(
pthread_mutex_init
(
&
recv
->
lock
,
NULL
)
==
0
,
"lock init failed."
);
check
(
pthread_cond_init
(
&
recv
->
pipeNotFullCv
,
NULL
)
==
0
,
"pipeNotFullCv init failed."
);
check
(
pthread_cond_init
(
&
recv
->
recordNotFoundCv
,
NULL
)
==
0
,
"recordNotFound init failed."
);
return
recv
;
error:
if
(
recv
!=
NULL
)
{
free
((
void
*
)
recv
->
host_name
);
free
(
recv
);
}
free
((
void
*
)
recv
->
host_name
);
free
(
recv
);
}
//PERROR("Memory issue.%s","");
return
NULL
;
}
bool
PrrtReceiver_destroy
(
PrrtReceiver
*
receiver
)
{
if
(
receiver
->
csi
!=
NULL
)
{
PrrtChannelStateInformation_destroy
(
receiver
->
csi
);
}
freeaddrinfo
(
receiver
->
ai
);
free
((
void
*
)
receiver
->
host_name
);
free
(
receiver
);
return
true
;
if
(
receiver
->
csi
!=
NULL
)
{
PrrtChannelStateInformation_destroy
(
receiver
->
csi
);
}
if
(
receiver
->
dataPacketStates
!=
NULL
)
{
PrrtInFlightPacketStore_destroy
(
receiver
->
dataPacketStates
);
}
if
(
receiver
->
redundancyPacketStates
!=
NULL
)
{
PrrtInFlightPacketStore_destroy
(
receiver
->
redundancyPacketStates
);
}
if
(
receiver
->
packetTracking
!=
NULL
)
{
free
(
receiver
->
packetTracking
);
}
if
(
receiver
->
rateSample
!=
NULL
)
{
free
(
receiver
->
rateSample
);
}
freeaddrinfo
(
receiver
->
ai
);
free
((
void
*
)
receiver
->
host_name
);
check
(
pthread_mutex_destroy
(
&
receiver
->
lock
)
==
0
,
"lock destroy failed."
);
check
(
pthread_cond_destroy
(
&
receiver
->
pipeNotFullCv
)
==
0
,
"pipeNotFullCv destroy failed."
);
check
(
pthread_cond_destroy
(
&
receiver
->
recordNotFoundCv
)
==
0
,
"recordNotFoundCv destroy failed."
);
free
(
receiver
);
return
true
;
error:
PERROR
(
"PrrtReceiver_destroy failed."
)
return
false
;
}
void
PrrtReceiver_updateRateSample
(
PrrtRateSample
*
rateSample
,
PrrtPacket
*
packet
,
prrtTimestamp_t
receiveTime
,
PrrtPacketTracking
*
packetTracking
)
{
if
(
packet
->
delivered_time
==
0
)
return
;
packetTracking
->
delivered
+=
packet
->
payloadLength
;
packetTracking
->
delivered_time
=
receiveTime
;
if
(
packet
->
delivered
>
rateSample
->
prior_delivered
)
{
rateSample
->
prior_delivered
=
packet
->
delivered
;
rateSample
->
prior_time
=
packet
->
delivered_time
;
rateSample
->
is_app_limited
=
packet
->
is_app_limited
;
rateSample
->
send_elapsed
=
packet
->
sent_time
-
packet
->
first_sent_time
;
rateSample
->
ack_elapsed
=
packetTracking
->
delivered_time
-
packet
->
delivered_time
;
packetTracking
->
first_sent_time
=
packet
->
sent_time
;
}
packet
->
delivered_time
=
0
;
}
void
PrrtReceiver_generateRateSample
(
PrrtRateSample
*
rateSample
,
PrrtPacketTracking
*
packetTracking
)
{
/* Clear app-limited field */
if
(
packetTracking
->
app_limited
&&
packetTracking
->
delivered
>
packetTracking
->
app_limited
)
packetTracking
->
app_limited
=
0
;
if
(
rateSample
->
prior_time
==
0
)
{
//printf("Prior Time is 0, Cancelling Rate sample calculation\n");
return
;
}
rateSample
->
interval
=
MAX
(
rateSample
->
send_elapsed
,
rateSample
->
ack_elapsed
);
rateSample
->
delivered
=
packetTracking
->
delivered
-
rateSample
->
prior_delivered
;
if
(
rateSample
->
interval
!=
0
)
{
// delivered: bytes; interval: us; convert to bps
rateSample
->
delivery_rate
=
rateSample
->
delivered
*
1000
*
1000
*
8
/
rateSample
->
interval
;
}
debug
(
DEBUG_FEEDBACK
,
"RS interval: %u, RS delivered: %u, RS delivery_rate: %u"
,
rateSample
->
interval
,
rateSample
->
delivered
,
rateSample
->
delivery_rate
);
/* Normally we expect interval >= MinRTT.
* Note that rate may still be over-estimated when a spuriously
* retransmitted skb was first (s)acked because "interval"
* is under-estimated (up to an RTT). However, continuously
* measuring the delivery rate during loss recovery is crucial
* for connections suffer heavy or prolonged losses.
if (packetStore->rateSample->interval < MinRTT(tp))
packetStore->rateSample->interval = -1;
return false // no reliable sample
*/
}
void
PrrtReceiver_updateAndGenerateRateSample
(
PrrtReceiver
*
recv
,
prrtSequenceNumber_t
seqnum
,
uint8_t
packetType
,
prrtTimestamp_t
receiveTime
)
{
PrrtInFlightPacketStore
*
packetStore
=
NULL
;
if
(
packetType
==
PACKET_TYPE_DATA
)
{
packetStore
=
recv
->
dataPacketStates
;
}
else
if
(
packetType
==
PACKET_TYPE_REDUNDANCY
)
{
packetStore
=
recv
->
redundancyPacketStates
;
}
else
return
;
check
(
pthread_mutex_lock
(
&
recv
->
lock
)
==
0
,
"Lock failed."
);
PrrtPacket
*
packet
=
PrrtInFlightPacketStore_get_packet
(
packetStore
,
seqnum
);
while
(
packet
==
NULL
)
{
pthread_cond_wait
(
&
recv
->
recordNotFoundCv
,
&
recv
->
lock
);
packet
=
PrrtInFlightPacketStore_get_packet
(
packetStore
,
seqnum
);
}
PrrtReceiver_updateRateSample
(
recv
->
rateSample
,
packet
,
receiveTime
,
recv
->
packetTracking
);
PrrtReceiver_generateRateSample
(
recv
->
rateSample
,
recv
->
packetTracking
);
PrrtInFlightPacketStore_remove_outstanding_packet
(
packetStore
,
seqnum
);
check
(
pthread_mutex_unlock
(
&
recv
->
lock
)
==
0
,
"Unlock failed."
);
check
(
pthread_cond_broadcast
(
&
recv
->
pipeNotFullCv
)
==
0
,
"Signal failed."
);
return
;
error:
PERROR
(
"Mutex error.%s"
,
""
);
}
void
PrrtReceiver_add_outstanding_packet_state
(
PrrtReceiver
*
recv
,
PrrtPacket
*
packet
,
prrtTimestamp_t
sentTime
)
{
PrrtInFlightPacketStore
*
packetStore
=
NULL
;
if
(
PrrtPacket_type
(
packet
)
==
PACKET_TYPE_DATA
)
{
packetStore
=
recv
->
dataPacketStates
;
}
else
if
(
PrrtPacket_type
(
packet
)
==
PACKET_TYPE_REDUNDANCY
)
{
packetStore
=
recv
->
redundancyPacketStates
;
}
else
return
;
//printf("Adding Packet #%u to %u\n", packet->sequenceNumber, PrrtPacket_type(packet));
check
(
pthread_mutex_lock
(
&
recv
->
lock
)
==
0
,
"Lock failed."
);
recv
->
packetTracking
->
app_limited
=
packet
->
is_app_limited
;
if
(
PrrtInFlightPacketStore_get_queue_size
(
recv
->
dataPacketStates
)
+
PrrtInFlightPacketStore_get_queue_size
(
recv
->
redundancyPacketStates
)
==
0
)
{
recv
->
packetTracking
->
first_sent_time
=
sentTime
;
recv
->
packetTracking
->
delivered_time
=
sentTime
;
}
packet
->
first_sent_time
=
recv
->
packetTracking
->
first_sent_time
;
packet
->
sent_time
=
sentTime
;
packet
->
delivered_time
=
recv
->
packetTracking
->
delivered_time
;
packet
->
delivered
=
recv
->
packetTracking
->
delivered
;
//packet->is_app_limited = packetStore->app_limited;
PrrtInFlightPacketStore_add_outstanding_packet
(
packetStore
,
packet
);
check
(
pthread_mutex_unlock
(
&
recv
->
lock
)
==
0
,
"Unlock failed."
);
check
(
pthread_cond_broadcast
(
&
recv
->
recordNotFoundCv
)
==
0
,
"Signal failed."
);
return
;
error:
PERROR
(
"Lock error.%s"
,
""
);
}
void
PrrtReceiver_interrupt
(
PrrtReceiver
*
recv
)
{
pthread_cond_broadcast
(
&
recv
->
recordNotFoundCv
);
pthread_cond_broadcast
(
&
recv
->
pipeNotFullCv
);
}
prrt/proto/receiver.h
View file @
89e337a9
...
...
@@ -7,15 +7,53 @@
#include <sys/socket.h>
#include <netdb.h>
#include "channelStateInformation.h"
#include "stores/inFlightPacketStore.h"
typedef
struct
prrtRateSample
{
prrtByteCount_t
prior_delivered
;
prrtTimestamp_t
prior_time
;
prrtTimedelta_t
send_elapsed
;
prrtTimedelta_t
ack_elapsed
;
prrtTimedelta_t
interval
;
prrtByteCount_t
delivered
;
bool
is_app_limited
;
prrtDeliveryRate_t
delivery_rate
;
// Bps
}
PrrtRateSample
;
typedef
struct
packetTracking
{
prrtByteCount_t
delivered
;
prrtTimestamp_t
delivered_time
;
prrtTimestamp_t
first_sent_time
;
bool
app_limited
;
}
PrrtPacketTracking
;
typedef
struct
prrtReceiver
{
const
char
*
host_name
;
const
char
*
host_name
;
uint16_t
port
;
struct
addrinfo
*
ai
;
PrrtChannelStateInformation
*
csi
;
struct
addrinfo
*
ai
;
PrrtChannelStateInformation
*
csi
;
pthread_cond_t
pipeNotFullCv
;
pthread_cond_t
recordNotFoundCv
;
pthread_mutex_t
lock
;
PrrtInFlightPacketStore
*
dataPacketStates
;
PrrtInFlightPacketStore
*
redundancyPacketStates
;
PrrtRateSample
*
rateSample
;
PrrtPacketTracking
*
packetTracking
;
}
PrrtReceiver
;
PrrtReceiver
*
PrrtReceiver_create
(
const
char
*
host
,
uint16_t
port
);
bool
PrrtReceiver_destroy
(
PrrtReceiver
*
receiver
);
PrrtReceiver
*
PrrtReceiver_create
(
const
char
*
host
,
uint16_t
port
);
void
PrrtReceiver_updateAndGenerateRateSample
(
PrrtReceiver
*
recv
,
prrtSequenceNumber_t
seqnum
,
uint8_t
packetType
,
prrtTimestamp_t
receiveTime
);
void
PrrtReceiver_add_outstanding_packet_state
(
PrrtReceiver
*
recv
,
PrrtPacket
*
packet
,
prrtTimestamp_t
sentTime
);
void
PrrtReceiver_interrupt
(
PrrtReceiver
*
recv
);
bool
PrrtReceiver_destroy
(
PrrtReceiver
*
receiver
);
#endif //PRRT_RECEIVER_H
prrt/proto/socket.c
View file @
89e337a9
...
...
@@ -10,7 +10,6 @@
#include <assert.h>
#include <sys/ioctl.h>
#include "../defines.h"
#include "packet.h"
#include "../util/dbg.h"
#include "../util/common.h"
#include "processes/dataTransmitter.h"
...
...
@@ -371,6 +370,9 @@ int PrrtSocket_interrupt(PrrtSocket *s) {
if
(
s
->
packetDeliveryStore
)
PrrtPacketDeliveryStore_wake
(
s
->
packetDeliveryStore
);
if
(
s
->
receiver
!=
NULL
)
{
PrrtReceiver_interrupt
(
s
->
receiver
);
}
void
**
res
=
NULL
;
if
(
s
->
sendDataThread
!=
0
)
{
...
...
@@ -574,6 +576,10 @@ uint32_t PrrtSocket_get_rtprop(PrrtSocket *s) {
return
PrrtChannelStateInformation_get_rtprop
(
s
->
receiver
->
csi
);
}
prrtPacketLossRate_t
PrrtSocket_get_plr
(
PrrtSocket
*
socket
)
{
return
PrrtChannelStateInformation_get_plr
(
socket
->
receiver
->
csi
);
prrtPacketLossRate_t
PrrtSocket_get_plr
(
PrrtSocket
*
s
)
{
return
PrrtChannelStateInformation_get_plr
(
s
->
receiver
->
csi
);
}
prrtDeliveryRate_t
PrrtSocket_get_delivery_rate
(
PrrtSocket
*
s
)
{
return
PrrtChannelStateInformation_get_delivery_rate
(
s
->
receiver
->
csi
);
}
prrt/proto/socket.h
View file @
89e337a9