Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add dual-stack socket support for FTL #180

Merged
merged 14 commits into from
Jan 12, 2018
Merged

Add dual-stack socket support for FTL #180

merged 14 commits into from
Jan 12, 2018

Conversation

DL6ER
Copy link
Member

@DL6ER DL6ER commented Dec 26, 2017

By submitting this pull request, I confirm the following (please check boxes, eg [X]) Failure to fill the template will close your PR:

Please submit all pull requests against the development branch. Failure to do so will delay or deny your request

  • I have read and understood the contributors guide.
  • I have checked that another pull request for this purpose does not exist.
  • I have considered, and confirmed that this submission will be valuable to others.
  • I accept that this submission may not be used, and the pull request closed at the will of the maintainer.
  • I give this submission freely, and claim no ownership to its content.

How familiar are you with the codebase?:

10


This pull request adds full dual-stack support for FTL's telnet-like socket. Previously, we bound only to an IPv4 port, now we bind to both the IPv4 and IPv6 port spaces.

In case no IPv6 interface is available (e.g. in docker), FTL will bind only to the IPv4 port - just as it did before.

This template was created based on the work of udemy-dl.

@DL6ER DL6ER added this to the v3.0 milestone Dec 26, 2017
@DL6ER DL6ER removed this from the v3.0 milestone Dec 26, 2017
@DL6ER
Copy link
Member Author

DL6ER commented Dec 26, 2017

Before this pull request:

$ echo ">quit" | nc -v 127.0.0.1 4711
Connection to 127.0.0.1 4711 port [tcp/*] succeeded!

$ echo ">quit" | nc -v ::1 4711
nc: connect to ::1 port 4711 (tcp) failed: Connection refused

With the proposed changes:

$ echo ">quit" | nc -v 127.0.0.1 4711
Connection to 127.0.0.1 4711 port [tcp/*] succeeded!

$ echo ">quit" | nc -v ::1 4711
Connection to ::1 4711 port [tcp/*] succeeded!

@DL6ER DL6ER changed the title Add dual-stack socket support for FTL [WIP] Add dual-stack socket support for FTL Dec 26, 2017
@DL6ER DL6ER changed the title [WIP] Add dual-stack socket support for FTL Add dual-stack socket support for FTL Dec 26, 2017
@DL6ER
Copy link
Member Author

DL6ER commented Jan 9, 2018

Resolved merge conflicts, what you you think? @Mcat12 @dschaper

socket.c Outdated
@@ -117,7 +151,7 @@ void bind_to_telnet_port(char type, int *socketdescriptor)
exit(EXIT_FAILURE);
}

logg("Listening on port %i for incoming connections", port);
logg("Listening on port %i for incoming %s connections", port, dualstack == true ? "IPv4 + IPv6" : "IPv4");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The == true can be removed since dualstack is a boolean already.

socket.c Outdated
if(bind(*socketdescriptor, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
logg("Error on binding on port %i", port);
}
else
{
bound = true;
dualstack = true;
break;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On a non-IPv6 system this would produce 20 lines of errors saying it can't bind to a port. Is there a quicker way to figure out if we have IPv6 access?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how to detect if the system has a working ipv6 interface. If we cannot find out how to do it, we could also change the error reporting (don't report on the Individual failures, but only once at the end when we couldn't find at least one port).

DL6ER added 3 commits January 9, 2018 19:59
…accordingly (don't try to bind to a dual-stack port if the machine isn't capable to handling IPv6, e.g. in docker)

Signed-off-by: DL6ER <[email protected]>
@DL6ER DL6ER changed the title Add dual-stack socket support for FTL [WIP] Add dual-stack socket support for FTL Jan 9, 2018
@DL6ER
Copy link
Member Author

DL6ER commented Jan 9, 2018

Marking as [WIP]

While in6addr_any accepts IPv4 and IPv6 connections simultaneously, in6addr_loopback only accepts connections to ::1. Have to further investigate on this.

… IPv4-only and one for IPv6-only) to be able to bind to the corresponding loopback interfaces. We listen independently, but handle incoming requests using the same code.

Signed-off-by: DL6ER <[email protected]>
@DL6ER DL6ER changed the title [WIP] Add dual-stack socket support for FTL Add dual-stack socket support for FTL Jan 10, 2018
@DL6ER
Copy link
Member Author

DL6ER commented Jan 10, 2018

Completely re-wrote this feature.

In case you are interested , here is the result of my research:
An IPv4 client can connect to INADDR_LOOPBACK (a.k.a. 127.0.0.1) on an dual-stack listening socket *if the listening socket is bound to IN6ADDR_ANY (a.k.a. ::). This is very convenient and allows to write more simple code that can live in both, the IPv4 and the IPv6 world at the same time.

However, an essential security feature of FTL (that can be disabled trough the config file) is that FTL does, by default, only bind to the lo interface such that data is only available locally and not from anywhere else in the network.
However, when binding a dual-stack socket to IN6ADDR_LOOPBACK (a.k.a. ::1), this will prevent IPv4 clients from being able to connect. Although he reason is simple it not very obvious: First, we have to understand that the socket lives in the IPv6 world, i.e. when an IPv4 client connects, it will be seen by the socket as connecting from the corresponding IPv4-mapped IPv6 address. Hence, when connecting to/from 127.0.0.1 the dual-stack socket will see the connection going to the IPv4-mapped IPv6 address ::FFFF:7F00:0001 (the equivalent of 127.0.0.1). However, as the dual-stack socket is explicitly bound to ::1 (and not ::) the IPv4 client cannot connect.

socket.c Outdated
{
// Try IPv4 only socket
// see the comments further up for details
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is no longer valid

socket.c Outdated
logg("Reason: %s (%i)", strerror(errno), errno);
if(bind(*socketdescriptor, (struct sockaddr *) &address, sizeof (address)) != 0)
{
logg("Error on binding on unix socket %s: %s (%i)", FTLfiles.socketfile, strerror(errno), errno);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unix is capitalized elsewhere.

socket.c Outdated
@@ -335,16 +383,69 @@ void *telnet_listening_thread(void *args)
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

// Set thread name
prctl(PR_SET_NAME,"telnet listener",0,0,0);
prctl(PR_SET_NAME,"telnet-v4",0,0,0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use IPv4 to distinguish this from appearing to be telnet version 4 API.

socket.c Outdated
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

// Set thread name
prctl(PR_SET_NAME,"telnet-v6",0,0,0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

@DL6ER DL6ER merged commit bb7bf43 into development Jan 12, 2018
@DL6ER DL6ER deleted the new/IPv6support branch January 12, 2018 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants