Kristian Evensen
2016-09-18 11:25:58 UTC
The current --server syntax allows for binding to interface or address. However,
in some (admittedly special) cases it is useful to be able to specify both. This
commit introduces the following syntax to support binding to both interface and
address:
--server ***@IP@interface#port
Based on my tests, the syntax is backwards compatible with the current
@IP/interface#port. The code will fail if two interface names are given.
Signed-off-by: Kristian Evensen <***@gmail.com>
---
src/option.c | 36 ++++++++++++++++++++++++++++++++----
1 file changed, 32 insertions(+), 4 deletions(-)
diff --git a/src/option.c b/src/option.c
index d0d9509..bcb19a9 100644
--- a/src/option.c
+++ b/src/option.c
@@ -757,6 +757,7 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
{
int source_port = 0, serv_port = NAMESERVER_PORT;
char *portno, *source;
+ char *interface_opt = NULL;
#ifdef HAVE_IPV6
int scope_index = 0;
char *scope_id;
@@ -782,6 +783,19 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
scope_id = split_chr(arg, '%');
#endif
+ if (source) {
+ interface_opt = split_chr(source, '@');
+
+ if (interface_opt)
+ {
+#if defined(SO_BINDTODEVICE)
+ strncpy(interface, interface_opt, IF_NAMESIZE - 1);
+#else
+ return _("interface binding not supported");
+#endif
+ }
+ }
+
if (inet_pton(AF_INET, arg, &addr->in.sin_addr) > 0)
{
addr->in.sin_port = htons(serv_port);
@@ -800,8 +814,15 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
if (!(inet_pton(AF_INET, source, &source_addr->in.sin_addr) > 0))
{
#if defined(SO_BINDTODEVICE)
- source_addr->in.sin_addr.s_addr = INADDR_ANY;
- strncpy(interface, source, IF_NAMESIZE - 1);
+ if (interface_opt)
+ {
+ return _("interface can only be specified once");
+ }
+ else
+ {
+ source_addr->in.sin_addr.s_addr = INADDR_ANY;
+ strncpy(interface, source, IF_NAMESIZE - 1);
+ }
#else
return _("interface binding not supported");
#endif
@@ -832,8 +853,15 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
if (inet_pton(AF_INET6, source, &source_addr->in6.sin6_addr) == 0)
{
#if defined(SO_BINDTODEVICE)
- source_addr->in6.sin6_addr = in6addr_any;
- strncpy(interface, source, IF_NAMESIZE - 1);
+ if (interface_opt)
+ {
+ return _("interface can only be specified once");
+ }
+ else
+ {
+ source_addr->in6.sin6_addr = in6addr_any;
+ strncpy(interface, source, IF_NAMESIZE - 1);
+ }
#else
return _("interface binding not supported");
#endif
in some (admittedly special) cases it is useful to be able to specify both. This
commit introduces the following syntax to support binding to both interface and
address:
--server ***@IP@interface#port
Based on my tests, the syntax is backwards compatible with the current
@IP/interface#port. The code will fail if two interface names are given.
Signed-off-by: Kristian Evensen <***@gmail.com>
---
src/option.c | 36 ++++++++++++++++++++++++++++++++----
1 file changed, 32 insertions(+), 4 deletions(-)
diff --git a/src/option.c b/src/option.c
index d0d9509..bcb19a9 100644
--- a/src/option.c
+++ b/src/option.c
@@ -757,6 +757,7 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
{
int source_port = 0, serv_port = NAMESERVER_PORT;
char *portno, *source;
+ char *interface_opt = NULL;
#ifdef HAVE_IPV6
int scope_index = 0;
char *scope_id;
@@ -782,6 +783,19 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
scope_id = split_chr(arg, '%');
#endif
+ if (source) {
+ interface_opt = split_chr(source, '@');
+
+ if (interface_opt)
+ {
+#if defined(SO_BINDTODEVICE)
+ strncpy(interface, interface_opt, IF_NAMESIZE - 1);
+#else
+ return _("interface binding not supported");
+#endif
+ }
+ }
+
if (inet_pton(AF_INET, arg, &addr->in.sin_addr) > 0)
{
addr->in.sin_port = htons(serv_port);
@@ -800,8 +814,15 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
if (!(inet_pton(AF_INET, source, &source_addr->in.sin_addr) > 0))
{
#if defined(SO_BINDTODEVICE)
- source_addr->in.sin_addr.s_addr = INADDR_ANY;
- strncpy(interface, source, IF_NAMESIZE - 1);
+ if (interface_opt)
+ {
+ return _("interface can only be specified once");
+ }
+ else
+ {
+ source_addr->in.sin_addr.s_addr = INADDR_ANY;
+ strncpy(interface, source, IF_NAMESIZE - 1);
+ }
#else
return _("interface binding not supported");
#endif
@@ -832,8 +853,15 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
if (inet_pton(AF_INET6, source, &source_addr->in6.sin6_addr) == 0)
{
#if defined(SO_BINDTODEVICE)
- source_addr->in6.sin6_addr = in6addr_any;
- strncpy(interface, source, IF_NAMESIZE - 1);
+ if (interface_opt)
+ {
+ return _("interface can only be specified once");
+ }
+ else
+ {
+ source_addr->in6.sin6_addr = in6addr_any;
+ strncpy(interface, source, IF_NAMESIZE - 1);
+ }
#else
return _("interface binding not supported");
#endif
--
2.5.0
2.5.0