Author: mpostaire Description: Add MPTCP support. https://github.com/openssh/openssh-portable/pull/335 diff --git a/readconf.c b/readconf.c index 7f26c680..589c73ac 100644 --- a/readconf.c +++ b/readconf.c @@ -175,7 +175,7 @@ typedef enum { oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms, oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump, oSecurityKeyProvider, oKnownHostsCommand, - oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported + oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported, oUseMPTCP } OpCodes; /* Textual representations of the tokens. */ @@ -320,6 +320,7 @@ static struct { { "proxyjump", oProxyJump }, { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, + { "usemptcp", oUseMPTCP}, { NULL, oBadOption } }; @@ -2176,6 +2177,10 @@ parse_pubkey_algos: *charptr = xstrdup(arg); break; + case oUseMPTCP: + intptr = &options->use_mptcp; + goto parse_flag; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -2423,6 +2428,7 @@ initialize_options(Options * options) options->hostbased_accepted_algos = NULL; options->pubkey_accepted_algos = NULL; options->known_hosts_command = NULL; + options->use_mptcp = -1; } /* @@ -2612,6 +2618,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"); @@ -3300,6 +3308,7 @@ dump_client_config(Options *o, const char *host) dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns); dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); + dump_cfg_fmtint(oUseMPTCP, o->use_mptcp); /* Integer options */ dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); diff --git a/readconf.h b/readconf.h index f647bd42..dfb5b1b4 100644 --- a/readconf.h +++ b/readconf.h @@ -177,6 +177,7 @@ typedef struct { char *known_hosts_command; 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 --git a/servconf.c b/servconf.c index 29df0463..07550d0f 100644 --- a/servconf.c +++ b/servconf.c @@ -195,6 +195,7 @@ initialize_server_options(ServerOptions *options) options->fingerprint_hash = -1; options->disable_forwarding = -1; options->expose_userauth_info = -1; + options->use_mptcp = -1; } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ @@ -441,6 +442,8 @@ fill_default_server_options(ServerOptions *options) options->expose_userauth_info = 0; if (options->sk_provider == NULL) options->sk_provider = xstrdup("internal"); + if (options->use_mptcp == -1) + options->use_mptcp = 0; assemble_algorithms(options); @@ -517,7 +520,7 @@ typedef enum { sStreamLocalBindMask, sStreamLocalBindUnlink, sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, - sDeprecated, sIgnore, sUnsupported + sDeprecated, sIgnore, sUnsupported, sUseMPTCP } ServerOpCodes; #define SSHCFG_GLOBAL 0x01 /* allowed in main section of config */ @@ -676,6 +679,7 @@ static struct { { "rdomain", sRDomain, SSHCFG_ALL }, { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, + { "usemptcp", sUseMPTCP, SSHCFG_GLOBAL}, { NULL, sBadOption, 0 } }; @@ -2438,6 +2442,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, *charptr = xstrdup(arg); break; + case sUseMPTCP: + intptr = &options->use_mptcp; + goto parse_flag; + case sDeprecated: case sIgnore: case sUnsupported: @@ -2920,6 +2928,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 --git a/servconf.h b/servconf.h index 8a04463e..9ab3f89c 100644 --- a/servconf.h +++ b/servconf.h @@ -229,6 +229,7 @@ typedef struct { int expose_userauth_info; u_int64_t timing_secret; char *sk_provider; + int use_mptcp; } ServerOptions; /* Information about the incoming connection as used by Match */ diff --git a/ssh_config b/ssh_config index 842ea866..a6202f1c 100644 --- a/ssh_config +++ b/ssh_config @@ -44,3 +44,4 @@ # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h # UserKnownHostsFile ~/.ssh/known_hosts.d/%k +# UseMPTCP no diff --git a/sshconnect.c b/sshconnect.c index dcd1036d..308bd755 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -359,7 +359,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 --git a/sshd.c b/sshd.c index f494cdbb..3f12299b 100644 --- a/sshd.c +++ b/sshd.c @@ -1046,8 +1046,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 --git a/sshd_config b/sshd_config index c423eba1..5515e2fe 100644 --- a/sshd_config +++ b/sshd_config @@ -101,6 +101,7 @@ AuthorizedKeysFile .ssh/authorized_keys #PermitTunnel no #ChrootDirectory none #VersionAddendum none +#UseMPTCP no # no default banner path #Banner none