Re: [Bug-wget] Add support to bind to a local port
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
Hi, some minor comments: Darshit Shahwrites: > +@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
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 ShahDate: 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_("\ +