diff --git a/doc/Holepunch-Protocol.txt b/doc/Holepunch-Protocol.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5bbad67557a5eda8ca9d970dd212a056ee469cd0
--- /dev/null
+++ b/doc/Holepunch-Protocol.txt
@@ -0,0 +1,34 @@
+             Bird's Hole Punching Protocol
+
+
+Hole punch - a mechanism to bypass a firewall
+Server     - a third party which is not behind a firewall
+Client     - anything contacting the server
+Magic      - the four bytes 00 52 EB 11
+Address    - an IPv4 address
+
+
+                  0 1 2 3 4 5 6 7 8  9
+                 +-------+-------+----+
+                 | Magic |Address|Port|
+                 +-------+-------+----+
+                      Relay Packet
+
+
+A client that expects to be the target of a hole punch
+must contact the server frequently, to keep a UDP
+"connection" open, so that the server may relay hole
+punching requests to them.
+
+A client makes a hole punching request to another client
+by sending a Relay Packet to the server. The server then
+sends another Relay Packet to the client described by the
+first packet. The second packet is filled with the source
+address and port of the first packet.
+
+Once a client receives a Relay Packet, this protocol's
+purpose is fulfilled and the client is aware that another
+client requests a hole punch.
+
+
+vim: noai
diff --git a/src/i_tcp.c b/src/i_tcp.c
index cf99fccb6208a9893a6887d7cc596229478491c4..2a80022ef786ae9c05643799674273e1950a3a4f 100644
--- a/src/i_tcp.c
+++ b/src/i_tcp.c
@@ -241,6 +241,7 @@ static size_t broadcastaddresses = 0;
 static boolean nodeconnected[MAXNETNODES+1];
 static mysockaddr_t banned[MAXBANS];
 static UINT8 bannedmask[MAXBANS];
+/* See ../doc/Holepunch-Protocol.txt */
 static const INT32 hole_punch_magic = MSBF_LONG (0x52eb11);
 #endif
 
@@ -600,6 +601,7 @@ void Command_Numnodes(void)
 #ifndef NONET
 static boolean hole_punch(ssize_t c)
 {
+	/* See ../doc/Holepunch-Protocol.txt */
 	if (cv_rendezvousserver.string[0] &&
 			c == 10 && holepunchpacket->magic == hole_punch_magic)
 	{
@@ -1408,6 +1410,8 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
 	return newnode;
 }
 
+/* See ../doc/Holepunch-Protocol.txt */
+
 static void rendezvous(int size)
 {
 	char *addrs = strdup(cv_rendezvousserver.string);