Skip to content

Commit

Permalink
Implementing Local Peer Discovery receiving
Browse files Browse the repository at this point in the history
  • Loading branch information
bizzehdee committed Nov 22, 2014
1 parent 1dbbad2 commit 580ff90
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 1 deletion.
118 changes: 118 additions & 0 deletions LocalPeerDiscovery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace System.Net.Torrent
{
public class LocalPeerDiscovery
{
private const string lpdMulticastAddress = "239.192.152.143";
private const int lpdMulticastPort = 6771;

private readonly Socket udpReaderSocket;

private Thread thread;
private bool _killSwitch;

public delegate void NewPeerCB(IPAddress address, int port, String infoHash);

public event NewPeerCB NewPeer;

public LocalPeerDiscovery()
{
udpReaderSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
}

public LocalPeerDiscovery(Socket socket)
{
if (socket == null)
{
throw new ArgumentNullException("socket");
}

if (socket.ProtocolType != ProtocolType.Udp)
{
throw new ArgumentException("socket must be a UDP socket", "socket");
}

if (socket.SocketType != SocketType.Dgram)
{
throw new ArgumentException("socket must be a datagram socket", "socket");
}

udpReaderSocket = socket;
}

public void Open()
{
udpReaderSocket.ExclusiveAddressUse = false;
udpReaderSocket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress,
true);

IPAddress address = IPAddress.Parse(lpdMulticastAddress);

var endPoint = new IPEndPoint(IPAddress.Any, lpdMulticastPort);
udpReaderSocket.Bind(endPoint);

udpReaderSocket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.AddMembership,
new MulticastOption(address, IPAddress.Any));

thread = new Thread(Process);
thread.Start();
}

public void Close()
{
_killSwitch = true;
thread.Abort();

udpReaderSocket.Close();
}

private void Process()
{
byte[] buffer = new byte[200];
while (!_killSwitch)
{
EndPoint endPoint = new IPEndPoint(0,0);
udpReaderSocket.ReceiveFrom(buffer, ref endPoint);

IPAddress remoteAddress = ((IPEndPoint) endPoint).Address;
int remotePort = 0;
string remoteHash = "";

String packet = Encoding.ASCII.GetString(buffer).Trim();

if (!packet.StartsWith("BT-SEARCH"))
{
continue;
}

String[] packetLines = packet.Split('\n');

foreach (string line in packetLines)
{
if (line.StartsWith("Port:"))
{
string portStr = line.Substring(5).Trim();
int.TryParse(portStr, out remotePort);
}
if (line.StartsWith("Infohash:"))
{
remoteHash = line.Substring(10, 40);
}
}

if (!String.IsNullOrEmpty(remoteHash) && remotePort != 0)
{
if (NewPeer != null)
{
NewPeer(remoteAddress, remotePort, remoteHash);
}
}
}
}
}
}
2 changes: 1 addition & 1 deletion Metadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ public bool Load(Stream stream)
BString pieces = (BString)infoDict["pieces"];
for (int x = 0; x < pieces.ByteValue.Length; x += 20)
{
byte[] hash = Utils.GetBytes(pieces.ByteValue, x, 20);
byte[] hash = pieces.ByteValue.GetBytes(x, 20);
PieceHashes.Add(hash);
}
}
Expand Down
1 change: 1 addition & 0 deletions System.Net.Torrent.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
<Compile Include="Extensions\UTPeerExchange.cs" />
<Compile Include="HTTPTrackerClient.cs" />
<Compile Include="IO\WireIO.Udp.cs" />
<Compile Include="LocalPeerDiscovery.cs" />
<Compile Include="ProtocolExtensions\IBTExtension.cs" />
<Compile Include="IPeerCommand.cs" />
<Compile Include="IProtocolExtension.cs" />
Expand Down

0 comments on commit 580ff90

Please sign in to comment.