Skip to content

Commit

Permalink
local peer discovery
Browse files Browse the repository at this point in the history
  • Loading branch information
bizzehdee committed Nov 22, 2014
1 parent 580ff90 commit 70d9aeb
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 20 deletions.
97 changes: 82 additions & 15 deletions LocalPeerDiscovery.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Net.Sockets;
using System.Diagnostics;
using System.Net.Sockets;
using System.Text;
using System.Threading;

Expand All @@ -10,57 +11,105 @@ public class LocalPeerDiscovery
private const int lpdMulticastPort = 6771;

private readonly Socket udpReaderSocket;
private readonly Socket udpSenderSocket;

private Thread thread;
private bool _killSwitch;

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

public event NewPeerCB NewPeer;

private int ttl = 8;

public int TTL
{
get { return ttl; }
set
{
ttl = value;

udpSenderSocket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.MulticastTimeToLive,
ttl);
}
}

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

public LocalPeerDiscovery(Socket socket)
public LocalPeerDiscovery(Socket receive, Socket send)
{
ValidateSocket(receive, "receive");
ValidateSocket(send, "send");

udpReaderSocket = receive;
udpSenderSocket = send;
}

[DebuggerHidden, DebuggerStepThrough]
private void ValidateSocket(Socket socket, String name)
{
if (socket == null)
{
throw new ArgumentNullException("socket");
throw new ArgumentNullException(name);
}

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

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

udpReaderSocket = socket;
}

public void Open()
{
IPAddress address = IPAddress.Parse(lpdMulticastAddress);
SetupReaderSocket(address, lpdMulticastPort);
SetupSenderSocket(address, lpdMulticastPort);

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

private void SetupReaderSocket(IPAddress address, int port)
{
var endPoint = new IPEndPoint(IPAddress.Any, port);

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,
udpReaderSocket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.AddMembership,
new MulticastOption(address, IPAddress.Any));
}

thread = new Thread(Process);
thread.Start();
private void SetupSenderSocket(IPAddress address, int port)
{
var endPoint = new IPEndPoint(address, port);

udpReaderSocket.ExclusiveAddressUse = false;
udpReaderSocket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress,
true);
udpSenderSocket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.AddMembership,
new MulticastOption(address));
udpSenderSocket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.MulticastTimeToLive,
TTL);

udpSenderSocket.Connect(endPoint);
}

public void Close()
Expand All @@ -69,6 +118,7 @@ public void Close()
thread.Abort();

udpReaderSocket.Close();
udpSenderSocket.Close();
}

private void Process()
Expand Down Expand Up @@ -114,5 +164,22 @@ private void Process()
}
}
}

public void Announce(int listeningPort, String infoHash)
{
String message = String.Format("BT-SEARCH * HTTP/1.1\r\n" +
"Host: {2}:{3}\r\n" +
"Port: {0}\r\n" +
"Infohash: {1}\r\n" +
"\r\n\r\n",
listeningPort,
infoHash,
lpdMulticastAddress,
lpdMulticastPort);

byte[] buffer = Encoding.ASCII.GetBytes(message);

udpSenderSocket.Send(buffer);
}
}
}
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ System.Net.Torrent

Open source bittorrent scraper and peer wire implementation written in C#

- [x] UDP Announce
- [x] UDP Scrape
- [x] HTTP Announce
- [x] HTTP Scrape
- [x] Tracker Announce (HTTP/UDP)
- [x] Tracker Scrape (HTTP/UDP)
- [x] PeerWire (TCP) Client
- [x] Choke
- [x] Unchoke
Expand All @@ -18,6 +16,6 @@ Open source bittorrent scraper and peer wire implementation written in C#
- [x] Piece
- [x] Fast Protocol Extensions
- [x] Extended Protocol Extensions
- [ ] Local Peer Discovery
- [x] Local Peer Discovery (Non-existant Multicast BEP-14)
- [x] Peer Exchange (utPEX)
- [x] Trackerless Metadata (utMetadata)

0 comments on commit 70d9aeb

Please sign in to comment.