P2PSP (https://p2psp.github.io) is an application-layer protocol that provides real-time broadcasting, also known as Application Layer Multicast (ALM), of a media stream on the Internet. Peers collaborate to diseminate the stream that is generated by a single source, minimizing the latency and the protocol overhead. P2PSP overlays are push-based (topology-driven) meshes. To minimize the transmission latency, P2PSP establishes a communication between nearby peers, and chunks of data are ﬂooded without explicit requests. P2PSP has a modular design organized in sets of rules, where each module is especialized in implementing diﬀerent functionalities.
P2PSP supposes that there is a collection of channels that are broadcasted in parallel.1 The channels are available at one or more2 streaming servers, and each channel has a diﬀerent URL (Universal Resource Locator), usually expressed as a Web address with the structure:
P2PSP does not perform data-ﬂow control over the stream. The transmission bit-rate between P2PSP entities is controlled by an external (Icecast, for example) server, which provides the stream. Fig. 1 shows an example of a streaming overlay where several servers relay a set of channels produced by a set of source-clients, directly or through other servers. As can be seen, a listener (which usually plays de stream) can be replaced by a splitter, a P2PSP entity that sends the received stream (a single channel) to a set of P2PSP peers, called team. Notice that, considering that at least one player can be attached to each peer, the scalability of the hybrid alternative is much higher than the pure client/server architecture.
In a pure CDN system, users request the channels directly to the servers. Unfortunately, this simple procedure has a drawback: normally, users do not know the load or the distance to the servers. This problem can be solved by using a load balancer. The listeners, which know the URL of the required channel, connects ﬁrst to a load balancer which redirects them (with a HTTP 302 code) to a suitable server.
This idea can be extended to minimize the response time of hybrid CDN/P2P structures. When a P2PSP user (who knows an URL of the channel) runs a local peer, it provides the peer with the URL of the channel: a server and a mount point. Then, the peer (as any other listener does) contacts a load balancer which in this case sends a list of splitters which are broadcasting the channel.3 Then, the peer tries to connect with all the splitters in parallel, and the ﬁrst establised connection determines the selected splitter (the rest of connections are closed). If only those splitters with space in their teams answer to the peer, this procedure should select the “optimal” splitter for the peer in terms of response time.
For the case of the incorporation of new splitters to the network the procedure is similar. A new splitter (which is instantiated knowing an URL of a channel) contacts the load balancer which returns a list of servers and peers, which are serving the channel. Then, the splitter tries to connect with all of them in parallel and the ﬁrst successfull connection is ﬁnally selected.4
Using the idea of the extended load balancer, when a player (listener) connects to it, if there is a local peer running in the same host or the same private network that the player, the balancer will redirect the player to the local peer.
Finally, all splitters associated to the same stream should generate exactly the same chunks (content and header). See Section 9.
|Buﬀer size in chunks|
|Maximum losses of chunk allowed|
|Number of monitors|
|Maximum number of peers in a team|
DBS provides ALM  of a media stream in unicast environments . The media is sent by a streaming server, and received by a splitter (see Sec. 1). The splitter divides the stream into a sequence of chunks of data, and relay them to its team using a round-robing schema, where it can be up to peers. Each peer gathers the chunks from the splitter and the rest of peers of the team, and sends them to at least one player5 .
In Tab. 1 the deﬁnitions used in the DBS have been summarized.
A team is a set of one or more peers that share the same stream. By deﬁnition, in a team of size one, the only peer is known as a monitor peer. In a team with more than one peer, at least one of them must be a monitor peer. Monitor peers are instantiated by the overlay administrator to monitorize diﬀerent aspects of the broadcasting, such as, the quality of the rendered video.
The splitter divides the stream into chunks of constant length , and sends exclusively each chunk to a diﬀerent origin peer6 , using a round-robin schema. Chunks are enumerated to distinguish them at the peers.
We deﬁne a round as the process of transmitting diﬀerent chunks from the splitter to a team of peers. In other words, for a team of size , the round-time is chunk-times. Notice that the round-time is variable, and depends on the current number of peers in the team (), the chunk size (), and the average bit-rate of the media stream.
The splitter remembers which chunk, of a list of the last transmitted chunks, was sent to each peer of the team. Notice that, in order to remember in a round which chunk was sent to each peer, . See in splitter_dbs.py.
After connecting with a splitter, incoming peers request (using a reliable communication) to the splitter the current list of peers in the team. To minimize the joining time, the peer sends a message to each peer of the team, in parallel with the reception of the list. When a peer of the team receives a , it adds the sender of the message to a table of peers called (see in peer.py). If a peer has an entry then, each chunk received by and originated at will be forwarded to .
The splitter, in a loop: (1) listens to the incoming peers, (2) sends the list of peers in the team, and (3) adds the incoming peer to the list.
Note: See in peer_dbs.py.
In order to hide the jitter generated by the physical network and the protocol itself, peers need to store the received chunks in a buﬀer during a period of time before playing them. A chunk with number is inserted in the position of the buﬀer, where is the maximum number of chunks that the buﬀer will store. In a peer’s life, is constant, but it is not compulsory that all peers of the same team use the same value.
The buﬀer is implemented as a circular queue of chunks, which is ﬁlled up to only chunks in the buﬀering time (which is the main part of the start-up time that the users experiment). Chunks with a higher number (newer chunks) are inserted in the head of the buﬀer. The chunk pointed by the tail of the buﬀer is sent to the player (if there is a chunk in that cell of the buﬀer). This action is carried out each time a new chunk is received.
The buﬀering time determines how much time the peers must wait before start playing the chunks. Considering that chunks can be lost in transit or delayed more than times of chunk, randomly, it is diﬃcult to determine, a priori, the optimal buﬀering time. In the current implementation, peers buﬀer a variable number of chunks that depends on the order in which chunks are received. If is the (number of the) ﬁrst chunk received (the ﬁrst chunk to be played), the buﬀering time ﬁnishes when the chunk is received.7
DBS implements a content-unaware push-based protocol, and when a peer receives a chunk, it can be retransmitted to a large number of neighbors. To avoid network congestion while ﬂooding, some kind of ﬂow control must be performed.
Congestion may be avoided by means of a basic idea: if I have received a chunk, I should send a chunk. It is easy to see that, in a fully connected overlay, this allows to control the data ﬂow. However, in more realistic scenarios, peers can be “connected” with a variable number of neighbors and therefore, if the splitter follows a pure round-robin strategy, some peers can send more chunks that they receive.
The previous idea can be improved to handle a variable connectivity degree. Each peer uses a table of lists, , indexed by the neighbor end-points, where each list stores the positions in the buﬀer of those chunks that must be transmited to the corresponding neighbor, the next time such neighbor be selected. Thus, if for example , chunks found at positions and of the buﬀer have to be sent to peer (when a round-robin scheduler used by the peer selects ). The current scheduler used by the peers selects a diﬀerent neighbor, using a round-robin scheme, for each new received chunk.
An example of the ﬂooding with congestion control algorithm has been show in the Figs. 2, ...
Chunks can be lost.8 A chunk is considered as lost when it is time to send it to the player and the chunk has not been received. In this situation, for each lost chunk, the peer sends a (that is the number of the next chunk to be played) to a randomly selected peer of the team. When a peer receives a from , adds to , where is the origin peer of the chunk stored in the position of the buﬀer.
In this situation, it is also possible that some peers can request redundant paths between an origin peer and itself, and therefore, some chunks could be received more than once. If this case, for each duplicate chunk, a peer should send a message to those neighbors that have sent to it the duplicate chunk. Neighbors receiving such message from peer should remove the from , where is the origin peer of the duplicate chunk.
An outgoing peer must to: (1) say to the splitter and the neighbor peers (in this order), (2) relay any pending (received but yet not sent) chunks, and (3) wait for a from the splitter. In case of timeout, the leaving procedure is reset a number of times.
When a peer of the team receives a , removes the sender from the table.
The splitter removes the outgoing peer from the list of peers.
In each team there are a set of monitors (trusted peers whose behavior is predictable and that are only known by the splitter), which complain to their splitter with a for each lost chunk. The splitter only considers these type of messages if they come from a monitor.
If a peer accumulates more than losts in rounds, is removed from the splitter’s list of peers. Peers do the same, but in this case they remove the selﬁsh neighbors from the and tables.
Note: This last functionality has not been implemented, at least, as it has been explained here. The forget() thread is controlled by a timer, not by a counter of rounds.
IPM is available by default in LANs (Local Are Network)s and VLANs (Virtual LANs) , but not in the Internet . IMS runs on the top of DBS and provides eﬃcient native IPM, where available.
The idea of IMS is simple: all peers in the same LAN or VLAN have the same network address. When a joining peer receives the list of peers from its splitter, ﬁrst checks if there are neighbors in the same subnet (all of them share the same private network address). For all those peers, uses the IP address (all systems on this subnet), (default) port , to multicast (only) the chunks received from the splitter. When implementing IMS, all peers in the same local network communicate using this IPM group address and port. The rest of external peers will be referenced using their public end-points.
DBS does not imposes any control over the grade of solidarity of the peers. This means that selﬁsh peers (or simply peers with reduced connectivity as a consecuence, for example, of NAT issues) can stay in the team thanks to the generosity of the rest of peers. If this is unnaceptable, this set of rules try to that all the peers of the team to share the same number of chunks that they receive.
To know the level of solidarity between neighbor peers, each peer implements a table of chunk debts, . Every time sends a chunk to , runs , and runs . So, peers increment the insolidarity measurement incrementally and decreases it exponentially towards zero. This respond to the idea of that, if a peer keeps sending chunks to their neighbors, it has doing its best in retransmitting the chunks it must forward.
With the information, peers modify the way the neighbor are selected during the ﬂooding procedure. Now, the list is sorted by debts (those peers with a lower debt will appear in the ﬁrst positions of ), and when a peer receives a chunk from the splitter, the run over the list will be reset. In this way, supportive peers will be served ﬁrst, incrementing the QoE of the corresponding users. On the other hand, those peers with a higher chunk debt will tend to be unserved if no enough bandwidth is available.
The second mechanism to increase the grade of solidarity is to send the to those peers with a higher debt. So, if the insolidarity is produced by a overlay topology imbalance, badly connected peers peers can mitigate this problem forwarding more chunks to their neighbors.
Note: The prioritized round-robin neighbor selection has not yet been implemented as it has been explained here. The structure exists, but is used for a diﬀerent purporse.
In TAS, the splitter request to each peer of the team the list of neighbors (peers that send chunks directly, in one hop). This communication is reliable (TCP) and transmits the lists as a collection of end-points. The number of requests per round is limited by the available bandwidth in the overlay, and by the request-ratio deﬁned at the splitter. Obviously, the higher the ratio, a more accurate description of the real connectivity in the overlay will be obtained.
After knowing the connectivity degree of each peer, the slitter can adapt the round-robin scheduling of the origin peers by sending a number of chunks proportional to the inverse of the degree of the origin peer.
MRS extends DBS (or an extension of it) to retransmit massively-lost chunks. MRS should be implemented if error-prone communications are expected, specially if these channels are used by the splitter. MRS is based on the use of monitors (see Sec: 2.8). The idea is: the splitter will resend lost chunks to one or more the monitors when all monitors report their loss. To increase the probability of receiving on time the resent chunk (by normal peers), monitors halves the number of chunks in their buﬀers in relation to common peers. Notice that MRS only modiﬁes the behavior of the splitters and the monitors (normal peers does no need to implement LRS or its extensions).
ACS relaxes the peer’s upload requirements imposed by DBS. It should be used in if it is known that some peers can provide the capacity than others cannot, or when we want to mix the CS and P2P models, sending more chunks from the splitter to one or more monitors controlled by the contents provider.
ACS is based on the idea of using the information that the splitter knows about the number of chunks that each peer has lost (see Sec 2.8), to send to those more reliable peers a higher number of chunks than to the others. In other words, ACS adapts the round-time of each peer to its capacity.
Notice that ACS only aﬀects the behavior of the splitter.
Most of the peers run inside of “private” networks, i.e. behind NAT devices. NTS9 is an DBS extension which provides peer connectivity for some NAT conﬁgurations where DBS can not provide direct peer communication.10
Peers behind the same NAT will use the same external (also called “public”, because in most cases we have not nested NAT conﬁgurations) IP address of the NAT. Basically, there exist two diﬀerent types of NATs: (1) cone, and (2) symmetric. At the same time, NATs can implement diﬀerent ﬁltering strategies for the packets that comes from the external side: (a) no ﬁltering, (b) source IP ﬁltering, and (c) source end-point ﬁltering. Finally, NATs can use several port allocation algorithms, among which, the most frequent are: (i) port preservation and (ii) random port. Notice that in this discussion, only UDP transmissions will be considered.
Lets suppose a team in which, for the sake of simplicity, there is only one external (public) peer , and that a new internal (private) peer has sent the sequence of ’s (see Sec 2.3). Lets denote ’s NAT as . When no ﬁltering is used at all, forwards to any external packet that arrives to it (obviously, if it was sent to the entry in ’s translation table that was created during the transmission of the sequence of ’s), independently on the source end-points of the packets. In the case of source (IP) address ﬁltering, will forward the packets only if they come from ’s host. When source end-point ﬁltering is used, also checks the source port, i.e., that the packets were originated at ’s end-point.
Cone NATs use the same external end-point for every packet that comes from the same internal end-point, independently on the destination of the packets (see Fig. 8). For the external peer , the situation is identical to the case in which the NATed peer would be running in a public host.
Symmetric NATs use diﬀerent external end-points for diﬀerent packets that comes from the same internal end-point, when these packets have diﬀerent destination end-points (see Fig. ??). Thus, two diﬀerent external peers will see two diﬀerent public end-points of .
In the case of port preservation, if : is the private end-point (IP address:port) of a UDP packet, the NAT will use the public port , if available (notice that cound have been assigned to a previous communcation). If were unavailable, the NAT usually will assign the closer free port (this is called “sequentially port allocation”), usually by increasing the port value, although this behavior has not been standarized at all.
When random port allocation is implemented, the public port will be assigned at random. Notice that, even in SN-PPA conﬁgurations, in most of the real situations (where peers must compete with the rest of processes that use the network for the same NAT resources,) some kind of randomization should be always expected during a the port assignment.
An incoming peer can determine its NAT behavior using the following steps:
for , the port distances gathered by .
where GCD is the Greatest Common Divisor operator.
Table 2 shows the theoretical traversal success of DBS (or an extension of it) for diﬀerent NAT type combinations. Peer1 represents to a peer already joined to the team, and Peer2 to an incoming peer. The entries labeled with “DBS” are those that will be handled by DBS, out-of-the-box. An explanation of why the DBS handshake works for such conﬁgurations is shown in Fig. 9. Notice that source end-point ﬁltering has been used in this example, although a similar results should be obtained for simple source address ﬁltering. On the other hand, the combinations labeled with “-” or “NTS” will not work with DBS (see Fig.10). In fact, only the “NTS” entries should work, in general, with NTS, depending on the port prediction algorithm and the number of tries.
Fig. 11 shows an example of an NTS (NAT traversal) success. When the new NATed peers, and , arrive at the team, the following events happen:
Summarizing, NTS can provide connectivity for those peers that are behind port-preservation symmetric NATs with sequential port allocation.
When both peers, Peer1 and Peer2, are behind symmetric NATs, both must predict the port that the NAT of the interlocutor peer will use to send the packets towards it. And obviously, this must be performed by each already incorporated peer that is behind a symmetric NAT.
The list of predicted ports that a a peer performs is determined by:
where “” denotes the concatenation of lists and is the number of guessed ports, is the ﬁrst external port (the port used to communicate with ) assigned to the incoming peer and is the (maximum) port step measured for the incoming peer’s NAT.
When using MDC , SVC , or for emulating the CS model, it can be interesting for peers to belong to more than one team. To implement MCS, peers must replicate the P2PSP modules (DBS at least) for each team (channel), except the buﬀer.
The use of MDC is trivial: the higher the number received descriptions (channels), even partially, the higher the quality of the playback. However, when transmitting SVC media, peers should prioritize the reception of the most important layers.
When a peer is in more than one team, and the teams broadcast exactly the same stream (the same chunks and headers), it could move between teams seamless (without losts of signal).
A pure CS service could be provided if the corresponding splitter announces one empty team and sends each chunk so many times as teams (with one peer/team) there are.
A variety of techniques to ﬁght pollution in P2P live streaming systems are available in the literature, including hash-based signature and data encryption techniques.
The following set of rules deals with privacy-related issues. Many content providers oﬀer pay-per-view channels as part of their services. From a technical point of view, this implies having a Key Server that ciphers the stream with a symmetric encryption key and delivers such key to authorized members only. However, this is not enough: it is crucial that the Key Server renews the encryption key after the expiration of a peer’s authorization period so the stream can not be decrypted any more by the peer (this feature is called forward secrecy). In addition, if we want to play on the safe side then the Key Server should renew the encryption key after a peer purchases an authorization period (if the key remained the same then the peer might decrypt previously captured stream packets for a later viewing). This renewal process is not trivial and is carried out by a secure multicast protocol. In order to alleviate the overhead incurred by avalanches of peers entering and leaving the authorized group (for example, at the beginning of a high interest event such as The Olympics) key renewal can be performed on a batch manner, i.e. renewing the key at a given ﬁxed frequency rather than on a per arrival/exit basis. Finally, key renewal messages should be authenticated by means of a digital signature or other alternative methods [Perrig].
Many secure multicast protocols protocols exist in the literature, for example [Xu],[Lin],[Zhou],[Yoon]. Here we suggest the implementation of a protocol by Naranjo et al [Naranjo]. On it, every authorized peer receives a large prime number from the Key Server at the beginning of its authorization period (this communication is done under a secure channel, for example SSL/TLS). For every renewal, the Key Server generates a message containing the new key to be used by means of algebraic operations: all the authorized primes are involved in this message generation process, and the key can only be extracted from the message by a peer with a valid prime. This protocol is eﬃcient and suits P2PSP architecture in a natural way: every splitter can act as a Key Server for its own team. Hence, the stream would be ﬁrst transmitted among splitters (possible encrypted by a diﬀerent key, shared by the splitters). Within each team, its corresponding splitter would control the encryption and key renewal process.
 Pierpaolo Baccichet, Jeonghun Noh, Eric Setton, and Bernd Girod. Content-aware p2p video streaming with low latency. In Multimedia and Expo, 2007 IEEE International Conference on, pages 400–403. IEEE, 2007.
 Xiaowen Chu, Kaiyong Zhao, Zongpeng Li, and Anirban Mahanti. Auction-based on-demand p2p min-cost media streaming with network coding. IEEE Transactions on Parallel and Distributed Systems, 20(12):1816–1829, 2009.