git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Small patch to add support for MPTCP on Linux

From
Muhammad Nuzaihan <zaihan@unrealasia.net>
Date
May 20, 2025, 04:32 UTC
Message-ID
<ZXLJWS.WPQLCXFNN8TH@unrealasia.net>
In-Reply-To
<xmqqo6vokvpv.fsf@gitster.g>

On Mon, May 19 2025 at 04:49:00 PM -0700, Junio C Hamano <gitster@pobox.com> wrote:

Show 38 quoted lines
> Phillip Wood <phillip.wood123@gmail.com> writes:
> 
>>  As brian has already said I think it would be better to have a
>>  Makefile knob to control this which defaults to being on for
>>  linux. Take a look at the various USE_xxx definitions in the 
>> Makefile
>>  and config.mak.uname for setting default compile flags for different
>>  operating systems.
>> 
>>>  Also another check if a socket is supported by looking for a return
>>>  value of
>>>  "EAI_SOCKTYPE" (not EINVAL) and fallback to regular TCP if that is
>>>  returned.
>>>  EAI_SOCKTYPE should work across different UNIX systems as this is a
>>>  posix error code.
>> 
>>  That error is not mentioned in the documentation for MCTCP on Linux
>>  [1]. Please make sure your code checks for the errno values 
>> described
>>  in the documentation.
> 
> Also according to RFC 6897, "MPTCP is designed to be totally
> backward compatible to applications".  I understand that this is
> quite unlike introducing IPv6 into IPv4-only world.  You can tell
> the system that supports MPTCP to use it in specific ways by
> updating your application, but your system's local policy may
> allow MPTCP to automatically set up multiple subflows even your
> application is not quite aware of MPTCP.
> 
> So, ... I somehow would be mildly surprised if Git were a kind of
> application that needs to take advantage of "several additional
> degrees of freedom that applications may wish to exploit" by using
> API that is "a simple extension of TCP's interface for MPTCP-aware
> applications".  Requiring a simple application like ours to tweak
> and rebuild in today's world does not sound like a winning strategy
> to promote a technology that "is designed to be totally backward
> compatible to applications", at least to me.
> 

Taking into scenario that i have WiFi access and regular Ethernet access on my Laptop and i'm cloning or pulling a large set of code from git (which uses regular ethernet as primary interface and WiFi as secondary.)

On the regular TCP, my connection will reset when disconnecting (plugging off) from Ethernet and switching to WiFi but MPTCP solves that issue for me and allows uninterrupted work on git cloning/pulling, especially when i have to work with huge codebases.

I think that's the relevant use-case for a laptop user working with git.

Apple had been using MPTCP for 12 years and their cloud services run on Linux servers with iOS clients and for that i can say that it's pretty much production ready.

And it's not just Apple. Intel and RedHat had been involved and RedHat[1] pretty much are into MPTCP.

Honestly, i love reading the git codebase as it is very simple and straightforward and i think my previous patches were a bit too big and needs to be simplified so,

I have reached out to Matthieu Baerts <matttbe@kernel.org> who works on Linux MPTCP on this issue and i've greatly simplified the code from his comments. (I've also added him to the loop in this email)

The patch i am attaching is a preview (still WIP) as i need some feedback from the linux mptcp developers if my implementation is correct. But it's greatly simplified to follow git codebase's structure.

Changed the part for the git server daemon to enable mptcp by default[0] and modified the git client to use .gitconfig (global or per repository) with:

git config --global core.mptcp true (or a single repo without --global)

which defaults to false (mptcp disabled for client) as per[0] and removed client-side the env var configuration.

[0] https://www.mptcp.dev/faq.html#why--when-should-mptcp-be-enabled-by-default (Thanks @matt!) [1] https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/getting-started-with-multipath-tcp_configuring-and-managing-networking#proc_monitoring-mptcp-sub-flows_getting-started-with-multipath-tcp

> 
diff --git a/cache.h b/cache.h
index eba12487b9..6839b3acbc 100644
--- a/cache.h
+++ b/cache.h
@@ -944,6 +944,7 @@ extern int verify_ce_order;
 
 /* Environment bits from configuration mechanism */
 extern int trust_executable_bit;
+extern int enable_mptcp;
 extern int trust_ctime;
 extern int check_stat;
 extern int quote_path_fully;
diff --git a/config.c b/config.c
index 2317a76696..833396aa4b 100644
--- a/config.c
+++ b/config.c
@@ -1464,6 +1464,11 @@ static int git_default_core_config(const char *var, const char *value, void *cb)
 	if (!strcmp(var, "core.editor"))
 		return git_config_string(&editor_program, var, value);
 
