From 12c3181b65a2664f11559e6f4ad9b39743076fd2 Mon Sep 17 00:00:00 2001
From: Richard Nyberg <rnyberg@murmeldjur.se>
Date: Wed, 15 Nov 2006 13:30:39 +0000
Subject: [PATCH] Add an option to specify the ip the tracker should distribute
 for this peer.

---
 btpd/http_tr_if.c | 15 ++++++++++++---
 btpd/main.c       | 18 ++++++++++++++++++
 btpd/opts.c       |  2 ++
 btpd/opts.h       |  1 +
 4 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/btpd/http_tr_if.c b/btpd/http_tr_if.c
index ab5639a..78741ac 100644
--- a/btpd/http_tr_if.c
+++ b/btpd/http_tr_if.c
@@ -1,3 +1,5 @@
+#include <arpa/inet.h>
+#include <netinet/in.h>
 #include <string.h>
 
 #include "btpd.h"
@@ -137,7 +139,7 @@ http_cb(struct http_req *req, struct http_response *res, void *arg)
 struct http_tr_req *
 http_tr_req(struct torrent *tp, enum tr_event event, const char *aurl)
 {
-    char e_hash[61], e_id[61], url[512], qc;;
+    char e_hash[61], e_id[61], ip_arg[INET_ADDRSTRLEN + 4], url[512], qc;
     const uint8_t *peer_id = btpd_get_peer_id();
 
     qc = (strchr(aurl, '?') == NULL) ? '?' : '&';
@@ -147,10 +149,17 @@ http_tr_req(struct torrent *tp, enum tr_event event, const char *aurl)
     for (int i = 0; i < 20; i++)
         snprintf(e_id + i * 3, 4, "%%%.2x", peer_id[i]);
 
+    if (tr_ip_arg == INADDR_ANY)
+        ip_arg[0] = '\0';
+    else {
+        bcopy("&ip=", ip_arg, 4);
+        inet_ntop(AF_INET, &tr_ip_arg, ip_arg + 4, sizeof(ip_arg) - 4);
+    }
+
     snprintf(url, sizeof(url),
-        "%s%cinfo_hash=%s&peer_id=%s&key=%ld&port=%d&uploaded=%llu"
+        "%s%cinfo_hash=%s&peer_id=%s&key=%ld%s&port=%d&uploaded=%llu"
         "&downloaded=%llu&left=%llu&compact=1%s%s",
-        aurl, qc, e_hash, e_id, tr_key, net_port,
+        aurl, qc, e_hash, e_id, tr_key, ip_arg, net_port,
         tp->net->uploaded, tp->net->downloaded,
         (long long)tp->total_length - cm_content(tp),
         event == TR_EV_EMPTY ? "" : "&event=", m_tr_events[event]);
diff --git a/btpd/main.c b/btpd/main.c
index 5eb40fd..79bbcd9 100644
--- a/btpd/main.c
+++ b/btpd/main.c
@@ -1,6 +1,7 @@
 #include <sys/types.h>
 #include <sys/file.h>
 #include <sys/stat.h>
+#include <arpa/inet.h>
 
 #include <err.h>
 #include <errno.h>
@@ -101,6 +102,11 @@ usage(void)
         "--help\n"
         "\tShow this text.\n"
         "\n"
+        "--ip addr\n"
+        "\tMake other peers use the given address, instead of the one\n"
+        "\tthe tracker perceives as this peer's address, when contacting\n"
+        "\tthis peer.\n"
+        "\n"
         "--ipcprot mode\n"
         "\tSet the protection mode of the command socket.\n"
         "\tThe mode is specified by an octal number. Default is 0600.\n"
@@ -147,6 +153,7 @@ static struct option longopts[] = {
     { "logfile", required_argument,     &longval,       7 },
     { "ipcprot", required_argument,     &longval,       8 },
     { "empty-start", no_argument,       &longval,       9 },
+    { "ip", required_argument,          &longval,       10 },
     { "help",   no_argument,            &longval,       128 },
     { NULL,     0,                      NULL,           0 }
 };
@@ -196,6 +203,17 @@ main(int argc, char **argv)
             case 9:
                 empty_start = 1;
                 break;
+            case 10:
+                switch (inet_pton(AF_INET, optarg, &tr_ip_arg)) {
+                case 1:
+                    break;
+                case 0:
+                    errx(1, "You must specify a dotted IPv4 address.\n");
+                    break;
+                default:
+                    err(1, "inet_ntop %s", optarg);
+                }
+                break;
             default:
                 usage();
             }
diff --git a/btpd/opts.c b/btpd/opts.c
index a6f5817..acaf034 100644
--- a/btpd/opts.c
+++ b/btpd/opts.c
@@ -1,3 +1,4 @@
+#include <netinet/in.h>
 #include <btpd.h>
 
 const char *btpd_dir;
@@ -14,3 +15,4 @@ int net_port = 6881;
 off_t cm_alloc_size = 2048 * 1024;
 int ipcprot = 0600;
 int empty_start = 0;
+uint32_t tr_ip_arg = INADDR_ANY;
diff --git a/btpd/opts.h b/btpd/opts.h
index 8372f4d..dc819f0 100644
--- a/btpd/opts.h
+++ b/btpd/opts.h
@@ -11,5 +11,6 @@ extern int net_port;
 extern off_t cm_alloc_size;
 extern int ipcprot;
 extern int empty_start;
+extern uint32_t tr_ip_arg;
 
 #endif