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

Update to the C example #5

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions c/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# Using Multipath TCP in C


It is pretty simple to use Multipath TCP with the C language. You simply need to pass IPPROTO_MPTCP as the third argument of the [socket()](https://www.man7.org/linux/man-pages/man3/socket.3p.html) system call. Make sure that IPPROTO_MPTCP is correctly defined and if you, define it as follows :
It is pretty simple to use Multipath TCP with the C language. You simply need to pass IPPROTO_MPTCP as the third argument of the [socket()](https://www.man7.org/linux/man-pages/man3/socket.3p.html) system call. Make sure that IPPROTO_MPTCP is correctly defined and if not, define it as follows :
Copy link
Collaborator

Choose a reason for hiding this comment

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

(do not hesitate to add backquotes around IPPROTO_MPTCP and any other non English words or non capitalised names)


```
#ifndef IPPROTO_MPTCP
#define IPPROTO_MPTCP 262
#endif
```

A typical socket call for Multipath TCP will look like: ` s = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP); `
A typical socket call for Multipath TCP will look like: `s = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP); `

The [simple project](mptcphello.c) in this repository also illustrates how to automatically check with autoconf whether the compilation is on a Multipath TCP enabled host, see [configure.ac](configure.ac)
Most networked applications abstract the creation of a TCP socket in a specific function that is called instead of calling [socket()](https://www.man7.org/linux/man-pages/man3/socket.3p.html) directly. This is a good opportunity to make the code portable and useable on hosts that support Multipath TCP or not. In practice, to efficiently enable Multipath TCP, your code should try to use Multipath TCP when creating the first TCP socket. If this socket is successfully created, then Multipath TCP is enabled on the host and you can continue to use Multipath TCP. Otherwise, the application is running on a host that does not yet support Multipath TCP. In this unfortunate case, you should fall back to regular TCP and always create TCP sockets. You might print an error message to encourage the user to upgrade his/her system to support Multipath TCP...
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure to understand the first sentence in this line here. I think some words are missing. Maybe:

In most network applications abstract, the creation of a TCP socket in a specific function is called instead of calling [socket()](https://www.man7.org/linux/man-pages/man3/socket.3p.html) directly.


The [simple project](mptcphello.c) in this repository illustrates this strategy. If you want to automatically check with autoconf whether the compilation is on a Multipath TCP enabled host, see [configure.ac](configure.ac)
Copy link
Collaborator

Choose a reason for hiding this comment

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

for the configure.ac, I would put big warnings to avoid doing that at compilation time except maybe to simplify tests (and still, I don't think it is a good idea to do that at the compilation time, even for tests but that's another story :) )


48 changes: 33 additions & 15 deletions c/mptcphello.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,52 @@
#include <sys/socket.h>
#include <stdbool.h>
#include <netinet/in.h>
#include <errno.h>

// IPPROTO_MPTCP is defined in <netinet/in.h> on recent kernels only
Copy link
Collaborator

Choose a reason for hiding this comment

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

(it depends on the libc version in fact, not the kernel in fact but that's probably a detail)


#ifndef IPPROTO_MPTCP
#define IPPROTO_MPTCP 262
#endif



/*
* Create a Multipath TCP socket for the specified domain
* If the creation fails because Multipath TCP is not supported
* on this system, falls back to regular TCP
*/
int socket_create(int domain) {

bool use_mptcp = true;
// if true, try always enable Multipath TCP for TCP sockets
static bool use_mptcp = true;
int s;
if(use_mptcp) {
s = socket(domain, SOCK_STREAM, IPPROTO_MPTCP);
if(s==-1 && ( errno==EPROTONOSUPPORT || errno==ENOPROTOOPT) ) {
// Multipath TCP is not supported on this system
use_mptcp = false;
Copy link
Collaborator

Choose a reason for hiding this comment

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

maybe good to re-add a clear error message?

fprintf(stderr, "Unable to create an MPTCP socket: "
        "your kernel probably don't support MPTCP yet, "
        "falling back to TCP for this socket and all the next ones.\n");

// Fall back to regular TCP
} else {
// Multipath TCP socket was created or another error occured
return s;
}
}
// Multipath TCP is not supported on this system, return a TCP socket
return(socket(domain, SOCK_STREAM, IPPROTO_TCP));
Copy link
Collaborator

Choose a reason for hiding this comment

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

(parenthesis not needed after the return)


}

int main(int argc, char **argv) {

int s;


if (use_mptcp) {
s = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP);
if (s == -1) {
use_mptcp = false;
fprintf(stderr, "Could not create MPTCP socket, falling back to TCP \n");
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s ==-1) {
fprintf(stderr, "Could not create TCP socket\n");
exit(-1);
}
}
close(s);
exit(0);
}

s = socket_create(AF_INET);
Copy link
Collaborator

Choose a reason for hiding this comment

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

maybe good to check for errors?

if (s < 0) {
    fprintf(stderr, "Unable to create a socket\n");
    exit(EXIT_FAILURE);
}

// do something useful with the socket

close(s);

return EXIT_SUCCESS;


// do something useful with the socket

close(s);

Copy link
Collaborator

Choose a reason for hiding this comment

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

(no need to have a return to avoid a warning? Or maybe only visible with -Wall?)

}