+	if (!strcmp(var, "core.mptcp")) {
+		enable_mptcp = git_config_bool(var, value);
+		return 0;
+	}
+
 	if (!strcmp(var, "core.commentchar")) {
 		if (!value)
 			return config_error_nonbool(var);
diff --git a/connect.c b/connect.c
index eaf7d6d261..ebeac99bd6 100644
--- a/connect.c
+++ b/connect.c
@@ -721,6 +721,16 @@ static void enable_keepalive(int sockfd)
 		error_errno(_("unable to set SO_KEEPALIVE on socket"));
 }
 
+static const int needs_mptcp(void)
+{
+	int mptcp = 0;
+
+	if (git_config_get_bool("core.mptcp", &mptcp))
+		return mptcp;
+
+	return mptcp;
+}
+
 #ifndef NO_IPV6
 
 static const char *ai_name(const struct addrinfo *ai)
@@ -770,7 +780,11 @@ static int git_tcp_connect_sock(char *host, int flags)
 
 	for (ai0 = ai; ai; ai = ai->ai_next, cnt++) {
 		sockfd = socket(ai->ai_family,
-				ai->ai_socktype, ai->ai_protocol);
+				ai->ai_socktype,
+#ifdef IPPROTO_MPTCP
+				needs_mptcp() ? IPPROTO_MPTCP :
+#endif
+				ai->ai_protocol);
 		if ((sockfd < 0) ||
 		    (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0)) {
 			strbuf_addf(&error_message, "%s[%d: %s]: errno=%s\n",
@@ -817,6 +831,7 @@ static int git_tcp_connect_sock(char *host, int flags)
 	char **ap;
 	unsigned int nport;
 	int cnt;
+	const int needs_mptcp;
 
 	get_host_and_port(&host, &port);
 
diff --git a/daemon.c b/daemon.c
index b1fcbe0d6f..08a16ccf03 100644
--- a/daemon.c
+++ b/daemon.c
@@ -17,6 +17,7 @@ static enum log_destination {
 } log_destination = LOG_DESTINATION_UNSET;
 static int verbose;
 static int reuseaddr;
+static int mptcp;
 static int informative_errors;
 
 static const char daemon_usage[] =
@@ -1007,6 +1008,10 @@ static int setup_named_sock(char *listen_addr, int listen_port, struct socketlis
 	for (ai = ai0; ai; ai = ai->ai_next) {
 		int sockfd;
 
+#if defined(__linux__) && defined(IPPROTO_MPTCP)
+		sockfd = socket(ai->ai_family, ai->ai_socktype, IPPROTO_MPTCP);
+		if (sockfd < 0)
+#endif
 		sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
 		if (sockfd < 0)
 			continue;
@@ -1360,6 +1365,10 @@ int cmd_main(int argc, const char **argv)
 			reuseaddr = 1;
 			continue;
 		}
+		if (!strcmp(arg, "--mptcp")) {
+			mptcp = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--user-path")) {
 			user_path = "";
 			continue;
diff --git a/environment.c b/environment.c
index 9da7f3c1a1..72f1adef6c 100644
--- a/environment.c
+++ b/environment.c
@@ -33,6 +33,7 @@ int warn_ambiguous_refs = 1;
 int warn_on_object_refname_ambiguity = 1;
 int repository_format_precious_objects;
 int repository_format_worktree_config;
+int enable_mptcp;
 const char *git_commit_encoding;
 const char *git_log_output_encoding;
 char *apply_default_whitespace;
Previous: Junio C HamanoNext: Matthieu Baerts
Message 8 of 14 in “Small patch to add support for MPTCP on Linux”
  1. Muhammad NuzaihanMay 16, 2025
  2. brian m. carlsonMay 16, 2025
  3. Muhammad NuzaihanMay 17, 2025
  4. brian m. carlsonMay 17, 2025
  5. Muhammad NuzaihanMay 17, 2025
  6. Phillip WoodMay 17, 2025
  7. Junio C HamanoMay 19, 2025
  8. Muhammad NuzaihanMay 20, 2025
  9. Matthieu BaertsMay 20, 2025
  10. Junio C HamanoMay 20, 2025
  11. Matthieu BaertsMay 20, 2025
  12. Junio C HamanoMay 20, 2025
  13. Matthieu BaertsMay 22, 2025
  14. Muhammad NuzaihanMay 17, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.