Re: [Bug-wget] Add support to bind to a local port

2018-05-03 Thread Tim Rühsen
On 03.05.2018 19:16, Darshit Shah wrote:
> +  { "bindport",  _port, 
> cmd_number },
>{ "bodydata", _data, cmd_string },

There are more tabs here.

I think that port binding does work with address 'ANY'.
So wouldn't it be possible to use --bind-port without --bind-address ?

Regards, Tim




signature.asc
Description: OpenPGP digital signature


Re: [Bug-wget] Add support to bind to a local port

2018-05-03 Thread Giuseppe Scrivano
Hi,

some minor comments:

Darshit Shah  writes:

> +@cindex bind port
> +@cindex client port number
> +@cindex IP address, client, port
> +@item --bind-port=@var{PORT}
> +When making client TCP/IP connections using @samp{--bind-address}, 
> additionally
> +bind to a specific @var{PORT} on the client machine.  If a negative value is
> +passed as the parameter, then the default vallue of 0 will be used.

s|vallue|value|

> diff --git a/src/connect.c b/src/connect.c
> index 37dae215..37a30879 100644
> --- a/src/connect.c
> +++ b/src/connect.c
> @@ -187,7 +187,7 @@ resolve_bind_address (struct sockaddr *sa)
>if (called)
>  {
>if (should_bind)
> -sockaddr_set_data (sa, , 0);
> +sockaddr_set_data (sa, , opt.bind_port);
>return should_bind;
>  }
>called = true;
> @@ -209,7 +209,7 @@ resolve_bind_address (struct sockaddr *sa)
>ip = *address_list_address_at (al, 0);
>address_list_release (al);
>  
> -  sockaddr_set_data (sa, , 0);
> +  sockaddr_set_data (sa, , opt.bind_port);
>should_bind = true;
>return true;
>  }
> @@ -340,6 +340,19 @@ connect_to_ip (const ip_address *ip, int port, const 
> char *print)
>struct sockaddr *bind_sa = (struct sockaddr *)_ss;
>if (resolve_bind_address (bind_sa))
>  {
> +
> +   // Set the SO_REUSEADDR socket option if it is available. It is
> +// useful when explicitly binding to a given address

mix of spaces and tabs here.

> +#ifdef SO_REUSEADDR
> +  /* For setting options with setsockopt. */
> +  int setopt_val = 1;
> +  void *setopt_ptr = (void *)_val;
> +  socklen_t setopt_size = sizeof (setopt_val);
> +
> +  if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, setopt_ptr, 
> setopt_size))
> +logprintf (LOG_NOTQUIET, _("setsockopt SO_REUSEADDR failed: 
> %s\n"),
> +   strerror (errno));
> +#endif
>if (bind (sock, bind_sa, sockaddr_size (bind_sa)) < 0)
>  goto err;
>  }
> diff --git a/src/init.c b/src/init.c
> index e4186abe..98b6ac45 100644
> --- a/src/init.c
> +++ b/src/init.c
> @@ -150,6 +150,7 @@ static const struct {
>  #ifdef HAVE_LIBCARES
>{ "binddnsaddress",   _dns_address,  cmd_string },
>  #endif
> +  { "bindport",  _port, 
> cmd_number },
>{ "bodydata", _data, cmd_string },
>{ "bodyfile", _file, cmd_string },
>  #ifdef HAVE_SSL
> @@ -396,6 +397,7 @@ defaults (void)
>opt.metalink_index = -1;
>  #endif
>  
> +  opt.bind_port = -1;
>opt.cookies = true;
>opt.verbose = -1;
>opt.ntry = 20;
> diff --git a/src/main.c b/src/main.c
> index 46824efd..c6e560bd 100644
> --- a/src/main.c
> +++ b/src/main.c
> @@ -275,6 +275,7 @@ static struct cmdline_option option_data[] =
>  #ifdef HAVE_LIBCARES
>  { "bind-dns-address", 0, OPT_VALUE, "binddnsaddress", -1 },
>  #endif
> +{ "bind-port", 0, OPT_VALUE, "bindport", -1 },
>  { "body-data", 0, OPT_VALUE, "bodydata", -1 },
>  { "body-file", 0, OPT_VALUE, "bodyfile", -1 },
>  { IF_SSL ("ca-certificate"), 0, OPT_VALUE, "cacertificate", -1 },
> @@ -692,6 +693,8 @@ Download:\n"),
>-Q,  --quota=NUMBER  set retrieval quota to NUMBER\n"),
>  N_("\
> --bind-address=ADDRESS  bind to ADDRESS (hostname or IP) on local 
> host\n"),
> +N_("\
> +   --bind-port=PORTbind to PORT on local host\n"),
>  N_("\
> --limit-rate=RATE   limit download rate to RATE\n"),
>  N_("\
> @@ -1749,6 +1752,15 @@ for details.\n\n"));
>exit (WGET_EXIT_GENERIC_ERROR);
>  }
>  
> +  if (opt.bind_port != -1 && !opt.bind_address) {
> +fprintf (stderr, _("bind-port requires bind-address to also be 
> specified.\n"));
> +exit (WGET_EXIT_GENERIC_ERROR);
> +  } else {
> +// We explicitly set the port to 0 if nothing (or a negative value) is
> +// specified
> +opt.bind_port = MAX(opt.bind_port, 0);
> +  }
> +
>/* Compile the regular expressions.  */
>switch (opt.regex_type)
>  {
> diff --git a/src/options.h b/src/options.h
> index 30845a1b..777affad 100644
> --- a/src/options.h
> +++ b/src/options.h
> @@ -219,6 +219,7 @@ struct options
>bool page_requisites; /* Whether we need to download all files
> necessary to display a page properly. */
>char *bind_address;   /* What local IP address to bind to. */
> +  int bind_port; /* What local port to bind to. 
> */

same here, there are some tabs.

Thanks,
Giuseppe



[Bug-wget] Add support to bind to a local port

2018-05-03 Thread Darshit Shah
This patch adds support to bind Wget's client socket to a user specified port.


-- 
Thanking You,
Darshit Shah
PGP Fingerprint: 7845 120B 07CB D8D6 ECE5 FF2B 2A17 43ED A91A 35B6
From 033a14cc952bd93618fa9b52f26beb4783a55d5f Mon Sep 17 00:00:00 2001
From: Darshit Shah 
Date: Thu, 3 May 2018 18:26:38 +0200
Subject: [PATCH] Add support for binding to local port

* src/options.h: Intriduce bind_port variable
* src/init.c: initialize bind_port to -1 to indicate no user value
* src/main.c: Add bind_port to command line options. Also ensure that
port is only specified along with bind_address
* src/connect.c: Use the specified bind_port when binding to a specific
address.
Also set the SO_REUSEADDR option on the socket when binding to a local
address
* doc/wget.texi: Add documentation for new option
---
 doc/wget.texi | 11 +++
 src/connect.c | 17 +++--
 src/init.c|  2 ++
 src/main.c| 12 
 src/options.h |  1 +
 5 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/doc/wget.texi b/doc/wget.texi
index 5fd11137..9b2f1a0a 100644
--- a/doc/wget.texi
+++ b/doc/wget.texi
@@ -591,6 +591,14 @@ the local machine.  @var{ADDRESS} may be specified as a 
hostname or IP
 address.  This option can be useful if your machine is bound to multiple
 IPs.
 
+@cindex bind port
+@cindex client port number
+@cindex IP address, client, port
+@item --bind-port=@var{PORT}
+When making client TCP/IP connections using @samp{--bind-address}, additionally
+bind to a specific @var{PORT} on the client machine.  If a negative value is
+passed as the parameter, then the default vallue of 0 will be used.
+
 @cindex bind DNS address
 @cindex client DNS address
 @cindex DNS IP address, client, DNS
@@ -3243,6 +3251,9 @@ as being relative to @var{string}---the same as 
@samp{--base=@var{string}}.
 @item bind_address = @var{address}
 Bind to @var{address}, like the @samp{--bind-address=@var{address}}.
 
+@item bind_port = @var{port}
+In addition to @samp{bind_address}, bind to specific @var{port}.
+
 @item ca_certificate = @var{file}
 Set the certificate authority bundle file to @var{file}.  The same
 as @samp{--ca-certificate=@var{file}}.
diff --git a/src/connect.c b/src/connect.c
index 37dae215..37a30879 100644
--- a/src/connect.c
+++ b/src/connect.c
@@ -187,7 +187,7 @@ resolve_bind_address (struct sockaddr *sa)
   if (called)
 {
   if (should_bind)
-sockaddr_set_data (sa, , 0);
+sockaddr_set_data (sa, , opt.bind_port);
   return should_bind;
 }
   called = true;
@@ -209,7 +209,7 @@ resolve_bind_address (struct sockaddr *sa)
   ip = *address_list_address_at (al, 0);
   address_list_release (al);
 
-  sockaddr_set_data (sa, , 0);
+  sockaddr_set_data (sa, , opt.bind_port);
   should_bind = true;
   return true;
 }
@@ -340,6 +340,19 @@ connect_to_ip (const ip_address *ip, int port, const char 
*print)
   struct sockaddr *bind_sa = (struct sockaddr *)_ss;
   if (resolve_bind_address (bind_sa))
 {
+
+   // Set the SO_REUSEADDR socket option if it is available. It is
+  // useful when explicitly binding to a given address
+#ifdef SO_REUSEADDR
+  /* For setting options with setsockopt. */
+  int setopt_val = 1;
+  void *setopt_ptr = (void *)_val;
+  socklen_t setopt_size = sizeof (setopt_val);
+
+  if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, setopt_ptr, 
setopt_size))
+logprintf (LOG_NOTQUIET, _("setsockopt SO_REUSEADDR failed: %s\n"),
+   strerror (errno));
+#endif
   if (bind (sock, bind_sa, sockaddr_size (bind_sa)) < 0)
 goto err;
 }
diff --git a/src/init.c b/src/init.c
index e4186abe..98b6ac45 100644
--- a/src/init.c
+++ b/src/init.c
@@ -150,6 +150,7 @@ static const struct {
 #ifdef HAVE_LIBCARES
   { "binddnsaddress",   _dns_address,  cmd_string },
 #endif
+  { "bindport",_port, 
cmd_number },
   { "bodydata", _data, cmd_string },
   { "bodyfile", _file, cmd_string },
 #ifdef HAVE_SSL
@@ -396,6 +397,7 @@ defaults (void)
   opt.metalink_index = -1;
 #endif
 
+  opt.bind_port = -1;
   opt.cookies = true;
   opt.verbose = -1;
   opt.ntry = 20;
diff --git a/src/main.c b/src/main.c
index 46824efd..c6e560bd 100644
--- a/src/main.c
+++ b/src/main.c
@@ -275,6 +275,7 @@ static struct cmdline_option option_data[] =
 #ifdef HAVE_LIBCARES
 { "bind-dns-address", 0, OPT_VALUE, "binddnsaddress", -1 },
 #endif
+{ "bind-port", 0, OPT_VALUE, "bindport", -1 },
 { "body-data", 0, OPT_VALUE, "bodydata", -1 },
 { "body-file", 0, OPT_VALUE, "bodyfile", -1 },
 { IF_SSL ("ca-certificate"), 0, OPT_VALUE, "cacertificate", -1 },
@@ -692,6 +693,8 @@ Download:\n"),
   -Q,  --quota=NUMBER  set retrieval quota to NUMBER\n"),
 N_("\
--bind-address=ADDRESS  bind to ADDRESS (hostname or IP) on local 
host\n"),
+N_("\
+