Author: mpostaire Description: Add MPTCP support. https://github.com/openssh/openssh-portable/pull/335 diff -Naurp openssh.orig/readconf.c openssh/readconf.c --- openssh.orig/readconf.c +++ openssh/readconf.c @@ -179,7 +179,7 @@ typedef enum { oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize, oEnableEscapeCommandline, oProtocolKeepAlives, oSetupTimeOut, - oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported + oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported, oUseMPTCP } OpCodes; /* Textual representations of the tokens. */ @@ -341,6 +341,7 @@ static struct { { "enableescapecommandline", oEnableEscapeCommandline }, { "protocolkeepalives", oProtocolKeepAlives }, { "setuptimeout", oSetupTimeOut }, + { "usemptcp", oUseMPTCP}, { NULL, oBadOption } }; @@ -2245,6 +2246,10 @@ parse_pubkey_algos: intptr = &options->required_rsa_size; goto parse_int; + case oUseMPTCP: + intptr = &options->use_mptcp; + goto parse_flag; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -2500,6 +2505,7 @@ initialize_options(Options * options) options->known_hosts_command = NULL; options->required_rsa_size = -1; options->enable_escape_commandline = -1; + options->use_mptcp = -1; } /* @@ -2704,6 +2710,8 @@ fill_default_options(Options * options) options->canonicalize_hostname = SSH_CANONICALISE_NO; if (options->fingerprint_hash == -1) options->fingerprint_hash = SSH_FP_HASH_DEFAULT; + if (options->use_mptcp == -1) + options->use_mptcp = 0; #ifdef ENABLE_SK_INTERNAL if (options->sk_provider == NULL) options->sk_provider = xstrdup("internal"); @@ -3405,6 +3413,7 @@ dump_client_config(Options *o, const cha dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); dump_cfg_fmtint(oEnableEscapeCommandline, o->enable_escape_commandline); + dump_cfg_fmtint(oUseMPTCP, o->use_mptcp); /* Integer options */ dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); diff -Naurp openssh.orig/readconf.h openssh/readconf.h --- openssh.orig/readconf.h +++ openssh/readconf.h @@ -187,6 +187,7 @@ typedef struct { int enable_escape_commandline; /* ~C commandline */ char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ + int use_mptcp; /* decides whether to use multipath TCP */ } Options; #define SSH_PUBKEY_AUTH_NO 0x00 diff -Naurp openssh.orig/servconf.c openssh/servconf.c --- openssh.orig/servconf.c +++ openssh/servconf.c @@ -203,6 +203,7 @@ initialize_server_options(ServerOptions options->num_channel_timeouts = 0; options->unused_connection_timeout = -1; options->debian_banner = -1; + options->use_mptcp = -1; } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ @@ -463,6 +464,8 @@ fill_default_server_options(ServerOption options->unused_connection_timeout = 0; if (options->debian_banner == -1) options->debian_banner = 1; + if (options->use_mptcp == -1) + options->use_mptcp = 0; assemble_algorithms(options); @@ -549,7 +552,7 @@ typedef enum { sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout, sDebianBanner, - sDeprecated, sIgnore, sUnsupported + sDeprecated, sIgnore, sUnsupported, sUseMPTCP } ServerOpCodes; #define SSHCFG_GLOBAL 0x01 /* allowed in main section of config */ @@ -723,6 +726,7 @@ static struct { { "channeltimeout", sChannelTimeout, SSHCFG_ALL }, { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL }, { "debianbanner", sDebianBanner, SSHCFG_GLOBAL }, + { "usemptcp", sUseMPTCP, SSHCFG_GLOBAL}, { NULL, sBadOption, 0 } }; @@ -2604,6 +2608,10 @@ process_server_config_line_depth(ServerO intptr = &options->debian_banner; goto parse_flag; + case sUseMPTCP: + intptr = &options->use_mptcp; + goto parse_flag; + case sDeprecated: case sIgnore: case sUnsupported: @@ -3107,6 +3115,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info); + dump_cfg_fmtint(sUseMPTCP, o->use_mptcp); /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); diff -Naurp openssh.orig/servconf.h openssh/servconf.h --- openssh.orig/servconf.h +++ openssh/servconf.h @@ -240,6 +240,7 @@ typedef struct { int unused_connection_timeout; int debian_banner; + int use_mptcp; } ServerOptions; /* Information about the incoming connection as used by Match */ diff -Naurp openssh.orig/ssh_config openssh/ssh_config --- openssh.orig/ssh_config +++ openssh/ssh_config @@ -49,5 +49,6 @@ Host * # ProxyJump gateway.example.com # RekeyLimit 1G 1h # UserKnownHostsFile ~/.ssh/known_hosts.d/%k +# UseMPTCP no SendEnv LANG LC_* HashKnownHosts yes diff -Naurp openssh.orig/sshconnect.c openssh/sshconnect.c --- openssh.orig/sshconnect.c +++ openssh/sshconnect.c @@ -358,7 +358,10 @@ ssh_create_socket(struct addrinfo *ai) #endif char ntop[NI_MAXHOST]; - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (options.use_mptcp) + sock = socket(ai->ai_family, ai->ai_socktype, IPPROTO_MPTCP); + else + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock == -1) { error("socket: %s", strerror(errno)); return -1; diff -Naurp openssh.orig/sshd.c openssh/sshd.c --- openssh.orig/sshd.c +++ openssh/sshd.c @@ -1092,8 +1092,13 @@ listen_on_addrs(struct listenaddr *la) continue; } /* Create socket for listening. */ - listen_sock = socket(ai->ai_family, ai->ai_socktype, - ai->ai_protocol); + if (options.use_mptcp) { + listen_sock = socket(ai->ai_family, ai->ai_socktype, + IPPROTO_MPTCP); + } else { + listen_sock = socket(ai->ai_family, ai->ai_socktype, + ai->ai_protocol); + } if (listen_sock == -1) { /* kernel may not support ipv6 */ verbose("socket: %.100s", strerror(errno)); diff -Naurp openssh.orig/sshd_config openssh/sshd_config --- openssh.orig/sshd_config +++ openssh/sshd_config @@ -105,6 +105,7 @@ PrintMotd no #PermitTunnel no #ChrootDirectory none #VersionAddendum none +#UseMPTCP no # no default banner path #Banner none