Explorar o código

Merge branch 'master' into tls13

Rod Hynes %!s(int64=7) %!d(string=hai) anos
pai
achega
cf7ce3be09
Modificáronse 45 ficheiros con 1861 adicións e 529 borrados
  1. 83 0
      MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest.xcodeproj/project.pbxproj
  2. 3 3
      MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/AppDelegate.swift
  3. 83 0
      MobileLibrary/iOS/SampleApps/TunneledWebView/TunneledWebView.xcodeproj/project.pbxproj
  4. 2 2
      MobileLibrary/iOS/SampleApps/TunneledWebView/TunneledWebView/AppDelegate.swift
  5. 43 0
      psiphon/common/parameters/clientParameters.go
  6. 33 0
      psiphon/common/protocol/protocol.go
  7. 21 1
      psiphon/common/quic/quic.go
  8. 10 0
      psiphon/config.go
  9. 28 1
      psiphon/tunnel.go
  10. 4 0
      vendor/github.com/lucas-clemente/quic-go/Changelog.md
  11. 2 2
      vendor/github.com/lucas-clemente/quic-go/appveyor.yml
  12. 55 43
      vendor/github.com/lucas-clemente/quic-go/client.go
  13. 1 1
      vendor/github.com/lucas-clemente/quic-go/crypto_stream.go
  14. 47 48
      vendor/github.com/lucas-clemente/quic-go/frame_sorter.go
  15. 2 2
      vendor/github.com/lucas-clemente/quic-go/interface.go
  16. 20 4
      vendor/github.com/lucas-clemente/quic-go/internal/protocol/version.go
  17. 5 0
      vendor/github.com/lucas-clemente/quic-go/internal/wire/frame_parser.go
  18. 69 20
      vendor/github.com/lucas-clemente/quic-go/internal/wire/header.go
  19. 58 20
      vendor/github.com/lucas-clemente/quic-go/internal/wire/header_parser.go
  20. 1 1
      vendor/github.com/lucas-clemente/quic-go/packet_handler_map.go
  21. 6 6
      vendor/github.com/lucas-clemente/quic-go/packet_packer.go
  22. 27 21
      vendor/github.com/lucas-clemente/quic-go/receive_stream.go
  23. 45 13
      vendor/github.com/lucas-clemente/quic-go/server.go
  24. 1 1
      vendor/github.com/lucas-clemente/quic-go/server_session.go
  25. 16 12
      vendor/github.com/lucas-clemente/quic-go/session.go
  26. 50 0
      vendor/golang.org/x/net/http/httpguts/guts.go
  27. 346 0
      vendor/golang.org/x/net/http/httpguts/httplex.go
  28. 1 1
      vendor/golang.org/x/net/http2/ciphers.go
  29. 27 1
      vendor/golang.org/x/net/http2/client_conn_pool.go
  30. 6 4
      vendor/golang.org/x/net/http2/configure_transport.go
  31. 5 5
      vendor/golang.org/x/net/http2/flow.go
  32. 51 16
      vendor/golang.org/x/net/http2/frame.go
  33. 26 0
      vendor/golang.org/x/net/http2/go111.go
  34. 15 0
      vendor/golang.org/x/net/http2/go17.go
  35. 15 5
      vendor/golang.org/x/net/http2/headermap.go
  36. 1 1
      vendor/golang.org/x/net/http2/hpack/encode.go
  37. 6 0
      vendor/golang.org/x/net/http2/hpack/hpack.go
  38. 15 5
      vendor/golang.org/x/net/http2/hpack/huffman.go
  39. 9 16
      vendor/golang.org/x/net/http2/http2.go
  40. 17 0
      vendor/golang.org/x/net/http2/not_go111.go
  41. 8 0
      vendor/golang.org/x/net/http2/not_go17.go
  42. 102 69
      vendor/golang.org/x/net/http2/server.go
  43. 458 166
      vendor/golang.org/x/net/http2/transport.go
  44. 3 8
      vendor/golang.org/x/net/http2/write.go
  45. 35 31
      vendor/vendor.json

+ 83 - 0
MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest.xcodeproj/project.pbxproj

@@ -16,6 +16,7 @@
 		6626590E1DCB8CF400872F6C /* TunneledWebRequestUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6626590D1DCB8CF400872F6C /* TunneledWebRequestUITests.swift */; };
 		6626590E1DCB8CF400872F6C /* TunneledWebRequestUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6626590D1DCB8CF400872F6C /* TunneledWebRequestUITests.swift */; };
 		6682D90E1EB1334000329958 /* psiphon-embedded-server-entries.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6682D90D1EB1334000329958 /* psiphon-embedded-server-entries.txt */; };
 		6682D90E1EB1334000329958 /* psiphon-embedded-server-entries.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6682D90D1EB1334000329958 /* psiphon-embedded-server-entries.txt */; };
 		6688DBB61DCD684B00721A9E /* psiphon-config.json in Resources */ = {isa = PBXBuildFile; fileRef = 6688DBB51DCD684B00721A9E /* psiphon-config.json */; };
 		6688DBB61DCD684B00721A9E /* psiphon-config.json in Resources */ = {isa = PBXBuildFile; fileRef = 6688DBB51DCD684B00721A9E /* psiphon-config.json */; };
+		DEB1E38A2E15C48277D2E61E /* libPods-TunneledWebRequest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 37F726750F0082A9B17447DC /* libPods-TunneledWebRequest.a */; };
 /* End PBXBuildFile section */
 /* End PBXBuildFile section */
 
 
 /* Begin PBXContainerItemProxy section */
 /* Begin PBXContainerItemProxy section */
@@ -48,6 +49,7 @@
 /* End PBXCopyFilesBuildPhase section */
 /* End PBXCopyFilesBuildPhase section */
 
 
 /* Begin PBXFileReference section */
 /* Begin PBXFileReference section */
+		37F726750F0082A9B17447DC /* libPods-TunneledWebRequest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-TunneledWebRequest.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		662658EA1DCB8CF300872F6C /* TunneledWebRequest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TunneledWebRequest.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		662658EA1DCB8CF300872F6C /* TunneledWebRequest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TunneledWebRequest.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		662658ED1DCB8CF300872F6C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
 		662658ED1DCB8CF300872F6C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
 		662658EF1DCB8CF300872F6C /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
 		662658EF1DCB8CF300872F6C /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
@@ -63,6 +65,8 @@
 		6626590F1DCB8CF400872F6C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		6626590F1DCB8CF400872F6C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		6682D90D1EB1334000329958 /* psiphon-embedded-server-entries.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "psiphon-embedded-server-entries.txt"; sourceTree = "<group>"; };
 		6682D90D1EB1334000329958 /* psiphon-embedded-server-entries.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "psiphon-embedded-server-entries.txt"; sourceTree = "<group>"; };
 		6688DBB51DCD684B00721A9E /* psiphon-config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "psiphon-config.json"; sourceTree = "<group>"; };
 		6688DBB51DCD684B00721A9E /* psiphon-config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "psiphon-config.json"; sourceTree = "<group>"; };
+		6BA09789075034B337A791DA /* Pods-TunneledWebRequest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TunneledWebRequest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TunneledWebRequest/Pods-TunneledWebRequest.debug.xcconfig"; sourceTree = "<group>"; };
+		FC00C7E45B17A3FDBDC1BF85 /* Pods-TunneledWebRequest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TunneledWebRequest.release.xcconfig"; path = "Pods/Target Support Files/Pods-TunneledWebRequest/Pods-TunneledWebRequest.release.xcconfig"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 /* End PBXFileReference section */
 
 
 /* Begin PBXFrameworksBuildPhase section */
 /* Begin PBXFrameworksBuildPhase section */
@@ -70,6 +74,7 @@
 			isa = PBXFrameworksBuildPhase;
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
+				DEB1E38A2E15C48277D2E61E /* libPods-TunneledWebRequest.a in Frameworks */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
@@ -90,6 +95,15 @@
 /* End PBXFrameworksBuildPhase section */
 /* End PBXFrameworksBuildPhase section */
 
 
 /* Begin PBXGroup section */
 /* Begin PBXGroup section */
+		0045CE62DA042FBB9EEC82C6 /* Pods */ = {
+			isa = PBXGroup;
+			children = (
+				6BA09789075034B337A791DA /* Pods-TunneledWebRequest.debug.xcconfig */,
+				FC00C7E45B17A3FDBDC1BF85 /* Pods-TunneledWebRequest.release.xcconfig */,
+			);
+			name = Pods;
+			sourceTree = "<group>";
+		};
 		662658E11DCB8CF300872F6C = {
 		662658E11DCB8CF300872F6C = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -97,6 +111,8 @@
 				662659011DCB8CF400872F6C /* TunneledWebRequestTests */,
 				662659011DCB8CF400872F6C /* TunneledWebRequestTests */,
 				6626590C1DCB8CF400872F6C /* TunneledWebRequestUITests */,
 				6626590C1DCB8CF400872F6C /* TunneledWebRequestUITests */,
 				662658EB1DCB8CF300872F6C /* Products */,
 				662658EB1DCB8CF300872F6C /* Products */,
+				0045CE62DA042FBB9EEC82C6 /* Pods */,
+				B9517667525E004ABCEB784D /* Frameworks */,
 			);
 			);
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
@@ -143,6 +159,14 @@
 			path = TunneledWebRequestUITests;
 			path = TunneledWebRequestUITests;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		B9517667525E004ABCEB784D /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				37F726750F0082A9B17447DC /* libPods-TunneledWebRequest.a */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 /* End PBXGroup section */
 
 
 /* Begin PBXNativeTarget section */
 /* Begin PBXNativeTarget section */
@@ -150,10 +174,13 @@
 			isa = PBXNativeTarget;
 			isa = PBXNativeTarget;
 			buildConfigurationList = 662659121DCB8CF400872F6C /* Build configuration list for PBXNativeTarget "TunneledWebRequest" */;
 			buildConfigurationList = 662659121DCB8CF400872F6C /* Build configuration list for PBXNativeTarget "TunneledWebRequest" */;
 			buildPhases = (
 			buildPhases = (
+				5555F15E8B8D35FD6F809B0B /* [CP] Check Pods Manifest.lock */,
 				662658E61DCB8CF300872F6C /* Sources */,
 				662658E61DCB8CF300872F6C /* Sources */,
 				662658E71DCB8CF300872F6C /* Frameworks */,
 				662658E71DCB8CF300872F6C /* Frameworks */,
 				662658E81DCB8CF300872F6C /* Resources */,
 				662658E81DCB8CF300872F6C /* Resources */,
 				662659221DCBC8CB00872F6C /* CopyFiles */,
 				662659221DCBC8CB00872F6C /* CopyFiles */,
+				161BCAA9D00D77704E622F78 /* [CP] Embed Pods Frameworks */,
+				A679CFEFFDF17884E46F6A14 /* [CP] Copy Pods Resources */,
 			);
 			);
 			buildRules = (
 			buildRules = (
 			);
 			);
@@ -278,6 +305,60 @@
 		};
 		};
 /* End PBXResourcesBuildPhase section */
 /* End PBXResourcesBuildPhase section */
 
 
+/* Begin PBXShellScriptBuildPhase section */
+		161BCAA9D00D77704E622F78 /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${SRCROOT}/Pods/Target Support Files/Pods-TunneledWebRequest/Pods-TunneledWebRequest-frameworks.sh",
+				"${PODS_ROOT}/PsiphonTunnel/Frameworks/PsiphonTunnel.framework",
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputPaths = (
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PsiphonTunnel.framework",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-TunneledWebRequest/Pods-TunneledWebRequest-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+		5555F15E8B8D35FD6F809B0B /* [CP] Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-TunneledWebRequest-checkManifestLockResult.txt",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+			showEnvVarsInLog = 0;
+		};
+		A679CFEFFDF17884E46F6A14 /* [CP] Copy Pods Resources */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "[CP] Copy Pods Resources";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-TunneledWebRequest/Pods-TunneledWebRequest-resources.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+/* End PBXShellScriptBuildPhase section */
+
 /* Begin PBXSourcesBuildPhase section */
 /* Begin PBXSourcesBuildPhase section */
 		662658E61DCB8CF300872F6C /* Sources */ = {
 		662658E61DCB8CF300872F6C /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			isa = PBXSourcesBuildPhase;
@@ -450,6 +531,7 @@
 		};
 		};
 		662659131DCB8CF400872F6C /* Debug */ = {
 		662659131DCB8CF400872F6C /* Debug */ = {
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
+			baseConfigurationReference = 6BA09789075034B337A791DA /* Pods-TunneledWebRequest.debug.xcconfig */;
 			buildSettings = {
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				DEVELOPMENT_TEAM = Q6HLNEX92A;
 				DEVELOPMENT_TEAM = Q6HLNEX92A;
@@ -469,6 +551,7 @@
 		};
 		};
 		662659141DCB8CF400872F6C /* Release */ = {
 		662659141DCB8CF400872F6C /* Release */ = {
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
+			baseConfigurationReference = FC00C7E45B17A3FDBDC1BF85 /* Pods-TunneledWebRequest.release.xcconfig */;
 			buildSettings = {
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				DEVELOPMENT_TEAM = Q6HLNEX92A;
 				DEVELOPMENT_TEAM = Q6HLNEX92A;

+ 3 - 3
MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/AppDelegate.swift

@@ -239,9 +239,9 @@ extension AppDelegate: TunneledAppDelegate {
         }
         }
     }
     }
 
 
-	func onDiagnosticMessage(_ message: String) {
-		NSLog("onDiagnosticMessage: %@", message)
-	}
+    func onDiagnosticMessage(_ message: String, withTimestamp timestamp: String) {
+        NSLog("onDiagnosticMessage(%@): %@", timestamp, message)
+    }
 
 
 	func onConnected() {
 	func onConnected() {
 		NSLog("onConnected")
 		NSLog("onConnected")

+ 83 - 0
MobileLibrary/iOS/SampleApps/TunneledWebView/TunneledWebView.xcodeproj/project.pbxproj

@@ -21,6 +21,7 @@
 		6626590E1DCB8CF400872F6C /* TunneledWebViewUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6626590D1DCB8CF400872F6C /* TunneledWebViewUITests.swift */; };
 		6626590E1DCB8CF400872F6C /* TunneledWebViewUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6626590D1DCB8CF400872F6C /* TunneledWebViewUITests.swift */; };
 		6682D90E1EB1334000329958 /* psiphon-embedded-server-entries.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6682D90D1EB1334000329958 /* psiphon-embedded-server-entries.txt */; };
 		6682D90E1EB1334000329958 /* psiphon-embedded-server-entries.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6682D90D1EB1334000329958 /* psiphon-embedded-server-entries.txt */; };
 		6688DBB61DCD684B00721A9E /* psiphon-config.json in Resources */ = {isa = PBXBuildFile; fileRef = 6688DBB51DCD684B00721A9E /* psiphon-config.json */; };
 		6688DBB61DCD684B00721A9E /* psiphon-config.json in Resources */ = {isa = PBXBuildFile; fileRef = 6688DBB51DCD684B00721A9E /* psiphon-config.json */; };
+		DDFD23795085E5852A8F4DD5 /* libPods-TunneledWebView.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E472F80E34E361EB72B2FD0C /* libPods-TunneledWebView.a */; };
 /* End PBXBuildFile section */
 /* End PBXBuildFile section */
 
 
 /* Begin PBXContainerItemProxy section */
 /* Begin PBXContainerItemProxy section */
@@ -78,6 +79,9 @@
 		6626590F1DCB8CF400872F6C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		6626590F1DCB8CF400872F6C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		6682D90D1EB1334000329958 /* psiphon-embedded-server-entries.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "psiphon-embedded-server-entries.txt"; sourceTree = "<group>"; };
 		6682D90D1EB1334000329958 /* psiphon-embedded-server-entries.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "psiphon-embedded-server-entries.txt"; sourceTree = "<group>"; };
 		6688DBB51DCD684B00721A9E /* psiphon-config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "psiphon-config.json"; sourceTree = "<group>"; };
 		6688DBB51DCD684B00721A9E /* psiphon-config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "psiphon-config.json"; sourceTree = "<group>"; };
+		76C8CF5D2CF9F4228B9CD56E /* Pods-TunneledWebView.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TunneledWebView.release.xcconfig"; path = "Pods/Target Support Files/Pods-TunneledWebView/Pods-TunneledWebView.release.xcconfig"; sourceTree = "<group>"; };
+		85795C6590EED64B7A6684AA /* Pods-TunneledWebView.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TunneledWebView.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TunneledWebView/Pods-TunneledWebView.debug.xcconfig"; sourceTree = "<group>"; };
+		E472F80E34E361EB72B2FD0C /* libPods-TunneledWebView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-TunneledWebView.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 /* End PBXFileReference section */
 /* End PBXFileReference section */
 
 
 /* Begin PBXFrameworksBuildPhase section */
 /* Begin PBXFrameworksBuildPhase section */
@@ -85,6 +89,7 @@
 			isa = PBXFrameworksBuildPhase;
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
+				DDFD23795085E5852A8F4DD5 /* libPods-TunneledWebView.a in Frameworks */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
@@ -128,6 +133,8 @@
 				662659011DCB8CF400872F6C /* TunneledWebViewTests */,
 				662659011DCB8CF400872F6C /* TunneledWebViewTests */,
 				6626590C1DCB8CF400872F6C /* TunneledWebViewUITests */,
 				6626590C1DCB8CF400872F6C /* TunneledWebViewUITests */,
 				662658EB1DCB8CF300872F6C /* Products */,
 				662658EB1DCB8CF300872F6C /* Products */,
+				A5804F65F614B094CCA05E13 /* Pods */,
+				8B6FB31735B11066EC18E1CB /* Frameworks */,
 			);
 			);
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
@@ -177,6 +184,23 @@
 			path = TunneledWebViewUITests;
 			path = TunneledWebViewUITests;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		8B6FB31735B11066EC18E1CB /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				E472F80E34E361EB72B2FD0C /* libPods-TunneledWebView.a */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		A5804F65F614B094CCA05E13 /* Pods */ = {
+			isa = PBXGroup;
+			children = (
+				85795C6590EED64B7A6684AA /* Pods-TunneledWebView.debug.xcconfig */,
+				76C8CF5D2CF9F4228B9CD56E /* Pods-TunneledWebView.release.xcconfig */,
+			);
+			name = Pods;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 /* End PBXGroup section */
 
 
 /* Begin PBXNativeTarget section */
 /* Begin PBXNativeTarget section */
@@ -184,10 +208,13 @@
 			isa = PBXNativeTarget;
 			isa = PBXNativeTarget;
 			buildConfigurationList = 662659121DCB8CF400872F6C /* Build configuration list for PBXNativeTarget "TunneledWebView" */;
 			buildConfigurationList = 662659121DCB8CF400872F6C /* Build configuration list for PBXNativeTarget "TunneledWebView" */;
 			buildPhases = (
 			buildPhases = (
+				5D5B0B0744787E007145BB7C /* [CP] Check Pods Manifest.lock */,
 				662658E61DCB8CF300872F6C /* Sources */,
 				662658E61DCB8CF300872F6C /* Sources */,
 				662658E71DCB8CF300872F6C /* Frameworks */,
 				662658E71DCB8CF300872F6C /* Frameworks */,
 				662658E81DCB8CF300872F6C /* Resources */,
 				662658E81DCB8CF300872F6C /* Resources */,
 				662659221DCBC8CB00872F6C /* CopyFiles */,
 				662659221DCBC8CB00872F6C /* CopyFiles */,
+				055465DE48CF8066AB340776 /* [CP] Embed Pods Frameworks */,
+				8A8D8BC5E8DAB19D43A5010A /* [CP] Copy Pods Resources */,
 			);
 			);
 			buildRules = (
 			buildRules = (
 			);
 			);
@@ -313,6 +340,60 @@
 		};
 		};
 /* End PBXResourcesBuildPhase section */
 /* End PBXResourcesBuildPhase section */
 
 
+/* Begin PBXShellScriptBuildPhase section */
+		055465DE48CF8066AB340776 /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${SRCROOT}/Pods/Target Support Files/Pods-TunneledWebView/Pods-TunneledWebView-frameworks.sh",
+				"${PODS_ROOT}/PsiphonTunnel/Frameworks/PsiphonTunnel.framework",
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputPaths = (
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PsiphonTunnel.framework",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-TunneledWebView/Pods-TunneledWebView-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+		5D5B0B0744787E007145BB7C /* [CP] Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-TunneledWebView-checkManifestLockResult.txt",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+			showEnvVarsInLog = 0;
+		};
+		8A8D8BC5E8DAB19D43A5010A /* [CP] Copy Pods Resources */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "[CP] Copy Pods Resources";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-TunneledWebView/Pods-TunneledWebView-resources.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+/* End PBXShellScriptBuildPhase section */
+
 /* Begin PBXSourcesBuildPhase section */
 /* Begin PBXSourcesBuildPhase section */
 		662658E61DCB8CF300872F6C /* Sources */ = {
 		662658E61DCB8CF300872F6C /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			isa = PBXSourcesBuildPhase;
@@ -489,6 +570,7 @@
 		};
 		};
 		662659131DCB8CF400872F6C /* Debug */ = {
 		662659131DCB8CF400872F6C /* Debug */ = {
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
+			baseConfigurationReference = 85795C6590EED64B7A6684AA /* Pods-TunneledWebView.debug.xcconfig */;
 			buildSettings = {
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				DEFINES_MODULE = YES;
 				DEFINES_MODULE = YES;
@@ -510,6 +592,7 @@
 		};
 		};
 		662659141DCB8CF400872F6C /* Release */ = {
 		662659141DCB8CF400872F6C /* Release */ = {
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
+			baseConfigurationReference = 76C8CF5D2CF9F4228B9CD56E /* Pods-TunneledWebView.release.xcconfig */;
 			buildSettings = {
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				DEFINES_MODULE = YES;
 				DEFINES_MODULE = YES;

+ 2 - 2
MobileLibrary/iOS/SampleApps/TunneledWebView/TunneledWebView/AppDelegate.swift

@@ -149,8 +149,8 @@ extension AppDelegate: TunneledAppDelegate {
         }
         }
     }
     }
 
 
-    func onDiagnosticMessage(_ message: String) {
-        NSLog("onDiagnosticMessage: %@", message)
+    func onDiagnosticMessage(_ message: String, withTimestamp timestamp: String) {
+        NSLog("onDiagnosticMessage(%@): %@", timestamp, message)
     }
     }
 
 
     func onConnected() {
     func onConnected() {

+ 43 - 0
psiphon/common/parameters/clientParameters.go

@@ -92,6 +92,8 @@ const (
 	LimitTunnelProtocols                       = "LimitTunnelProtocols"
 	LimitTunnelProtocols                       = "LimitTunnelProtocols"
 	LimitTLSProfilesProbability                = "LimitTLSProfilesProbability"
 	LimitTLSProfilesProbability                = "LimitTLSProfilesProbability"
 	LimitTLSProfiles                           = "LimitTLSProfiles"
 	LimitTLSProfiles                           = "LimitTLSProfiles"
+	LimitQUICVersionsProbability               = "LimitQUICVersionsProbability"
+	LimitQUICVersions                          = "LimitQUICVersions"
 	FragmentorProbability                      = "FragmentorProbability"
 	FragmentorProbability                      = "FragmentorProbability"
 	FragmentorLimitProtocols                   = "FragmentorLimitProtocols"
 	FragmentorLimitProtocols                   = "FragmentorLimitProtocols"
 	FragmentorMinTotalBytes                    = "FragmentorMinTotalBytes"
 	FragmentorMinTotalBytes                    = "FragmentorMinTotalBytes"
@@ -228,6 +230,9 @@ var defaultClientParameters = map[string]struct {
 	LimitTLSProfilesProbability: {value: 1.0, minimum: 0.0},
 	LimitTLSProfilesProbability: {value: 1.0, minimum: 0.0},
 	LimitTLSProfiles:            {value: protocol.TLSProfiles{}},
 	LimitTLSProfiles:            {value: protocol.TLSProfiles{}},
 
 
+	LimitQUICVersionsProbability: {value: 1.0, minimum: 0.0},
+	LimitQUICVersions:            {value: []string{protocol.QUIC_VERSION_GQUIC43}},
+
 	FragmentorProbability:    {value: 0.5, minimum: 0.0},
 	FragmentorProbability:    {value: 0.5, minimum: 0.0},
 	FragmentorLimitProtocols: {value: protocol.TunnelProtocols{}},
 	FragmentorLimitProtocols: {value: protocol.TunnelProtocols{}},
 	FragmentorMinTotalBytes:  {value: 0, minimum: 0},
 	FragmentorMinTotalBytes:  {value: 0, minimum: 0},
@@ -505,6 +510,15 @@ func (p *ClientParameters) Set(
 						return nil, common.ContextError(err)
 						return nil, common.ContextError(err)
 					}
 					}
 				}
 				}
+			case protocol.QUICVersions:
+				if skipOnError {
+					newValue = v.PruneInvalid()
+				} else {
+					err := v.Validate()
+					if err != nil {
+						return nil, common.ContextError(err)
+					}
+				}
 			}
 			}
 
 
 			// Enforce any minimums. Assumes defaultClientParameters[name]
 			// Enforce any minimums. Assumes defaultClientParameters[name]
@@ -740,6 +754,35 @@ func (p *ClientParametersSnapshot) TLSProfiles(name string) protocol.TLSProfiles
 	return value
 	return value
 }
 }
 
 
+// QUICVersions returns a protocol.QUICVersions parameter value.
+// If there is a corresponding Probability value, a weighted coin flip
+// will be performed and, depending on the result, the value or the
+// parameter default will be returned.
+func (p *ClientParametersSnapshot) QUICVersions(name string) protocol.QUICVersions {
+
+	probabilityName := name + "Probability"
+	_, ok := p.parameters[probabilityName]
+	if ok {
+		probabilityValue := float64(1.0)
+		p.getValue(probabilityName, &probabilityValue)
+		if !common.FlipWeightedCoin(probabilityValue) {
+			defaultParameter, ok := defaultClientParameters[name]
+			if ok {
+				defaultValue, ok := defaultParameter.value.(protocol.QUICVersions)
+				if ok {
+					value := make(protocol.QUICVersions, len(defaultValue))
+					copy(value, defaultValue)
+					return value
+				}
+			}
+		}
+	}
+
+	value := protocol.QUICVersions{}
+	p.getValue(name, &value)
+	return value
+}
+
 // DownloadURLs returns a DownloadURLs parameter value.
 // DownloadURLs returns a DownloadURLs parameter value.
 func (p *ClientParametersSnapshot) DownloadURLs(name string) DownloadURLs {
 func (p *ClientParametersSnapshot) DownloadURLs(name string) DownloadURLs {
 	value := DownloadURLs{}
 	value := DownloadURLs{}

+ 33 - 0
psiphon/common/protocol/protocol.go

@@ -229,6 +229,39 @@ func (profiles TLSProfiles) PruneInvalid() TLSProfiles {
 	return q
 	return q
 }
 }
 
 
+const (
+	QUIC_VERSION_GQUIC39 = "gQUICv39"
+	QUIC_VERSION_GQUIC43 = "gQUICv43"
+	QUIC_VERSION_GQUIC44 = "gQUICv44"
+)
+
+var SupportedQUICVersions = QUICVersions{
+	QUIC_VERSION_GQUIC39,
+	QUIC_VERSION_GQUIC43,
+	QUIC_VERSION_GQUIC44,
+}
+
+type QUICVersions []string
+
+func (versions QUICVersions) Validate() error {
+	for _, v := range versions {
+		if !common.Contains(SupportedQUICVersions, v) {
+			return common.ContextError(fmt.Errorf("invalid QUIC version: %s", v))
+		}
+	}
+	return nil
+}
+
+func (versions QUICVersions) PruneInvalid() QUICVersions {
+	u := make(QUICVersions, 0)
+	for _, v := range versions {
+		if common.Contains(SupportedQUICVersions, v) {
+			u = append(u, v)
+		}
+	}
+	return u
+}
+
 type HandshakeResponse struct {
 type HandshakeResponse struct {
 	SSHSessionID           string              `json:"ssh_session_id"`
 	SSHSessionID           string              `json:"ssh_session_id"`
 	Homepages              []string            `json:"homepages"`
 	Homepages              []string            `json:"homepages"`

+ 21 - 1
psiphon/common/quic/quic.go

@@ -43,6 +43,7 @@ package quic
 import (
 import (
 	"context"
 	"context"
 	"crypto/tls"
 	"crypto/tls"
+	"fmt"
 	"io"
 	"io"
 	"net"
 	"net"
 	"sync"
 	"sync"
@@ -50,6 +51,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common"
 	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common"
+	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/protocol"
 	quic_go "github.com/lucas-clemente/quic-go"
 	quic_go "github.com/lucas-clemente/quic-go"
 	"github.com/lucas-clemente/quic-go/qerr"
 	"github.com/lucas-clemente/quic-go/qerr"
 )
 )
@@ -120,6 +122,12 @@ func (listener *Listener) Accept() (net.Conn, error) {
 	}, nil
 	}, nil
 }
 }
 
 
+var supportedVersionNumbers = map[string]quic_go.VersionNumber{
+	protocol.QUIC_VERSION_GQUIC39: quic_go.VersionGQUIC39,
+	protocol.QUIC_VERSION_GQUIC43: quic_go.VersionGQUIC43,
+	protocol.QUIC_VERSION_GQUIC44: quic_go.VersionGQUIC44,
+}
+
 // Dial establishes a new QUIC session and stream to the server specified by
 // Dial establishes a new QUIC session and stream to the server specified by
 // address.
 // address.
 //
 //
@@ -133,12 +141,24 @@ func Dial(
 	ctx context.Context,
 	ctx context.Context,
 	packetConn net.PacketConn,
 	packetConn net.PacketConn,
 	remoteAddr *net.UDPAddr,
 	remoteAddr *net.UDPAddr,
-	quicSNIAddress string) (net.Conn, error) {
+	quicSNIAddress string,
+	negotiateQUICVersion string) (net.Conn, error) {
+
+	var versions []quic_go.VersionNumber
+
+	if negotiateQUICVersion != "" {
+		versionNumber, ok := supportedVersionNumbers[negotiateQUICVersion]
+		if !ok {
+			return nil, common.ContextError(fmt.Errorf("unsupported version: %s", negotiateQUICVersion))
+		}
+		versions = []quic_go.VersionNumber{versionNumber}
+	}
 
 
 	quicConfig := &quic_go.Config{
 	quicConfig := &quic_go.Config{
 		HandshakeTimeout: time.Duration(1<<63 - 1),
 		HandshakeTimeout: time.Duration(1<<63 - 1),
 		IdleTimeout:      CLIENT_IDLE_TIMEOUT,
 		IdleTimeout:      CLIENT_IDLE_TIMEOUT,
 		KeepAlive:        true,
 		KeepAlive:        true,
+		Versions:         versions,
 	}
 	}
 
 
 	deadline, ok := ctx.Deadline()
 	deadline, ok := ctx.Deadline()

+ 10 - 0
psiphon/config.go

@@ -160,6 +160,12 @@ type Config struct {
 	// selection.
 	// selection.
 	LimitTLSProfiles []string
 	LimitTLSProfiles []string
 
 
+	// LimitQUICVersions indicates which QUIC versions to select from. Valid
+	// values are listed in protocols.SupportedQUICVersions.
+	// For the default, an empty list, all versions are candidates for
+	// selection.
+	LimitQUICVersions []string
+
 	// EstablishTunnelTimeoutSeconds specifies a time limit after which to
 	// EstablishTunnelTimeoutSeconds specifies a time limit after which to
 	// halt the core tunnel controller if no tunnel has been established. The
 	// halt the core tunnel controller if no tunnel has been established. The
 	// default is parameters.EstablishTunnelTimeoutSeconds.
 	// default is parameters.EstablishTunnelTimeoutSeconds.
@@ -829,6 +835,10 @@ func (config *Config) makeConfigParameters() map[string]interface{} {
 		applyParameters[parameters.LimitTLSProfiles] = protocol.TunnelProtocols(config.LimitTLSProfiles)
 		applyParameters[parameters.LimitTLSProfiles] = protocol.TunnelProtocols(config.LimitTLSProfiles)
 	}
 	}
 
 
+	if len(config.LimitQUICVersions) > 0 {
+		applyParameters[parameters.LimitQUICVersions] = protocol.QUICVersions(config.LimitQUICVersions)
+	}
+
 	if config.EstablishTunnelTimeoutSeconds != nil {
 	if config.EstablishTunnelTimeoutSeconds != nil {
 		applyParameters[parameters.EstablishTunnelTimeout] = fmt.Sprintf("%ds", *config.EstablishTunnelTimeoutSeconds)
 		applyParameters[parameters.EstablishTunnelTimeout] = fmt.Sprintf("%ds", *config.EstablishTunnelTimeoutSeconds)
 	}
 	}

+ 28 - 1
psiphon/tunnel.go

@@ -902,7 +902,8 @@ func dialSsh(
 			ctx,
 			ctx,
 			packetConn,
 			packetConn,
 			remoteAddr,
 			remoteAddr,
-			quicDialSNIAddress)
+			quicDialSNIAddress,
+			selectQUICVersion(config.clientParameters))
 		if err != nil {
 		if err != nil {
 			return nil, common.ContextError(err)
 			return nil, common.ContextError(err)
 		}
 		}
@@ -1117,6 +1118,32 @@ func dialSsh(
 		nil
 		nil
 }
 }
 
 
+func selectQUICVersion(
+	clientParameters *parameters.ClientParameters) string {
+
+	limitQUICVersions := clientParameters.Get().QUICVersions(parameters.LimitQUICVersions)
+
+	quicVersions := make([]string, 0)
+
+	for _, quicVersion := range protocol.SupportedQUICVersions {
+
+		if len(limitQUICVersions) > 0 &&
+			!common.Contains(limitQUICVersions, quicVersion) {
+			continue
+		}
+
+		quicVersions = append(quicVersions, quicVersion)
+	}
+
+	if len(quicVersions) == 0 {
+		return ""
+	}
+
+	choice, _ := common.MakeSecureRandomInt(len(quicVersions))
+
+	return quicVersions[choice]
+}
+
 func makeRandomPeriod(min, max time.Duration) time.Duration {
 func makeRandomPeriod(min, max time.Duration) time.Duration {
 	period, err := common.MakeSecureRandomPeriod(min, max)
 	period, err := common.MakeSecureRandomPeriod(min, max)
 	if err != nil {
 	if err != nil {

+ 4 - 0
vendor/github.com/lucas-clemente/quic-go/Changelog.md

@@ -1,5 +1,9 @@
 # Changelog
 # Changelog
 
 
+## v0.10.0 (2018-08-28)
+
+- Add support for QUIC 44, drop support for QUIC 42.
+
 ## v0.9.0 (2018-08-15)
 ## v0.9.0 (2018-08-15)
 
 
 - Add a `quic.Config` option for the length of the connection ID (for IETF QUIC).
 - Add a `quic.Config` option for the length of the connection ID (for IETF QUIC).

+ 2 - 2
vendor/github.com/lucas-clemente/quic-go/appveyor.yml

@@ -14,8 +14,8 @@ clone_folder: c:\gopath\src\github.com\lucas-clemente\quic-go
 
 
 install:
 install:
   - rmdir c:\go /s /q
   - rmdir c:\go /s /q
-  - appveyor DownloadFile https://storage.googleapis.com/golang/go1.11rc1.windows-amd64.zip
-  - 7z x go1.11rc1.windows-amd64.zip -y -oC:\ > NUL
+  - appveyor DownloadFile https://storage.googleapis.com/golang/go1.11.windows-amd64.zip
+  - 7z x go1.11.windows-amd64.zip -y -oC:\ > NUL
   - set PATH=%PATH%;%GOPATH%\bin\windows_%GOARCH%;%GOPATH%\bin
   - set PATH=%PATH%;%GOPATH%\bin\windows_%GOARCH%;%GOPATH%\bin
   - echo %PATH%
   - echo %PATH%
   - echo %GOPATH%
   - echo %GOPATH%

+ 55 - 43
vendor/github.com/lucas-clemente/quic-go/client.go

@@ -127,7 +127,22 @@ func dialContext(
 	config *Config,
 	config *Config,
 	createdPacketConn bool,
 	createdPacketConn bool,
 ) (Session, error) {
 ) (Session, error) {
-	config = populateClientConfig(config, createdPacketConn)
+
+	// [Psiphon]
+	// We call DialContext as we need to create a custom net.PacketConn.
+	// There is one custom net.PacketConn per QUIC connection, which
+	// satisfies the gQUIC 44 constraint.
+	config = populateClientConfig(config, true)
+	/*
+		config = populateClientConfig(config, createdPacketConn)
+		if !createdPacketConn {
+			for _, v := range config.Versions {
+				if v == protocol.Version44 {
+					return nil, errors.New("Cannot multiplex connections using gQUIC 44, see https://groups.google.com/a/chromium.org/forum/#!topic/proto-quic/pE9NlLLjizE. Please disable gQUIC 44 in the quic.Config, or use DialAddr")
+				}
+			}
+		}
+	*/
 	packetHandlers, err := getMultiplexer().AddConn(pconn, config.ConnectionIDLength)
 	packetHandlers, err := getMultiplexer().AddConn(pconn, config.ConnectionIDLength)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -234,6 +249,11 @@ func populateClientConfig(config *Config, createdPacketConn bool) *Config {
 	if connIDLen == 0 && !createdPacketConn {
 	if connIDLen == 0 && !createdPacketConn {
 		connIDLen = protocol.DefaultConnectionIDLength
 		connIDLen = protocol.DefaultConnectionIDLength
 	}
 	}
+	for _, v := range versions {
+		if v == protocol.Version44 {
+			connIDLen = 0
+		}
+	}
 
 
 	return &Config{
 	return &Config{
 		Versions:                              versions,
 		Versions:                              versions,
@@ -267,6 +287,9 @@ func (c *client) generateConnectionIDs() error {
 	}
 	}
 	c.srcConnID = srcConnID
 	c.srcConnID = srcConnID
 	c.destConnID = destConnID
 	c.destConnID = destConnID
+	if c.version == protocol.Version44 {
+		c.srcConnID = nil
+	}
 	return nil
 	return nil
 }
 }
 
 
@@ -372,23 +395,32 @@ func (c *client) handlePacketImpl(p *receivedPacket) error {
 		return err
 		return err
 	}
 	}
 
 
-	if p.header.IsPublicHeader {
-		return c.handleGQUICPacket(p)
+	if !c.version.UsesIETFHeaderFormat() {
+		connID := p.header.DestConnectionID
+		// reject packets with truncated connection id if we didn't request truncation
+		if !c.config.RequestConnectionIDOmission && connID.Len() == 0 {
+			return errors.New("received packet with truncated connection ID, but didn't request truncation")
+		}
+		// reject packets with the wrong connection ID
+		if connID.Len() > 0 && !connID.Equal(c.srcConnID) {
+			return fmt.Errorf("received a packet with an unexpected connection ID (%s, expected %s)", connID, c.srcConnID)
+		}
+		if p.header.ResetFlag {
+			return c.handlePublicReset(p)
+		}
+	} else {
+		// reject packets with the wrong connection ID
+		if !p.header.DestConnectionID.Equal(c.srcConnID) {
+			return fmt.Errorf("received a packet with an unexpected connection ID (%s, expected %s)", p.header.DestConnectionID, c.srcConnID)
+		}
 	}
 	}
-	return c.handleIETFQUICPacket(p)
-}
 
 
-func (c *client) handleIETFQUICPacket(p *receivedPacket) error {
-	// reject packets with the wrong connection ID
-	if !p.header.DestConnectionID.Equal(c.srcConnID) {
-		return fmt.Errorf("received a packet with an unexpected connection ID (%s, expected %s)", p.header.DestConnectionID, c.srcConnID)
-	}
 	if p.header.IsLongHeader {
 	if p.header.IsLongHeader {
 		switch p.header.Type {
 		switch p.header.Type {
 		case protocol.PacketTypeRetry:
 		case protocol.PacketTypeRetry:
 			c.handleRetryPacket(p.header)
 			c.handleRetryPacket(p.header)
 			return nil
 			return nil
-		case protocol.PacketTypeHandshake:
+		case protocol.PacketTypeHandshake, protocol.PacketType0RTT:
 		default:
 		default:
 			return fmt.Errorf("Received unsupported packet type: %s", p.header.Type)
 			return fmt.Errorf("Received unsupported packet type: %s", p.header.Type)
 		}
 		}
@@ -404,40 +436,19 @@ func (c *client) handleIETFQUICPacket(p *receivedPacket) error {
 	return nil
 	return nil
 }
 }
 
 
-func (c *client) handleGQUICPacket(p *receivedPacket) error {
-	connID := p.header.DestConnectionID
-	// reject packets with truncated connection id if we didn't request truncation
-	if !c.config.RequestConnectionIDOmission && connID.Len() == 0 {
-		return errors.New("received packet with truncated connection ID, but didn't request truncation")
-	}
-	// reject packets with the wrong connection ID
-	if connID.Len() > 0 && !connID.Equal(c.srcConnID) {
-		return fmt.Errorf("received a packet with an unexpected connection ID (%s, expected %s)", connID, c.srcConnID)
+func (c *client) handlePublicReset(p *receivedPacket) error {
+	cr := c.conn.RemoteAddr()
+	// check if the remote address and the connection ID match
+	// otherwise this might be an attacker trying to inject a PUBLIC_RESET to kill the connection
+	if cr.Network() != p.remoteAddr.Network() || cr.String() != p.remoteAddr.String() || !p.header.DestConnectionID.Equal(c.srcConnID) {
+		return errors.New("Received a spoofed Public Reset")
 	}
 	}
-
-	if p.header.ResetFlag {
-		cr := c.conn.RemoteAddr()
-		// check if the remote address and the connection ID match
-		// otherwise this might be an attacker trying to inject a PUBLIC_RESET to kill the connection
-		if cr.Network() != p.remoteAddr.Network() || cr.String() != p.remoteAddr.String() || !connID.Equal(c.srcConnID) {
-			return errors.New("Received a spoofed Public Reset")
-		}
-		pr, err := wire.ParsePublicReset(bytes.NewReader(p.data))
-		if err != nil {
-			return fmt.Errorf("Received a Public Reset. An error occurred parsing the packet: %s", err)
-		}
-		c.session.closeRemote(qerr.Error(qerr.PublicReset, fmt.Sprintf("Received a Public Reset for packet number %#x", pr.RejectedPacketNumber)))
-		c.logger.Infof("Received Public Reset, rejected packet number: %#x", pr.RejectedPacketNumber)
-		return nil
-	}
-
-	// this is the first packet we are receiving
-	// since it is not a Version Negotiation Packet, this means the server supports the suggested version
-	if !c.versionNegotiated {
-		c.versionNegotiated = true
+	pr, err := wire.ParsePublicReset(bytes.NewReader(p.data))
+	if err != nil {
+		return fmt.Errorf("Received a Public Reset. An error occurred parsing the packet: %s", err)
 	}
 	}
-
-	c.session.handlePacket(p)
+	c.session.closeRemote(qerr.Error(qerr.PublicReset, fmt.Sprintf("Received a Public Reset for packet number %#x", pr.RejectedPacketNumber)))
+	c.logger.Infof("Received Public Reset, rejected packet number: %#x", pr.RejectedPacketNumber)
 	return nil
 	return nil
 }
 }
 
 
@@ -513,6 +524,7 @@ func (c *client) createNewGQUICSession() error {
 		c.hostname,
 		c.hostname,
 		c.version,
 		c.version,
 		c.destConnID,
 		c.destConnID,
+		c.srcConnID,
 		c.tlsConf,
 		c.tlsConf,
 		c.config,
 		c.config,
 		c.initialVersion,
 		c.initialVersion,

+ 1 - 1
vendor/github.com/lucas-clemente/quic-go/crypto_stream.go

@@ -37,5 +37,5 @@ func newCryptoStream(sender streamSender, flowController flowcontrol.StreamFlowC
 // It must not be called concurrently with any other stream methods, especially Read and Write.
 // It must not be called concurrently with any other stream methods, especially Read and Write.
 func (s *cryptoStreamImpl) setReadOffset(offset protocol.ByteCount) {
 func (s *cryptoStreamImpl) setReadOffset(offset protocol.ByteCount) {
 	s.receiveStream.readOffset = offset
 	s.receiveStream.readOffset = offset
-	s.receiveStream.frameQueue.readPosition = offset
+	s.receiveStream.frameQueue.readPos = offset
 }
 }

+ 47 - 48
vendor/github.com/lucas-clemente/quic-go/stream_frame_sorter.go → vendor/github.com/lucas-clemente/quic-go/frame_sorter.go

@@ -5,49 +5,55 @@ import (
 
 
 	"github.com/lucas-clemente/quic-go/internal/protocol"
 	"github.com/lucas-clemente/quic-go/internal/protocol"
 	"github.com/lucas-clemente/quic-go/internal/utils"
 	"github.com/lucas-clemente/quic-go/internal/utils"
-	"github.com/lucas-clemente/quic-go/internal/wire"
 )
 )
 
 
-type streamFrameSorter struct {
-	queuedFrames map[protocol.ByteCount]*wire.StreamFrame
-	readPosition protocol.ByteCount
-	gaps         *utils.ByteIntervalList
+type frameSorter struct {
+	queue       map[protocol.ByteCount][]byte
+	readPos     protocol.ByteCount
+	finalOffset protocol.ByteCount
+	gaps        *utils.ByteIntervalList
 }
 }
 
 
-var (
-	errTooManyGapsInReceivedStreamData = errors.New("Too many gaps in received StreamFrame data")
-	errDuplicateStreamData             = errors.New("Duplicate Stream Data")
-)
+var errDuplicateStreamData = errors.New("Duplicate Stream Data")
 
 
-func newStreamFrameSorter() *streamFrameSorter {
-	s := streamFrameSorter{
-		gaps:         utils.NewByteIntervalList(),
-		queuedFrames: make(map[protocol.ByteCount]*wire.StreamFrame),
+func newFrameSorter() *frameSorter {
+	s := frameSorter{
+		gaps:        utils.NewByteIntervalList(),
+		queue:       make(map[protocol.ByteCount][]byte),
+		finalOffset: protocol.MaxByteCount,
 	}
 	}
 	s.gaps.PushFront(utils.ByteInterval{Start: 0, End: protocol.MaxByteCount})
 	s.gaps.PushFront(utils.ByteInterval{Start: 0, End: protocol.MaxByteCount})
 	return &s
 	return &s
 }
 }
 
 
-func (s *streamFrameSorter) Push(frame *wire.StreamFrame) error {
-	if frame.DataLen() == 0 {
-		if frame.FinBit {
-			s.queuedFrames[frame.Offset] = frame
-		}
+func (s *frameSorter) Push(data []byte, offset protocol.ByteCount, fin bool) error {
+	err := s.push(data, offset, fin)
+	if err == errDuplicateStreamData {
+		return nil
+	}
+	return err
+}
+
+func (s *frameSorter) push(data []byte, offset protocol.ByteCount, fin bool) error {
+	if fin {
+		s.finalOffset = offset + protocol.ByteCount(len(data))
+	}
+	if len(data) == 0 {
 		return nil
 		return nil
 	}
 	}
 
 
 	var wasCut bool
 	var wasCut bool
-	if oldFrame, ok := s.queuedFrames[frame.Offset]; ok {
-		if frame.DataLen() <= oldFrame.DataLen() {
+	if oldData, ok := s.queue[offset]; ok {
+		if len(data) <= len(oldData) {
 			return errDuplicateStreamData
 			return errDuplicateStreamData
 		}
 		}
-		frame.Data = frame.Data[oldFrame.DataLen():]
-		frame.Offset += oldFrame.DataLen()
+		data = data[len(oldData):]
+		offset += protocol.ByteCount(len(oldData))
 		wasCut = true
 		wasCut = true
 	}
 	}
 
 
-	start := frame.Offset
-	end := frame.Offset + frame.DataLen()
+	start := offset
+	end := offset + protocol.ByteCount(len(data))
 
 
 	// skip all gaps that are before this stream frame
 	// skip all gaps that are before this stream frame
 	var gap *utils.ByteIntervalElement
 	var gap *utils.ByteIntervalElement
@@ -67,9 +73,9 @@ func (s *streamFrameSorter) Push(frame *wire.StreamFrame) error {
 
 
 	if start < gap.Value.Start {
 	if start < gap.Value.Start {
 		add := gap.Value.Start - start
 		add := gap.Value.Start - start
-		frame.Offset += add
+		offset += add
 		start += add
 		start += add
-		frame.Data = frame.Data[add:]
+		data = data[add:]
 		wasCut = true
 		wasCut = true
 	}
 	}
 
 
@@ -87,15 +93,15 @@ func (s *streamFrameSorter) Push(frame *wire.StreamFrame) error {
 			break
 			break
 		}
 		}
 		// delete queued frames completely covered by the current frame
 		// delete queued frames completely covered by the current frame
-		delete(s.queuedFrames, endGap.Value.End)
+		delete(s.queue, endGap.Value.End)
 		endGap = nextEndGap
 		endGap = nextEndGap
 	}
 	}
 
 
 	if end > endGap.Value.End {
 	if end > endGap.Value.End {
 		cutLen := end - endGap.Value.End
 		cutLen := end - endGap.Value.End
-		len := frame.DataLen() - cutLen
+		len := protocol.ByteCount(len(data)) - cutLen
 		end -= cutLen
 		end -= cutLen
-		frame.Data = frame.Data[:len]
+		data = data[:len]
 		wasCut = true
 		wasCut = true
 	}
 	}
 
 
@@ -128,32 +134,25 @@ func (s *streamFrameSorter) Push(frame *wire.StreamFrame) error {
 	}
 	}
 
 
 	if s.gaps.Len() > protocol.MaxStreamFrameSorterGaps {
 	if s.gaps.Len() > protocol.MaxStreamFrameSorterGaps {
-		return errTooManyGapsInReceivedStreamData
+		return errors.New("Too many gaps in received data")
 	}
 	}
 
 
 	if wasCut {
 	if wasCut {
-		data := make([]byte, frame.DataLen())
-		copy(data, frame.Data)
-		frame.Data = data
+		newData := make([]byte, len(data))
+		copy(newData, data)
+		data = newData
 	}
 	}
 
 
-	s.queuedFrames[frame.Offset] = frame
+	s.queue[offset] = data
 	return nil
 	return nil
 }
 }
 
 
-func (s *streamFrameSorter) Pop() *wire.StreamFrame {
-	frame := s.Head()
-	if frame != nil {
-		s.readPosition += frame.DataLen()
-		delete(s.queuedFrames, frame.Offset)
+func (s *frameSorter) Pop() ([]byte /* data */, bool /* fin */) {
+	data, ok := s.queue[s.readPos]
+	if !ok {
+		return nil, s.readPos >= s.finalOffset
 	}
 	}
-	return frame
-}
-
-func (s *streamFrameSorter) Head() *wire.StreamFrame {
-	frame, ok := s.queuedFrames[s.readPosition]
-	if ok {
-		return frame
-	}
-	return nil
+	delete(s.queue, s.readPos)
+	s.readPos += protocol.ByteCount(len(data))
+	return data, s.readPos >= s.finalOffset
 }
 }

+ 2 - 2
vendor/github.com/lucas-clemente/quic-go/interface.go

@@ -19,10 +19,10 @@ type VersionNumber = protocol.VersionNumber
 const (
 const (
 	// VersionGQUIC39 is gQUIC version 39.
 	// VersionGQUIC39 is gQUIC version 39.
 	VersionGQUIC39 = protocol.Version39
 	VersionGQUIC39 = protocol.Version39
-	// VersionGQUIC42 is gQUIC version 42.
-	VersionGQUIC42 = protocol.Version42
 	// VersionGQUIC43 is gQUIC version 43.
 	// VersionGQUIC43 is gQUIC version 43.
 	VersionGQUIC43 = protocol.Version43
 	VersionGQUIC43 = protocol.Version43
+	// VersionGQUIC44 is gQUIC version 44.
+	VersionGQUIC44 = protocol.Version44
 )
 )
 
 
 // A Cookie can be used to verify the ownership of the client address.
 // A Cookie can be used to verify the ownership of the client address.

+ 20 - 4
vendor/github.com/lucas-clemente/quic-go/internal/protocol/version.go

@@ -19,8 +19,8 @@ const (
 // The version numbers, making grepping easier
 // The version numbers, making grepping easier
 const (
 const (
 	Version39       VersionNumber = gquicVersion0 + 3*0x100 + 0x9
 	Version39       VersionNumber = gquicVersion0 + 3*0x100 + 0x9
-	Version42       VersionNumber = gquicVersion0 + 4*0x100 + 0x2
 	Version43       VersionNumber = gquicVersion0 + 4*0x100 + 0x3
 	Version43       VersionNumber = gquicVersion0 + 4*0x100 + 0x3
+	Version44       VersionNumber = gquicVersion0 + 4*0x100 + 0x4
 	VersionTLS      VersionNumber = 101
 	VersionTLS      VersionNumber = 101
 	VersionWhatever VersionNumber = 0 // for when the version doesn't matter
 	VersionWhatever VersionNumber = 0 // for when the version doesn't matter
 	VersionUnknown  VersionNumber = math.MaxUint32
 	VersionUnknown  VersionNumber = math.MaxUint32
@@ -29,8 +29,8 @@ const (
 // SupportedVersions lists the versions that the server supports
 // SupportedVersions lists the versions that the server supports
 // must be in sorted descending order
 // must be in sorted descending order
 var SupportedVersions = []VersionNumber{
 var SupportedVersions = []VersionNumber{
+	Version44,
 	Version43,
 	Version43,
-	Version42,
 	Version39,
 	Version39,
 }
 }
 
 
@@ -41,7 +41,7 @@ func IsValidVersion(v VersionNumber) bool {
 
 
 // UsesTLS says if this QUIC version uses TLS 1.3 for the handshake
 // UsesTLS says if this QUIC version uses TLS 1.3 for the handshake
 func (vn VersionNumber) UsesTLS() bool {
 func (vn VersionNumber) UsesTLS() bool {
-	return vn == VersionTLS
+	return !vn.isGQUIC()
 }
 }
 
 
 func (vn VersionNumber) String() string {
 func (vn VersionNumber) String() string {
@@ -81,11 +81,27 @@ func (vn VersionNumber) UsesIETFFrameFormat() bool {
 	return !vn.isGQUIC()
 	return !vn.isGQUIC()
 }
 }
 
 
+// UsesIETFHeaderFormat tells if this version uses the IETF header format
+func (vn VersionNumber) UsesIETFHeaderFormat() bool {
+	return !vn.isGQUIC() || vn >= Version44
+}
+
+// UsesLengthInHeader tells if this version uses the Length field in the IETF header
+func (vn VersionNumber) UsesLengthInHeader() bool {
+	return !vn.isGQUIC()
+}
+
+// UsesTokenInHeader tells if this version uses the Token field in the IETF header
+func (vn VersionNumber) UsesTokenInHeader() bool {
+	return !vn.isGQUIC()
+}
+
 // UsesStopWaitingFrames tells if this version uses STOP_WAITING frames
 // UsesStopWaitingFrames tells if this version uses STOP_WAITING frames
 func (vn VersionNumber) UsesStopWaitingFrames() bool {
 func (vn VersionNumber) UsesStopWaitingFrames() bool {
-	return vn.isGQUIC()
+	return vn.isGQUIC() && vn <= Version43
 }
 }
 
 
+// UsesVarintPacketNumbers tells if this version uses 7/14/30 bit packet numbers
 func (vn VersionNumber) UsesVarintPacketNumbers() bool {
 func (vn VersionNumber) UsesVarintPacketNumbers() bool {
 	return !vn.isGQUIC()
 	return !vn.isGQUIC()
 }
 }

+ 5 - 0
vendor/github.com/lucas-clemente/quic-go/internal/wire/frame_parser.go

@@ -2,6 +2,7 @@ package wire
 
 
 import (
 import (
 	"bytes"
 	"bytes"
+	"errors"
 	"fmt"
 	"fmt"
 
 
 	"github.com/lucas-clemente/quic-go/internal/protocol"
 	"github.com/lucas-clemente/quic-go/internal/protocol"
@@ -154,6 +155,10 @@ func parseGQUICFrame(r *bytes.Reader, typeByte byte, hdr *Header, v protocol.Ver
 			err = qerr.Error(qerr.InvalidBlockedData, err.Error())
 			err = qerr.Error(qerr.InvalidBlockedData, err.Error())
 		}
 		}
 	case 0x6:
 	case 0x6:
+		if !v.UsesStopWaitingFrames() {
+			err = errors.New("STOP_WAITING frames not supported by this QUIC version")
+			break
+		}
 		frame, err = parseStopWaitingFrame(r, hdr.PacketNumber, hdr.PacketNumberLen, v)
 		frame, err = parseStopWaitingFrame(r, hdr.PacketNumber, hdr.PacketNumberLen, v)
 		if err != nil {
 		if err != nil {
 			err = qerr.Error(qerr.InvalidStopWaitingData, err.Error())
 			err = qerr.Error(qerr.InvalidStopWaitingData, err.Error())

+ 69 - 20
vendor/github.com/lucas-clemente/quic-go/internal/wire/header.go

@@ -42,23 +42,23 @@ type Header struct {
 	Token        []byte
 	Token        []byte
 }
 }
 
 
-var errInvalidPacketNumberLen6 = errors.New("invalid packet number length: 6 bytes")
+var errInvalidPacketNumberLen = errors.New("invalid packet number length")
 
 
 // Write writes the Header.
 // Write writes the Header.
-func (h *Header) Write(b *bytes.Buffer, pers protocol.Perspective, version protocol.VersionNumber) error {
-	if !version.UsesTLS() {
+func (h *Header) Write(b *bytes.Buffer, pers protocol.Perspective, ver protocol.VersionNumber) error {
+	if !ver.UsesIETFHeaderFormat() {
 		h.IsPublicHeader = true // save that this is a Public Header, so we can log it correctly later
 		h.IsPublicHeader = true // save that this is a Public Header, so we can log it correctly later
-		return h.writePublicHeader(b, pers, version)
+		return h.writePublicHeader(b, pers, ver)
 	}
 	}
 	// write an IETF QUIC header
 	// write an IETF QUIC header
 	if h.IsLongHeader {
 	if h.IsLongHeader {
-		return h.writeLongHeader(b)
+		return h.writeLongHeader(b, ver)
 	}
 	}
-	return h.writeShortHeader(b)
+	return h.writeShortHeader(b, ver)
 }
 }
 
 
 // TODO: add support for the key phase
 // TODO: add support for the key phase
-func (h *Header) writeLongHeader(b *bytes.Buffer) error {
+func (h *Header) writeLongHeader(b *bytes.Buffer, v protocol.VersionNumber) error {
 	b.WriteByte(byte(0x80 | h.Type))
 	b.WriteByte(byte(0x80 | h.Type))
 	utils.BigEndian.WriteUint32(b, uint32(h.Version))
 	utils.BigEndian.WriteUint32(b, uint32(h.Version))
 	connIDLen, err := encodeConnIDLen(h.DestConnectionID, h.SrcConnectionID)
 	connIDLen, err := encodeConnIDLen(h.DestConnectionID, h.SrcConnectionID)
@@ -69,7 +69,7 @@ func (h *Header) writeLongHeader(b *bytes.Buffer) error {
 	b.Write(h.DestConnectionID.Bytes())
 	b.Write(h.DestConnectionID.Bytes())
 	b.Write(h.SrcConnectionID.Bytes())
 	b.Write(h.SrcConnectionID.Bytes())
 
 
-	if h.Type == protocol.PacketTypeInitial {
+	if h.Type == protocol.PacketTypeInitial && v.UsesTokenInHeader() {
 		utils.WriteVarInt(b, uint64(len(h.Token)))
 		utils.WriteVarInt(b, uint64(len(h.Token)))
 		b.Write(h.Token)
 		b.Write(h.Token)
 	}
 	}
@@ -89,16 +89,51 @@ func (h *Header) writeLongHeader(b *bytes.Buffer) error {
 		return nil
 		return nil
 	}
 	}
 
 
-	utils.WriteVarInt(b, uint64(h.PayloadLen))
-	return utils.WriteVarIntPacketNumber(b, h.PacketNumber, h.PacketNumberLen)
+	if v.UsesLengthInHeader() {
+		utils.WriteVarInt(b, uint64(h.PayloadLen))
+	}
+	if v.UsesVarintPacketNumbers() {
+		return utils.WriteVarIntPacketNumber(b, h.PacketNumber, h.PacketNumberLen)
+	}
+	utils.BigEndian.WriteUint32(b, uint32(h.PacketNumber))
+	if h.Type == protocol.PacketType0RTT && v == protocol.Version44 {
+		if len(h.DiversificationNonce) != 32 {
+			return errors.New("invalid diversification nonce length")
+		}
+		b.Write(h.DiversificationNonce)
+	}
+	return nil
 }
 }
 
 
-func (h *Header) writeShortHeader(b *bytes.Buffer) error {
+func (h *Header) writeShortHeader(b *bytes.Buffer, v protocol.VersionNumber) error {
 	typeByte := byte(0x30)
 	typeByte := byte(0x30)
 	typeByte |= byte(h.KeyPhase << 6)
 	typeByte |= byte(h.KeyPhase << 6)
-	b.WriteByte(typeByte)
+	if !v.UsesVarintPacketNumbers() {
+		switch h.PacketNumberLen {
+		case protocol.PacketNumberLen1:
+		case protocol.PacketNumberLen2:
+			typeByte |= 0x1
+		case protocol.PacketNumberLen4:
+			typeByte |= 0x2
+		default:
+			return errInvalidPacketNumberLen
+		}
+	}
 
 
+	b.WriteByte(typeByte)
 	b.Write(h.DestConnectionID.Bytes())
 	b.Write(h.DestConnectionID.Bytes())
+
+	if !v.UsesVarintPacketNumbers() {
+		switch h.PacketNumberLen {
+		case protocol.PacketNumberLen1:
+			b.WriteByte(uint8(h.PacketNumber))
+		case protocol.PacketNumberLen2:
+			utils.BigEndian.WriteUint16(b, uint16(h.PacketNumber))
+		case protocol.PacketNumberLen4:
+			utils.BigEndian.WriteUint32(b, uint32(h.PacketNumber))
+		}
+		return nil
+	}
 	return utils.WriteVarIntPacketNumber(b, h.PacketNumber, h.PacketNumberLen)
 	return utils.WriteVarIntPacketNumber(b, h.PacketNumber, h.PacketNumberLen)
 }
 }
 
 
@@ -155,7 +190,7 @@ func (h *Header) writePublicHeader(b *bytes.Buffer, pers protocol.Perspective, _
 	case protocol.PacketNumberLen4:
 	case protocol.PacketNumberLen4:
 		utils.BigEndian.WriteUint32(b, uint32(h.PacketNumber))
 		utils.BigEndian.WriteUint32(b, uint32(h.PacketNumber))
 	case protocol.PacketNumberLen6:
 	case protocol.PacketNumberLen6:
-		return errInvalidPacketNumberLen6
+		return errInvalidPacketNumberLen
 	default:
 	default:
 		return errors.New("PublicHeader: PacketNumberLen not set")
 		return errors.New("PublicHeader: PacketNumberLen not set")
 	}
 	}
@@ -164,19 +199,25 @@ func (h *Header) writePublicHeader(b *bytes.Buffer, pers protocol.Perspective, _
 }
 }
 
 
 // GetLength determines the length of the Header.
 // GetLength determines the length of the Header.
-func (h *Header) GetLength(version protocol.VersionNumber) (protocol.ByteCount, error) {
-	if !version.UsesTLS() {
+func (h *Header) GetLength(v protocol.VersionNumber) (protocol.ByteCount, error) {
+	if !v.UsesIETFHeaderFormat() {
 		return h.getPublicHeaderLength()
 		return h.getPublicHeaderLength()
 	}
 	}
-	return h.getHeaderLength()
+	return h.getHeaderLength(v)
 }
 }
 
 
-func (h *Header) getHeaderLength() (protocol.ByteCount, error) {
+func (h *Header) getHeaderLength(v protocol.VersionNumber) (protocol.ByteCount, error) {
 	if h.IsLongHeader {
 	if h.IsLongHeader {
-		length := 1 /* type byte */ + 4 /* version */ + 1 /* conn id len byte */ + protocol.ByteCount(h.DestConnectionID.Len()+h.SrcConnectionID.Len()) + utils.VarIntLen(uint64(h.PayloadLen)) + protocol.ByteCount(h.PacketNumberLen)
-		if h.Type == protocol.PacketTypeInitial {
+		length := 1 /* type byte */ + 4 /* version */ + 1 /* conn id len byte */ + protocol.ByteCount(h.DestConnectionID.Len()+h.SrcConnectionID.Len()) + protocol.ByteCount(h.PacketNumberLen)
+		if v.UsesLengthInHeader() {
+			length += utils.VarIntLen(uint64(h.PayloadLen))
+		}
+		if h.Type == protocol.PacketTypeInitial && v.UsesTokenInHeader() {
 			length += utils.VarIntLen(uint64(len(h.Token))) + protocol.ByteCount(len(h.Token))
 			length += utils.VarIntLen(uint64(len(h.Token))) + protocol.ByteCount(len(h.Token))
 		}
 		}
+		if h.Type == protocol.PacketType0RTT && v == protocol.Version44 {
+			length += protocol.ByteCount(len(h.DiversificationNonce))
+		}
 		return length, nil
 		return length, nil
 	}
 	}
 
 
@@ -193,7 +234,7 @@ func (h *Header) getHeaderLength() (protocol.ByteCount, error) {
 func (h *Header) getPublicHeaderLength() (protocol.ByteCount, error) {
 func (h *Header) getPublicHeaderLength() (protocol.ByteCount, error) {
 	length := protocol.ByteCount(1) // 1 byte for public flags
 	length := protocol.ByteCount(1) // 1 byte for public flags
 	if h.PacketNumberLen == protocol.PacketNumberLen6 {
 	if h.PacketNumberLen == protocol.PacketNumberLen6 {
-		return 0, errInvalidPacketNumberLen6
+		return 0, errInvalidPacketNumberLen
 	}
 	}
 	if h.PacketNumberLen != protocol.PacketNumberLen1 && h.PacketNumberLen != protocol.PacketNumberLen2 && h.PacketNumberLen != protocol.PacketNumberLen4 {
 	if h.PacketNumberLen != protocol.PacketNumberLen1 && h.PacketNumberLen != protocol.PacketNumberLen2 && h.PacketNumberLen != protocol.PacketNumberLen4 {
 		return 0, errPacketNumberLenNotSet
 		return 0, errPacketNumberLenNotSet
@@ -234,6 +275,14 @@ func (h *Header) logHeader(logger utils.Logger) {
 				logger.Debugf("\tLong Header{Type: %s, DestConnectionID: %s, SrcConnectionID: %s, %sOrigDestConnectionID: %s, Version: %s}", h.Type, h.DestConnectionID, h.SrcConnectionID, token, h.OrigDestConnectionID, h.Version)
 				logger.Debugf("\tLong Header{Type: %s, DestConnectionID: %s, SrcConnectionID: %s, %sOrigDestConnectionID: %s, Version: %s}", h.Type, h.DestConnectionID, h.SrcConnectionID, token, h.OrigDestConnectionID, h.Version)
 				return
 				return
 			}
 			}
+			if h.Version == protocol.Version44 {
+				var divNonce string
+				if h.Type == protocol.PacketType0RTT {
+					divNonce = fmt.Sprintf("Diversification Nonce: %#x, ", h.DiversificationNonce)
+				}
+				logger.Debugf("\tLong Header{Type: %s, DestConnectionID: %s, SrcConnectionID: %s, PacketNumber: %#x, PacketNumberLen: %d, %sVersion: %s}", h.Type, h.DestConnectionID, h.SrcConnectionID, h.PacketNumber, h.PacketNumberLen, divNonce, h.Version)
+				return
+			}
 			logger.Debugf("\tLong Header{Type: %s, DestConnectionID: %s, SrcConnectionID: %s, %sPacketNumber: %#x, PacketNumberLen: %d, PayloadLen: %d, Version: %s}", h.Type, h.DestConnectionID, h.SrcConnectionID, token, h.PacketNumber, h.PacketNumberLen, h.PayloadLen, h.Version)
 			logger.Debugf("\tLong Header{Type: %s, DestConnectionID: %s, SrcConnectionID: %s, %sPacketNumber: %#x, PacketNumberLen: %d, PayloadLen: %d, Version: %s}", h.Type, h.DestConnectionID, h.SrcConnectionID, token, h.PacketNumber, h.PacketNumberLen, h.PayloadLen, h.Version)
 		}
 		}
 	} else {
 	} else {

+ 58 - 20
vendor/github.com/lucas-clemente/quic-go/internal/wire/header_parser.go

@@ -79,7 +79,7 @@ func (iv *InvariantHeader) Parse(b *bytes.Reader, sentBy protocol.Perspective, v
 		if iv.Version == 0 { // Version Negotiation Packet
 		if iv.Version == 0 { // Version Negotiation Packet
 			return iv.parseVersionNegotiationPacket(b)
 			return iv.parseVersionNegotiationPacket(b)
 		}
 		}
-		return iv.parseLongHeader(b)
+		return iv.parseLongHeader(b, sentBy, ver)
 	}
 	}
 	// The Public Header never uses 6 byte packet numbers.
 	// The Public Header never uses 6 byte packet numbers.
 	// Therefore, the third and fourth bit will never be 11.
 	// Therefore, the third and fourth bit will never be 11.
@@ -90,8 +90,7 @@ func (iv *InvariantHeader) Parse(b *bytes.Reader, sentBy protocol.Perspective, v
 		}
 		}
 		return iv.parsePublicHeader(b, sentBy, ver)
 		return iv.parsePublicHeader(b, sentBy, ver)
 	}
 	}
-	return iv.parseShortHeader(b)
-
+	return iv.parseShortHeader(b, ver)
 }
 }
 
 
 func (iv *InvariantHeader) toHeader() *Header {
 func (iv *InvariantHeader) toHeader() *Header {
@@ -121,7 +120,7 @@ func (iv *InvariantHeader) parseVersionNegotiationPacket(b *bytes.Reader) (*Head
 	return h, nil
 	return h, nil
 }
 }
 
 
-func (iv *InvariantHeader) parseLongHeader(b *bytes.Reader) (*Header, error) {
+func (iv *InvariantHeader) parseLongHeader(b *bytes.Reader, sentBy protocol.Perspective, v protocol.VersionNumber) (*Header, error) {
 	h := iv.toHeader()
 	h := iv.toHeader()
 	h.Type = protocol.PacketType(iv.typeByte & 0x7f)
 	h.Type = protocol.PacketType(iv.typeByte & 0x7f)
 
 
@@ -146,7 +145,7 @@ func (iv *InvariantHeader) parseLongHeader(b *bytes.Reader) (*Header, error) {
 		return h, nil
 		return h, nil
 	}
 	}
 
 
-	if h.Type == protocol.PacketTypeInitial {
+	if h.Type == protocol.PacketTypeInitial && v.UsesTokenInHeader() {
 		tokenLen, err := utils.ReadVarInt(b)
 		tokenLen, err := utils.ReadVarInt(b)
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
@@ -160,30 +159,69 @@ func (iv *InvariantHeader) parseLongHeader(b *bytes.Reader) (*Header, error) {
 		}
 		}
 	}
 	}
 
 
-	pl, err := utils.ReadVarInt(b)
-	if err != nil {
-		return nil, err
+	if v.UsesLengthInHeader() {
+		pl, err := utils.ReadVarInt(b)
+		if err != nil {
+			return nil, err
+		}
+		h.PayloadLen = protocol.ByteCount(pl)
 	}
 	}
-	h.PayloadLen = protocol.ByteCount(pl)
-	pn, pnLen, err := utils.ReadVarIntPacketNumber(b)
-	if err != nil {
-		return nil, err
+	if v.UsesVarintPacketNumbers() {
+		pn, pnLen, err := utils.ReadVarIntPacketNumber(b)
+		if err != nil {
+			return nil, err
+		}
+		h.PacketNumber = pn
+		h.PacketNumberLen = pnLen
+	} else {
+		pn, err := utils.BigEndian.ReadUint32(b)
+		if err != nil {
+			return nil, err
+		}
+		h.PacketNumber = protocol.PacketNumber(pn)
+		h.PacketNumberLen = protocol.PacketNumberLen4
+	}
+	if h.Type == protocol.PacketType0RTT && v == protocol.Version44 && sentBy == protocol.PerspectiveServer {
+		h.DiversificationNonce = make([]byte, 32)
+		if _, err := io.ReadFull(b, h.DiversificationNonce); err != nil {
+			if err == io.ErrUnexpectedEOF {
+				return nil, io.EOF
+			}
+			return nil, err
+		}
 	}
 	}
-	h.PacketNumber = pn
-	h.PacketNumberLen = pnLen
 
 
 	return h, nil
 	return h, nil
 }
 }
 
 
-func (iv *InvariantHeader) parseShortHeader(b *bytes.Reader) (*Header, error) {
+func (iv *InvariantHeader) parseShortHeader(b *bytes.Reader, v protocol.VersionNumber) (*Header, error) {
 	h := iv.toHeader()
 	h := iv.toHeader()
 	h.KeyPhase = int(iv.typeByte&0x40) >> 6
 	h.KeyPhase = int(iv.typeByte&0x40) >> 6
-	pn, pnLen, err := utils.ReadVarIntPacketNumber(b)
-	if err != nil {
-		return nil, err
+
+	if v.UsesVarintPacketNumbers() {
+		pn, pnLen, err := utils.ReadVarIntPacketNumber(b)
+		if err != nil {
+			return nil, err
+		}
+		h.PacketNumber = pn
+		h.PacketNumberLen = pnLen
+	} else {
+		switch iv.typeByte & 0x3 {
+		case 0x0:
+			h.PacketNumberLen = protocol.PacketNumberLen1
+		case 0x1:
+			h.PacketNumberLen = protocol.PacketNumberLen2
+		case 0x2:
+			h.PacketNumberLen = protocol.PacketNumberLen4
+		default:
+			return nil, errInvalidPacketNumberLen
+		}
+		p, err := utils.BigEndian.ReadUintN(b, uint8(h.PacketNumberLen))
+		if err != nil {
+			return nil, err
+		}
+		h.PacketNumber = protocol.PacketNumber(p)
 	}
 	}
-	h.PacketNumber = pn
-	h.PacketNumberLen = pnLen
 	return h, nil
 	return h, nil
 }
 }
 
 

+ 1 - 1
vendor/github.com/lucas-clemente/quic-go/packet_handler_map.go

@@ -180,7 +180,7 @@ func (h *packetHandlerMap) handlePacket(addr net.Addr, data []byte) error {
 	hdr.Raw = data[:len(data)-r.Len()]
 	hdr.Raw = data[:len(data)-r.Len()]
 	packetData := data[len(data)-r.Len():]
 	packetData := data[len(data)-r.Len():]
 
 
-	if hdr.IsLongHeader {
+	if hdr.IsLongHeader && hdr.Version.UsesLengthInHeader() {
 		if protocol.ByteCount(len(packetData)) < hdr.PayloadLen {
 		if protocol.ByteCount(len(packetData)) < hdr.PayloadLen {
 			return fmt.Errorf("packet payload (%d bytes) is smaller than the expected payload length (%d bytes)", len(packetData), hdr.PayloadLen)
 			return fmt.Errorf("packet payload (%d bytes) is smaller than the expected payload length (%d bytes)", len(packetData), hdr.PayloadLen)
 		}
 		}

+ 6 - 6
vendor/github.com/lucas-clemente/quic-go/packet_packer.go

@@ -457,11 +457,15 @@ func (p *packetPacker) getHeader(encLevel protocol.EncryptionLevel) *wire.Header
 	header := &wire.Header{
 	header := &wire.Header{
 		PacketNumber:    pnum,
 		PacketNumber:    pnum,
 		PacketNumberLen: packetNumberLen,
 		PacketNumberLen: packetNumberLen,
+		Version:         p.version,
 	}
 	}
 
 
-	if p.version.UsesTLS() && encLevel != protocol.EncryptionForwardSecure {
+	if p.version.UsesIETFHeaderFormat() && encLevel != protocol.EncryptionForwardSecure {
 		header.IsLongHeader = true
 		header.IsLongHeader = true
 		header.SrcConnectionID = p.srcConnID
 		header.SrcConnectionID = p.srcConnID
+		if !p.version.UsesVarintPacketNumbers() {
+			header.PacketNumberLen = protocol.PacketNumberLen4
+		}
 		// Set the payload len to maximum size.
 		// Set the payload len to maximum size.
 		// Since it is encoded as a varint, this guarantees us that the header will end up at most as big as GetLength() returns.
 		// Since it is encoded as a varint, this guarantees us that the header will end up at most as big as GetLength() returns.
 		header.PayloadLen = p.maxPacketSize
 		header.PayloadLen = p.maxPacketSize
@@ -478,15 +482,11 @@ func (p *packetPacker) getHeader(encLevel protocol.EncryptionLevel) *wire.Header
 	}
 	}
 	if !p.version.UsesTLS() {
 	if !p.version.UsesTLS() {
 		if p.perspective == protocol.PerspectiveServer && encLevel == protocol.EncryptionSecure {
 		if p.perspective == protocol.PerspectiveServer && encLevel == protocol.EncryptionSecure {
+			header.Type = protocol.PacketType0RTT
 			header.DiversificationNonce = p.divNonce
 			header.DiversificationNonce = p.divNonce
 		}
 		}
 		if p.perspective == protocol.PerspectiveClient && encLevel != protocol.EncryptionForwardSecure {
 		if p.perspective == protocol.PerspectiveClient && encLevel != protocol.EncryptionForwardSecure {
 			header.VersionFlag = true
 			header.VersionFlag = true
-			header.Version = p.version
-		}
-	} else {
-		if encLevel != protocol.EncryptionForwardSecure {
-			header.Version = p.version
 		}
 		}
 	}
 	}
 	return header
 	return header

+ 27 - 21
vendor/github.com/lucas-clemente/quic-go/receive_stream.go

@@ -8,7 +8,6 @@ import (
 
 
 	"github.com/lucas-clemente/quic-go/internal/flowcontrol"
 	"github.com/lucas-clemente/quic-go/internal/flowcontrol"
 	"github.com/lucas-clemente/quic-go/internal/protocol"
 	"github.com/lucas-clemente/quic-go/internal/protocol"
-	"github.com/lucas-clemente/quic-go/internal/utils"
 	"github.com/lucas-clemente/quic-go/internal/wire"
 	"github.com/lucas-clemente/quic-go/internal/wire"
 )
 )
 
 
@@ -28,9 +27,12 @@ type receiveStream struct {
 
 
 	sender streamSender
 	sender streamSender
 
 
-	frameQueue     *streamFrameSorter
-	readPosInFrame int
-	readOffset     protocol.ByteCount
+	frameQueue *frameSorter
+	readOffset protocol.ByteCount
+
+	currentFrame       []byte
+	currentFrameIsLast bool // is the currentFrame the last frame on this stream
+	readPosInFrame     int
 
 
 	closeForShutdownErr error
 	closeForShutdownErr error
 	cancelReadErr       error
 	cancelReadErr       error
@@ -61,7 +63,7 @@ func newReceiveStream(
 		streamID:       streamID,
 		streamID:       streamID,
 		sender:         sender,
 		sender:         sender,
 		flowController: flowController,
 		flowController: flowController,
-		frameQueue:     newStreamFrameSorter(),
+		frameQueue:     newFrameSorter(),
 		readChan:       make(chan struct{}, 1),
 		readChan:       make(chan struct{}, 1),
 		version:        version,
 		version:        version,
 	}
 	}
@@ -99,8 +101,10 @@ func (s *receiveStream) readImpl(p []byte) (bool /*stream completed */, int, err
 
 
 	bytesRead := 0
 	bytesRead := 0
 	for bytesRead < len(p) {
 	for bytesRead < len(p) {
-		frame := s.frameQueue.Head()
-		if frame == nil && bytesRead > 0 {
+		if s.currentFrame == nil || s.readPosInFrame >= len(s.currentFrame) {
+			s.dequeueNextFrame()
+		}
+		if s.currentFrame == nil && bytesRead > 0 {
 			return false, bytesRead, s.closeForShutdownErr
 			return false, bytesRead, s.closeForShutdownErr
 		}
 		}
 
 
@@ -121,8 +125,7 @@ func (s *receiveStream) readImpl(p []byte) (bool /*stream completed */, int, err
 				return false, bytesRead, errDeadline
 				return false, bytesRead, errDeadline
 			}
 			}
 
 
-			if frame != nil {
-				s.readPosInFrame = int(s.readOffset - frame.Offset)
+			if s.currentFrame != nil || s.currentFrameIsLast {
 				break
 				break
 			}
 			}
 
 
@@ -136,20 +139,21 @@ func (s *receiveStream) readImpl(p []byte) (bool /*stream completed */, int, err
 				}
 				}
 			}
 			}
 			s.mutex.Lock()
 			s.mutex.Lock()
-			frame = s.frameQueue.Head()
+			if s.currentFrame == nil {
+				s.dequeueNextFrame()
+			}
 		}
 		}
 
 
 		if bytesRead > len(p) {
 		if bytesRead > len(p) {
 			return false, bytesRead, fmt.Errorf("BUG: bytesRead (%d) > len(p) (%d) in stream.Read", bytesRead, len(p))
 			return false, bytesRead, fmt.Errorf("BUG: bytesRead (%d) > len(p) (%d) in stream.Read", bytesRead, len(p))
 		}
 		}
-		if s.readPosInFrame > int(frame.DataLen()) {
-			return false, bytesRead, fmt.Errorf("BUG: readPosInFrame (%d) > frame.DataLen (%d) in stream.Read", s.readPosInFrame, frame.DataLen())
+		if s.readPosInFrame > len(s.currentFrame) {
+			return false, bytesRead, fmt.Errorf("BUG: readPosInFrame (%d) > frame.DataLen (%d) in stream.Read", s.readPosInFrame, len(s.currentFrame))
 		}
 		}
 
 
 		s.mutex.Unlock()
 		s.mutex.Unlock()
 
 
-		copy(p[bytesRead:], frame.Data[s.readPosInFrame:])
-		m := utils.Min(len(p)-bytesRead, int(frame.DataLen())-s.readPosInFrame)
+		m := copy(p[bytesRead:], s.currentFrame[s.readPosInFrame:])
 		s.readPosInFrame += m
 		s.readPosInFrame += m
 		bytesRead += m
 		bytesRead += m
 		s.readOffset += protocol.ByteCount(m)
 		s.readOffset += protocol.ByteCount(m)
@@ -162,17 +166,19 @@ func (s *receiveStream) readImpl(p []byte) (bool /*stream completed */, int, err
 		// increase the flow control window, if necessary
 		// increase the flow control window, if necessary
 		s.flowController.MaybeQueueWindowUpdate()
 		s.flowController.MaybeQueueWindowUpdate()
 
 
-		if s.readPosInFrame >= int(frame.DataLen()) {
-			s.frameQueue.Pop()
-			s.finRead = frame.FinBit
-			if frame.FinBit {
-				return true, bytesRead, io.EOF
-			}
+		if s.readPosInFrame >= len(s.currentFrame) && s.currentFrameIsLast {
+			s.finRead = true
+			return true, bytesRead, io.EOF
 		}
 		}
 	}
 	}
 	return false, bytesRead, nil
 	return false, bytesRead, nil
 }
 }
 
 
+func (s *receiveStream) dequeueNextFrame() {
+	s.currentFrame, s.currentFrameIsLast = s.frameQueue.Pop()
+	s.readPosInFrame = 0
+}
+
 func (s *receiveStream) CancelRead(errorCode protocol.ApplicationErrorCode) error {
 func (s *receiveStream) CancelRead(errorCode protocol.ApplicationErrorCode) error {
 	s.mutex.Lock()
 	s.mutex.Lock()
 	defer s.mutex.Unlock()
 	defer s.mutex.Unlock()
@@ -203,7 +209,7 @@ func (s *receiveStream) handleStreamFrame(frame *wire.StreamFrame) error {
 
 
 	s.mutex.Lock()
 	s.mutex.Lock()
 	defer s.mutex.Unlock()
 	defer s.mutex.Unlock()
-	if err := s.frameQueue.Push(frame); err != nil && err != errDuplicateStreamData {
+	if err := s.frameQueue.Push(frame.Data, frame.Offset, frame.FinBit); err != nil {
 		return err
 		return err
 	}
 	}
 	s.signalRead()
 	s.signalRead()

+ 45 - 13
vendor/github.com/lucas-clemente/quic-go/server.go

@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 	"net"
 	"net"
+	"sync"
 	"time"
 	"time"
 
 
 	"github.com/lucas-clemente/quic-go/internal/crypto"
 	"github.com/lucas-clemente/quic-go/internal/crypto"
@@ -62,6 +63,8 @@ var _ sessionRunner = &runner{}
 
 
 // A Listener of QUIC
 // A Listener of QUIC
 type server struct {
 type server struct {
+	mutex sync.Mutex
+
 	tlsConf *tls.Config
 	tlsConf *tls.Config
 	config  *Config
 	config  *Config
 
 
@@ -79,13 +82,14 @@ type server struct {
 	sessionHandler packetHandlerManager
 	sessionHandler packetHandlerManager
 
 
 	serverError error
 	serverError error
+	errorChan   chan struct{}
+	closed      bool
 
 
 	sessionQueue chan Session
 	sessionQueue chan Session
-	errorChan    chan struct{}
 
 
 	sessionRunner sessionRunner
 	sessionRunner sessionRunner
 	// set as a member, so they can be set in the tests
 	// set as a member, so they can be set in the tests
-	newSession func(connection, sessionRunner, protocol.VersionNumber, protocol.ConnectionID, *handshake.ServerConfig, *tls.Config, *Config, utils.Logger) (quicSession, error)
+	newSession func(connection, sessionRunner, protocol.VersionNumber, protocol.ConnectionID, protocol.ConnectionID, *handshake.ServerConfig, *tls.Config, *Config, utils.Logger) (quicSession, error)
 
 
 	logger utils.Logger
 	logger utils.Logger
 }
 }
@@ -265,6 +269,11 @@ func populateServerConfig(config *Config) *Config {
 	if connIDLen == 0 {
 	if connIDLen == 0 {
 		connIDLen = protocol.DefaultConnectionIDLength
 		connIDLen = protocol.DefaultConnectionIDLength
 	}
 	}
+	for _, v := range versions {
+		if v == protocol.Version44 {
+			connIDLen = protocol.ConnectionIDLenGQUIC
+		}
+	}
 
 
 	return &Config{
 	return &Config{
 		Versions:                              versions,
 		Versions:                              versions,
@@ -293,6 +302,15 @@ func (s *server) Accept() (Session, error) {
 
 
 // Close the server
 // Close the server
 func (s *server) Close() error {
 func (s *server) Close() error {
+	s.mutex.Lock()
+	defer s.mutex.Unlock()
+	if s.closed {
+		return nil
+	}
+	return s.closeWithMutex()
+}
+
+func (s *server) closeWithMutex() error {
 	s.sessionHandler.CloseServer()
 	s.sessionHandler.CloseServer()
 	if s.serverError == nil {
 	if s.serverError == nil {
 		s.serverError = errors.New("server closed")
 		s.serverError = errors.New("server closed")
@@ -303,20 +321,26 @@ func (s *server) Close() error {
 	if s.createdPacketConn {
 	if s.createdPacketConn {
 		err = s.conn.Close()
 		err = s.conn.Close()
 	}
 	}
+	s.closed = true
 	close(s.errorChan)
 	close(s.errorChan)
 	return err
 	return err
 }
 }
 
 
+func (s *server) closeWithError(e error) error {
+	s.mutex.Lock()
+	defer s.mutex.Unlock()
+	if s.closed {
+		return nil
+	}
+	s.serverError = e
+	return s.closeWithMutex()
+}
+
 // Addr returns the server's network address
 // Addr returns the server's network address
 func (s *server) Addr() net.Addr {
 func (s *server) Addr() net.Addr {
 	return s.conn.LocalAddr()
 	return s.conn.LocalAddr()
 }
 }
 
 
-func (s *server) closeWithError(e error) error {
-	s.serverError = e
-	return s.Close()
-}
-
 func (s *server) handlePacket(p *receivedPacket) {
 func (s *server) handlePacket(p *receivedPacket) {
 	if err := s.handlePacketImpl(p); err != nil {
 	if err := s.handlePacketImpl(p); err != nil {
 		s.logger.Debugf("error handling packet from %s: %s", p.remoteAddr, err)
 		s.logger.Debugf("error handling packet from %s: %s", p.remoteAddr, err)
@@ -332,13 +356,13 @@ func (s *server) handlePacketImpl(p *receivedPacket) error {
 			return s.sendVersionNegotiationPacket(p)
 			return s.sendVersionNegotiationPacket(p)
 		}
 		}
 	}
 	}
-	if hdr.Type == protocol.PacketTypeInitial {
+	if hdr.Type == protocol.PacketTypeInitial && hdr.Version.UsesTLS() {
 		go s.serverTLS.HandleInitial(p)
 		go s.serverTLS.HandleInitial(p)
 		return nil
 		return nil
 	}
 	}
 
 
 	// TODO(#943): send Stateless Reset, if this an IETF QUIC packet
 	// TODO(#943): send Stateless Reset, if this an IETF QUIC packet
-	if !hdr.VersionFlag {
+	if !hdr.VersionFlag && !hdr.Version.UsesIETFHeaderFormat() {
 		_, err := s.conn.WriteTo(wire.WritePublicReset(hdr.DestConnectionID, 0, 0), p.remoteAddr)
 		_, err := s.conn.WriteTo(wire.WritePublicReset(hdr.DestConnectionID, 0, 0), p.remoteAddr)
 		return err
 		return err
 	}
 	}
@@ -349,12 +373,20 @@ func (s *server) handlePacketImpl(p *receivedPacket) error {
 		return errors.New("dropping small packet for unknown connection")
 		return errors.New("dropping small packet for unknown connection")
 	}
 	}
 
 
+	var destConnID, srcConnID protocol.ConnectionID
+	if hdr.Version.UsesIETFHeaderFormat() {
+		srcConnID = hdr.DestConnectionID
+	} else {
+		destConnID = hdr.DestConnectionID
+		srcConnID = hdr.DestConnectionID
+	}
 	s.logger.Infof("Serving new connection: %s, version %s from %v", hdr.DestConnectionID, hdr.Version, p.remoteAddr)
 	s.logger.Infof("Serving new connection: %s, version %s from %v", hdr.DestConnectionID, hdr.Version, p.remoteAddr)
 	sess, err := s.newSession(
 	sess, err := s.newSession(
 		&conn{pconn: s.conn, currentAddr: p.remoteAddr},
 		&conn{pconn: s.conn, currentAddr: p.remoteAddr},
 		s.sessionRunner,
 		s.sessionRunner,
 		hdr.Version,
 		hdr.Version,
-		hdr.DestConnectionID,
+		destConnID,
+		srcConnID,
 		s.scfg,
 		s.scfg,
 		s.tlsConf,
 		s.tlsConf,
 		s.config,
 		s.config,
@@ -374,14 +406,14 @@ func (s *server) sendVersionNegotiationPacket(p *receivedPacket) error {
 	s.logger.Debugf("Client offered version %s, sending VersionNegotiationPacket", hdr.Version)
 	s.logger.Debugf("Client offered version %s, sending VersionNegotiationPacket", hdr.Version)
 
 
 	var data []byte
 	var data []byte
-	if hdr.Version.UsesIETFFrameFormat() {
+	if hdr.IsPublicHeader {
+		data = wire.ComposeGQUICVersionNegotiation(hdr.DestConnectionID, s.config.Versions)
+	} else {
 		var err error
 		var err error
 		data, err = wire.ComposeVersionNegotiation(hdr.SrcConnectionID, hdr.DestConnectionID, s.config.Versions)
 		data, err = wire.ComposeVersionNegotiation(hdr.SrcConnectionID, hdr.DestConnectionID, s.config.Versions)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
-	} else {
-		data = wire.ComposeGQUICVersionNegotiation(hdr.DestConnectionID, s.config.Versions)
 	}
 	}
 	_, err := s.conn.WriteTo(data, p.remoteAddr)
 	_, err := s.conn.WriteTo(data, p.remoteAddr)
 	return err
 	return err

+ 1 - 1
vendor/github.com/lucas-clemente/quic-go/server_session.go

@@ -46,7 +46,7 @@ func (s *serverSession) handlePacketImpl(p *receivedPacket) error {
 
 
 	if hdr.IsLongHeader {
 	if hdr.IsLongHeader {
 		switch hdr.Type {
 		switch hdr.Type {
-		case protocol.PacketTypeHandshake:
+		case protocol.PacketTypeHandshake, protocol.PacketType0RTT: // 0-RTT accepted for gQUIC 44
 			// nothing to do here. Packet will be passed to the session.
 			// nothing to do here. Packet will be passed to the session.
 		default:
 		default:
 			// Note that this also drops 0-RTT packets.
 			// Note that this also drops 0-RTT packets.

+ 16 - 12
vendor/github.com/lucas-clemente/quic-go/session.go

@@ -152,19 +152,21 @@ func newSession(
 	conn connection,
 	conn connection,
 	sessionRunner sessionRunner,
 	sessionRunner sessionRunner,
 	v protocol.VersionNumber,
 	v protocol.VersionNumber,
-	connectionID protocol.ConnectionID,
+	destConnID protocol.ConnectionID,
+	srcConnID protocol.ConnectionID,
 	scfg *handshake.ServerConfig,
 	scfg *handshake.ServerConfig,
 	tlsConf *tls.Config,
 	tlsConf *tls.Config,
 	config *Config,
 	config *Config,
 	logger utils.Logger,
 	logger utils.Logger,
 ) (quicSession, error) {
 ) (quicSession, error) {
+	logger.Debugf("Creating new session. Destination Connection ID: %s, Source Connection ID: %s", destConnID, srcConnID)
 	paramsChan := make(chan handshake.TransportParameters)
 	paramsChan := make(chan handshake.TransportParameters)
 	handshakeEvent := make(chan struct{}, 1)
 	handshakeEvent := make(chan struct{}, 1)
 	s := &session{
 	s := &session{
 		conn:           conn,
 		conn:           conn,
 		sessionRunner:  sessionRunner,
 		sessionRunner:  sessionRunner,
-		srcConnID:      connectionID,
-		destConnID:     connectionID,
+		srcConnID:      srcConnID,
+		destConnID:     destConnID,
 		perspective:    protocol.PerspectiveServer,
 		perspective:    protocol.PerspectiveServer,
 		version:        v,
 		version:        v,
 		config:         config,
 		config:         config,
@@ -185,7 +187,7 @@ func newSession(
 	}
 	}
 	cs, err := newCryptoSetup(
 	cs, err := newCryptoSetup(
 		s.cryptoStream,
 		s.cryptoStream,
-		connectionID,
+		srcConnID,
 		s.conn.RemoteAddr(),
 		s.conn.RemoteAddr(),
 		s.version,
 		s.version,
 		divNonce,
 		divNonce,
@@ -205,8 +207,8 @@ func newSession(
 	s.streamsMap = newStreamsMapLegacy(s.newStream, s.config.MaxIncomingStreams, s.perspective)
 	s.streamsMap = newStreamsMapLegacy(s.newStream, s.config.MaxIncomingStreams, s.perspective)
 	s.streamFramer = newStreamFramer(s.cryptoStream, s.streamsMap, s.version)
 	s.streamFramer = newStreamFramer(s.cryptoStream, s.streamsMap, s.version)
 	s.packer = newPacketPacker(
 	s.packer = newPacketPacker(
-		connectionID,
-		nil, // no src connection ID
+		destConnID,
+		srcConnID,
 		1,
 		1,
 		s.sentPacketHandler.GetPacketNumberLen,
 		s.sentPacketHandler.GetPacketNumberLen,
 		s.RemoteAddr(),
 		s.RemoteAddr(),
@@ -226,20 +228,22 @@ var newClientSession = func(
 	sessionRunner sessionRunner,
 	sessionRunner sessionRunner,
 	hostname string,
 	hostname string,
 	v protocol.VersionNumber,
 	v protocol.VersionNumber,
-	connectionID protocol.ConnectionID,
+	destConnID protocol.ConnectionID,
+	srcConnID protocol.ConnectionID,
 	tlsConf *tls.Config,
 	tlsConf *tls.Config,
 	config *Config,
 	config *Config,
 	initialVersion protocol.VersionNumber,
 	initialVersion protocol.VersionNumber,
 	negotiatedVersions []protocol.VersionNumber, // needed for validation of the GQUIC version negotiation
 	negotiatedVersions []protocol.VersionNumber, // needed for validation of the GQUIC version negotiation
 	logger utils.Logger,
 	logger utils.Logger,
 ) (quicSession, error) {
 ) (quicSession, error) {
+	logger.Debugf("Creating new session. Destination Connection ID: %s, Source Connection ID: %s", destConnID, srcConnID)
 	paramsChan := make(chan handshake.TransportParameters)
 	paramsChan := make(chan handshake.TransportParameters)
 	handshakeEvent := make(chan struct{}, 1)
 	handshakeEvent := make(chan struct{}, 1)
 	s := &session{
 	s := &session{
 		conn:           conn,
 		conn:           conn,
 		sessionRunner:  sessionRunner,
 		sessionRunner:  sessionRunner,
-		srcConnID:      connectionID,
-		destConnID:     connectionID,
+		srcConnID:      srcConnID,
+		destConnID:     destConnID,
 		perspective:    protocol.PerspectiveClient,
 		perspective:    protocol.PerspectiveClient,
 		version:        v,
 		version:        v,
 		config:         config,
 		config:         config,
@@ -258,7 +262,7 @@ var newClientSession = func(
 	cs, err := newCryptoSetupClient(
 	cs, err := newCryptoSetupClient(
 		s.cryptoStream,
 		s.cryptoStream,
 		hostname,
 		hostname,
-		connectionID,
+		destConnID,
 		s.version,
 		s.version,
 		tlsConf,
 		tlsConf,
 		transportParams,
 		transportParams,
@@ -276,8 +280,8 @@ var newClientSession = func(
 	s.streamsMap = newStreamsMapLegacy(s.newStream, s.config.MaxIncomingStreams, s.perspective)
 	s.streamsMap = newStreamsMapLegacy(s.newStream, s.config.MaxIncomingStreams, s.perspective)
 	s.streamFramer = newStreamFramer(s.cryptoStream, s.streamsMap, s.version)
 	s.streamFramer = newStreamFramer(s.cryptoStream, s.streamsMap, s.version)
 	s.packer = newPacketPacker(
 	s.packer = newPacketPacker(
-		connectionID,
-		nil, // no src connection ID
+		destConnID,
+		srcConnID,
 		1,
 		1,
 		s.sentPacketHandler.GetPacketNumberLen,
 		s.sentPacketHandler.GetPacketNumberLen,
 		s.RemoteAddr(),
 		s.RemoteAddr(),

+ 50 - 0
vendor/golang.org/x/net/http/httpguts/guts.go

@@ -0,0 +1,50 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package httpguts provides functions implementing various details
+// of the HTTP specification.
+//
+// This package is shared by the standard library (which vendors it)
+// and x/net/http2. It comes with no API stability promise.
+package httpguts
+
+import (
+	"net/textproto"
+	"strings"
+)
+
+// ValidTrailerHeader reports whether name is a valid header field name to appear
+// in trailers.
+// See RFC 7230, Section 4.1.2
+func ValidTrailerHeader(name string) bool {
+	name = textproto.CanonicalMIMEHeaderKey(name)
+	if strings.HasPrefix(name, "If-") || badTrailer[name] {
+		return false
+	}
+	return true
+}
+
+var badTrailer = map[string]bool{
+	"Authorization":       true,
+	"Cache-Control":       true,
+	"Connection":          true,
+	"Content-Encoding":    true,
+	"Content-Length":      true,
+	"Content-Range":       true,
+	"Content-Type":        true,
+	"Expect":              true,
+	"Host":                true,
+	"Keep-Alive":          true,
+	"Max-Forwards":        true,
+	"Pragma":              true,
+	"Proxy-Authenticate":  true,
+	"Proxy-Authorization": true,
+	"Proxy-Connection":    true,
+	"Range":               true,
+	"Realm":               true,
+	"Te":                  true,
+	"Trailer":             true,
+	"Transfer-Encoding":   true,
+	"Www-Authenticate":    true,
+}

+ 346 - 0
vendor/golang.org/x/net/http/httpguts/httplex.go

@@ -0,0 +1,346 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package httpguts
+
+import (
+	"net"
+	"strings"
+	"unicode/utf8"
+
+	"golang.org/x/net/idna"
+)
+
+var isTokenTable = [127]bool{
+	'!':  true,
+	'#':  true,
+	'$':  true,
+	'%':  true,
+	'&':  true,
+	'\'': true,
+	'*':  true,
+	'+':  true,
+	'-':  true,
+	'.':  true,
+	'0':  true,
+	'1':  true,
+	'2':  true,
+	'3':  true,
+	'4':  true,
+	'5':  true,
+	'6':  true,
+	'7':  true,
+	'8':  true,
+	'9':  true,
+	'A':  true,
+	'B':  true,
+	'C':  true,
+	'D':  true,
+	'E':  true,
+	'F':  true,
+	'G':  true,
+	'H':  true,
+	'I':  true,
+	'J':  true,
+	'K':  true,
+	'L':  true,
+	'M':  true,
+	'N':  true,
+	'O':  true,
+	'P':  true,
+	'Q':  true,
+	'R':  true,
+	'S':  true,
+	'T':  true,
+	'U':  true,
+	'W':  true,
+	'V':  true,
+	'X':  true,
+	'Y':  true,
+	'Z':  true,
+	'^':  true,
+	'_':  true,
+	'`':  true,
+	'a':  true,
+	'b':  true,
+	'c':  true,
+	'd':  true,
+	'e':  true,
+	'f':  true,
+	'g':  true,
+	'h':  true,
+	'i':  true,
+	'j':  true,
+	'k':  true,
+	'l':  true,
+	'm':  true,
+	'n':  true,
+	'o':  true,
+	'p':  true,
+	'q':  true,
+	'r':  true,
+	's':  true,
+	't':  true,
+	'u':  true,
+	'v':  true,
+	'w':  true,
+	'x':  true,
+	'y':  true,
+	'z':  true,
+	'|':  true,
+	'~':  true,
+}
+
+func IsTokenRune(r rune) bool {
+	i := int(r)
+	return i < len(isTokenTable) && isTokenTable[i]
+}
+
+func isNotToken(r rune) bool {
+	return !IsTokenRune(r)
+}
+
+// HeaderValuesContainsToken reports whether any string in values
+// contains the provided token, ASCII case-insensitively.
+func HeaderValuesContainsToken(values []string, token string) bool {
+	for _, v := range values {
+		if headerValueContainsToken(v, token) {
+			return true
+		}
+	}
+	return false
+}
+
+// isOWS reports whether b is an optional whitespace byte, as defined
+// by RFC 7230 section 3.2.3.
+func isOWS(b byte) bool { return b == ' ' || b == '\t' }
+
+// trimOWS returns x with all optional whitespace removes from the
+// beginning and end.
+func trimOWS(x string) string {
+	// TODO: consider using strings.Trim(x, " \t") instead,
+	// if and when it's fast enough. See issue 10292.
+	// But this ASCII-only code will probably always beat UTF-8
+	// aware code.
+	for len(x) > 0 && isOWS(x[0]) {
+		x = x[1:]
+	}
+	for len(x) > 0 && isOWS(x[len(x)-1]) {
+		x = x[:len(x)-1]
+	}
+	return x
+}
+
+// headerValueContainsToken reports whether v (assumed to be a
+// 0#element, in the ABNF extension described in RFC 7230 section 7)
+// contains token amongst its comma-separated tokens, ASCII
+// case-insensitively.
+func headerValueContainsToken(v string, token string) bool {
+	v = trimOWS(v)
+	if comma := strings.IndexByte(v, ','); comma != -1 {
+		return tokenEqual(trimOWS(v[:comma]), token) || headerValueContainsToken(v[comma+1:], token)
+	}
+	return tokenEqual(v, token)
+}
+
+// lowerASCII returns the ASCII lowercase version of b.
+func lowerASCII(b byte) byte {
+	if 'A' <= b && b <= 'Z' {
+		return b + ('a' - 'A')
+	}
+	return b
+}
+
+// tokenEqual reports whether t1 and t2 are equal, ASCII case-insensitively.
+func tokenEqual(t1, t2 string) bool {
+	if len(t1) != len(t2) {
+		return false
+	}
+	for i, b := range t1 {
+		if b >= utf8.RuneSelf {
+			// No UTF-8 or non-ASCII allowed in tokens.
+			return false
+		}
+		if lowerASCII(byte(b)) != lowerASCII(t2[i]) {
+			return false
+		}
+	}
+	return true
+}
+
+// isLWS reports whether b is linear white space, according
+// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
+//      LWS            = [CRLF] 1*( SP | HT )
+func isLWS(b byte) bool { return b == ' ' || b == '\t' }
+
+// isCTL reports whether b is a control byte, according
+// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
+//      CTL            = <any US-ASCII control character
+//                       (octets 0 - 31) and DEL (127)>
+func isCTL(b byte) bool {
+	const del = 0x7f // a CTL
+	return b < ' ' || b == del
+}
+
+// ValidHeaderFieldName reports whether v is a valid HTTP/1.x header name.
+// HTTP/2 imposes the additional restriction that uppercase ASCII
+// letters are not allowed.
+//
+//  RFC 7230 says:
+//   header-field   = field-name ":" OWS field-value OWS
+//   field-name     = token
+//   token          = 1*tchar
+//   tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
+//           "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
+func ValidHeaderFieldName(v string) bool {
+	if len(v) == 0 {
+		return false
+	}
+	for _, r := range v {
+		if !IsTokenRune(r) {
+			return false
+		}
+	}
+	return true
+}
+
+// ValidHostHeader reports whether h is a valid host header.
+func ValidHostHeader(h string) bool {
+	// The latest spec is actually this:
+	//
+	// http://tools.ietf.org/html/rfc7230#section-5.4
+	//     Host = uri-host [ ":" port ]
+	//
+	// Where uri-host is:
+	//     http://tools.ietf.org/html/rfc3986#section-3.2.2
+	//
+	// But we're going to be much more lenient for now and just
+	// search for any byte that's not a valid byte in any of those
+	// expressions.
+	for i := 0; i < len(h); i++ {
+		if !validHostByte[h[i]] {
+			return false
+		}
+	}
+	return true
+}
+
+// See the validHostHeader comment.
+var validHostByte = [256]bool{
+	'0': true, '1': true, '2': true, '3': true, '4': true, '5': true, '6': true, '7': true,
+	'8': true, '9': true,
+
+	'a': true, 'b': true, 'c': true, 'd': true, 'e': true, 'f': true, 'g': true, 'h': true,
+	'i': true, 'j': true, 'k': true, 'l': true, 'm': true, 'n': true, 'o': true, 'p': true,
+	'q': true, 'r': true, 's': true, 't': true, 'u': true, 'v': true, 'w': true, 'x': true,
+	'y': true, 'z': true,
+
+	'A': true, 'B': true, 'C': true, 'D': true, 'E': true, 'F': true, 'G': true, 'H': true,
+	'I': true, 'J': true, 'K': true, 'L': true, 'M': true, 'N': true, 'O': true, 'P': true,
+	'Q': true, 'R': true, 'S': true, 'T': true, 'U': true, 'V': true, 'W': true, 'X': true,
+	'Y': true, 'Z': true,
+
+	'!':  true, // sub-delims
+	'$':  true, // sub-delims
+	'%':  true, // pct-encoded (and used in IPv6 zones)
+	'&':  true, // sub-delims
+	'(':  true, // sub-delims
+	')':  true, // sub-delims
+	'*':  true, // sub-delims
+	'+':  true, // sub-delims
+	',':  true, // sub-delims
+	'-':  true, // unreserved
+	'.':  true, // unreserved
+	':':  true, // IPv6address + Host expression's optional port
+	';':  true, // sub-delims
+	'=':  true, // sub-delims
+	'[':  true,
+	'\'': true, // sub-delims
+	']':  true,
+	'_':  true, // unreserved
+	'~':  true, // unreserved
+}
+
+// ValidHeaderFieldValue reports whether v is a valid "field-value" according to
+// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 :
+//
+//        message-header = field-name ":" [ field-value ]
+//        field-value    = *( field-content | LWS )
+//        field-content  = <the OCTETs making up the field-value
+//                         and consisting of either *TEXT or combinations
+//                         of token, separators, and quoted-string>
+//
+// http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 :
+//
+//        TEXT           = <any OCTET except CTLs,
+//                          but including LWS>
+//        LWS            = [CRLF] 1*( SP | HT )
+//        CTL            = <any US-ASCII control character
+//                         (octets 0 - 31) and DEL (127)>
+//
+// RFC 7230 says:
+//  field-value    = *( field-content / obs-fold )
+//  obj-fold       =  N/A to http2, and deprecated
+//  field-content  = field-vchar [ 1*( SP / HTAB ) field-vchar ]
+//  field-vchar    = VCHAR / obs-text
+//  obs-text       = %x80-FF
+//  VCHAR          = "any visible [USASCII] character"
+//
+// http2 further says: "Similarly, HTTP/2 allows header field values
+// that are not valid. While most of the values that can be encoded
+// will not alter header field parsing, carriage return (CR, ASCII
+// 0xd), line feed (LF, ASCII 0xa), and the zero character (NUL, ASCII
+// 0x0) might be exploited by an attacker if they are translated
+// verbatim. Any request or response that contains a character not
+// permitted in a header field value MUST be treated as malformed
+// (Section 8.1.2.6). Valid characters are defined by the
+// field-content ABNF rule in Section 3.2 of [RFC7230]."
+//
+// This function does not (yet?) properly handle the rejection of
+// strings that begin or end with SP or HTAB.
+func ValidHeaderFieldValue(v string) bool {
+	for i := 0; i < len(v); i++ {
+		b := v[i]
+		if isCTL(b) && !isLWS(b) {
+			return false
+		}
+	}
+	return true
+}
+
+func isASCII(s string) bool {
+	for i := 0; i < len(s); i++ {
+		if s[i] >= utf8.RuneSelf {
+			return false
+		}
+	}
+	return true
+}
+
+// PunycodeHostPort returns the IDNA Punycode version
+// of the provided "host" or "host:port" string.
+func PunycodeHostPort(v string) (string, error) {
+	if isASCII(v) {
+		return v, nil
+	}
+
+	host, port, err := net.SplitHostPort(v)
+	if err != nil {
+		// The input 'v' argument was just a "host" argument,
+		// without a port. This error should not be returned
+		// to the caller.
+		host = v
+		port = ""
+	}
+	host, err = idna.ToASCII(host)
+	if err != nil {
+		// Non-UTF-8? Not representable in Punycode, in any
+		// case.
+		return "", err
+	}
+	if port == "" {
+		return host, nil
+	}
+	return net.JoinHostPort(host, port), nil
+}

+ 1 - 1
vendor/golang.org/x/net/http2/ciphers.go

@@ -5,7 +5,7 @@
 package http2
 package http2
 
 
 // A list of the possible cipher suite ids. Taken from
 // A list of the possible cipher suite ids. Taken from
-// http://www.iana.org/assignments/tls-parameters/tls-parameters.txt
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.txt
 
 
 const (
 const (
 	cipher_TLS_NULL_WITH_NULL_NULL               uint16 = 0x0000
 	cipher_TLS_NULL_WITH_NULL_NULL               uint16 = 0x0000

+ 27 - 1
vendor/golang.org/x/net/http2/client_conn_pool.go

@@ -52,9 +52,31 @@ const (
 	noDialOnMiss = false
 	noDialOnMiss = false
 )
 )
 
 
+// shouldTraceGetConn reports whether getClientConn should call any
+// ClientTrace.GetConn hook associated with the http.Request.
+//
+// This complexity is needed to avoid double calls of the GetConn hook
+// during the back-and-forth between net/http and x/net/http2 (when the
+// net/http.Transport is upgraded to also speak http2), as well as support
+// the case where x/net/http2 is being used directly.
+func (p *clientConnPool) shouldTraceGetConn(st clientConnIdleState) bool {
+	// If our Transport wasn't made via ConfigureTransport, always
+	// trace the GetConn hook if provided, because that means the
+	// http2 package is being used directly and it's the one
+	// dialing, as opposed to net/http.
+	if _, ok := p.t.ConnPool.(noDialClientConnPool); !ok {
+		return true
+	}
+	// Otherwise, only use the GetConn hook if this connection has
+	// been used previously for other requests. For fresh
+	// connections, the net/http package does the dialing.
+	return !st.freshConn
+}
+
 func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) {
 func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) {
 	if isConnectionCloseRequest(req) && dialOnMiss {
 	if isConnectionCloseRequest(req) && dialOnMiss {
 		// It gets its own connection.
 		// It gets its own connection.
+		traceGetConn(req, addr)
 		const singleUse = true
 		const singleUse = true
 		cc, err := p.t.dialClientConn(addr, singleUse)
 		cc, err := p.t.dialClientConn(addr, singleUse)
 		if err != nil {
 		if err != nil {
@@ -64,7 +86,10 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis
 	}
 	}
 	p.mu.Lock()
 	p.mu.Lock()
 	for _, cc := range p.conns[addr] {
 	for _, cc := range p.conns[addr] {
-		if cc.CanTakeNewRequest() {
+		if st := cc.idleState(); st.canTakeNewRequest {
+			if p.shouldTraceGetConn(st) {
+				traceGetConn(req, addr)
+			}
 			p.mu.Unlock()
 			p.mu.Unlock()
 			return cc, nil
 			return cc, nil
 		}
 		}
@@ -73,6 +98,7 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis
 		p.mu.Unlock()
 		p.mu.Unlock()
 		return nil, ErrNoCachedConn
 		return nil, ErrNoCachedConn
 	}
 	}
+	traceGetConn(req, addr)
 	call := p.getStartDialLocked(addr)
 	call := p.getStartDialLocked(addr)
 	p.mu.Unlock()
 	p.mu.Unlock()
 	<-call.done
 	<-call.done

+ 6 - 4
vendor/golang.org/x/net/http2/configure_transport.go

@@ -57,7 +57,7 @@ func configureTransport(t1 *http.Transport) (*Transport, error) {
 
 
 // registerHTTPSProtocol calls Transport.RegisterProtocol but
 // registerHTTPSProtocol calls Transport.RegisterProtocol but
 // converting panics into errors.
 // converting panics into errors.
-func registerHTTPSProtocol(t *http.Transport, rt http.RoundTripper) (err error) {
+func registerHTTPSProtocol(t *http.Transport, rt noDialH2RoundTripper) (err error) {
 	defer func() {
 	defer func() {
 		if e := recover(); e != nil {
 		if e := recover(); e != nil {
 			err = fmt.Errorf("%v", e)
 			err = fmt.Errorf("%v", e)
@@ -69,11 +69,13 @@ func registerHTTPSProtocol(t *http.Transport, rt http.RoundTripper) (err error)
 
 
 // noDialH2RoundTripper is a RoundTripper which only tries to complete the request
 // noDialH2RoundTripper is a RoundTripper which only tries to complete the request
 // if there's already has a cached connection to the host.
 // if there's already has a cached connection to the host.
-type noDialH2RoundTripper struct{ t *Transport }
+// (The field is exported so it can be accessed via reflect from net/http; tested
+// by TestNoDialH2RoundTripperType)
+type noDialH2RoundTripper struct{ *Transport }
 
 
 func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
 func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
-	res, err := rt.t.RoundTrip(req)
-	if err == ErrNoCachedConn {
+	res, err := rt.Transport.RoundTrip(req)
+	if isNoCachedConnError(err) {
 		return nil, http.ErrSkipAltProtocol
 		return nil, http.ErrSkipAltProtocol
 	}
 	}
 	return res, err
 	return res, err

+ 5 - 5
vendor/golang.org/x/net/http2/flow.go

@@ -41,10 +41,10 @@ func (f *flow) take(n int32) {
 // add adds n bytes (positive or negative) to the flow control window.
 // add adds n bytes (positive or negative) to the flow control window.
 // It returns false if the sum would exceed 2^31-1.
 // It returns false if the sum would exceed 2^31-1.
 func (f *flow) add(n int32) bool {
 func (f *flow) add(n int32) bool {
-	remain := (1<<31 - 1) - f.n
-	if n > remain {
-		return false
+	sum := f.n + n
+	if (sum > n) == (f.n > 0) {
+		f.n = sum
+		return true
 	}
 	}
-	f.n += n
-	return true
+	return false
 }
 }

+ 51 - 16
vendor/golang.org/x/net/http2/frame.go

@@ -14,8 +14,8 @@ import (
 	"strings"
 	"strings"
 	"sync"
 	"sync"
 
 
+	"golang.org/x/net/http/httpguts"
 	"golang.org/x/net/http2/hpack"
 	"golang.org/x/net/http2/hpack"
-	"golang.org/x/net/lex/httplex"
 )
 )
 
 
 const frameHeaderLen = 9
 const frameHeaderLen = 9
@@ -733,32 +733,67 @@ func (f *SettingsFrame) IsAck() bool {
 	return f.FrameHeader.Flags.Has(FlagSettingsAck)
 	return f.FrameHeader.Flags.Has(FlagSettingsAck)
 }
 }
 
 
-func (f *SettingsFrame) Value(s SettingID) (v uint32, ok bool) {
+func (f *SettingsFrame) Value(id SettingID) (v uint32, ok bool) {
 	f.checkValid()
 	f.checkValid()
-	buf := f.p
-	for len(buf) > 0 {
-		settingID := SettingID(binary.BigEndian.Uint16(buf[:2]))
-		if settingID == s {
-			return binary.BigEndian.Uint32(buf[2:6]), true
+	for i := 0; i < f.NumSettings(); i++ {
+		if s := f.Setting(i); s.ID == id {
+			return s.Val, true
 		}
 		}
-		buf = buf[6:]
 	}
 	}
 	return 0, false
 	return 0, false
 }
 }
 
 
+// Setting returns the setting from the frame at the given 0-based index.
+// The index must be >= 0 and less than f.NumSettings().
+func (f *SettingsFrame) Setting(i int) Setting {
+	buf := f.p
+	return Setting{
+		ID:  SettingID(binary.BigEndian.Uint16(buf[i*6 : i*6+2])),
+		Val: binary.BigEndian.Uint32(buf[i*6+2 : i*6+6]),
+	}
+}
+
+func (f *SettingsFrame) NumSettings() int { return len(f.p) / 6 }
+
+// HasDuplicates reports whether f contains any duplicate setting IDs.
+func (f *SettingsFrame) HasDuplicates() bool {
+	num := f.NumSettings()
+	if num == 0 {
+		return false
+	}
+	// If it's small enough (the common case), just do the n^2
+	// thing and avoid a map allocation.
+	if num < 10 {
+		for i := 0; i < num; i++ {
+			idi := f.Setting(i).ID
+			for j := i + 1; j < num; j++ {
+				idj := f.Setting(j).ID
+				if idi == idj {
+					return true
+				}
+			}
+		}
+		return false
+	}
+	seen := map[SettingID]bool{}
+	for i := 0; i < num; i++ {
+		id := f.Setting(i).ID
+		if seen[id] {
+			return true
+		}
+		seen[id] = true
+	}
+	return false
+}
+
 // ForeachSetting runs fn for each setting.
 // ForeachSetting runs fn for each setting.
 // It stops and returns the first error.
 // It stops and returns the first error.
 func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error {
 func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error {
 	f.checkValid()
 	f.checkValid()
-	buf := f.p
-	for len(buf) > 0 {
-		if err := fn(Setting{
-			SettingID(binary.BigEndian.Uint16(buf[:2])),
-			binary.BigEndian.Uint32(buf[2:6]),
-		}); err != nil {
+	for i := 0; i < f.NumSettings(); i++ {
+		if err := fn(f.Setting(i)); err != nil {
 			return err
 			return err
 		}
 		}
-		buf = buf[6:]
 	}
 	}
 	return nil
 	return nil
 }
 }
@@ -1462,7 +1497,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
 		if VerboseLogs && fr.logReads {
 		if VerboseLogs && fr.logReads {
 			fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
 			fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
 		}
 		}
-		if !httplex.ValidHeaderFieldValue(hf.Value) {
+		if !httpguts.ValidHeaderFieldValue(hf.Value) {
 			invalid = headerFieldValueError(hf.Value)
 			invalid = headerFieldValueError(hf.Value)
 		}
 		}
 		isPseudo := strings.HasPrefix(hf.Name, ":")
 		isPseudo := strings.HasPrefix(hf.Name, ":")

+ 26 - 0
vendor/golang.org/x/net/http2/go111.go

@@ -0,0 +1,26 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.11
+
+package http2
+
+import "net/textproto"
+
+func traceHasWroteHeaderField(trace *clientTrace) bool {
+	return trace != nil && trace.WroteHeaderField != nil
+}
+
+func traceWroteHeaderField(trace *clientTrace, k, v string) {
+	if trace != nil && trace.WroteHeaderField != nil {
+		trace.WroteHeaderField(k, []string{v})
+	}
+}
+
+func traceGot1xxResponseFunc(trace *clientTrace) func(int, textproto.MIMEHeader) error {
+	if trace != nil {
+		return trace.Got1xxResponse
+	}
+	return nil
+}

+ 15 - 0
vendor/golang.org/x/net/http2/go17.go

@@ -18,6 +18,8 @@ type contextContext interface {
 	context.Context
 	context.Context
 }
 }
 
 
+var errCanceled = context.Canceled
+
 func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx contextContext, cancel func()) {
 func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx contextContext, cancel func()) {
 	ctx, cancel = context.WithCancel(context.Background())
 	ctx, cancel = context.WithCancel(context.Background())
 	ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr())
 	ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr())
@@ -48,6 +50,14 @@ func (t *Transport) idleConnTimeout() time.Duration {
 
 
 func setResponseUncompressed(res *http.Response) { res.Uncompressed = true }
 func setResponseUncompressed(res *http.Response) { res.Uncompressed = true }
 
 
+func traceGetConn(req *http.Request, hostPort string) {
+	trace := httptrace.ContextClientTrace(req.Context())
+	if trace == nil || trace.GetConn == nil {
+		return
+	}
+	trace.GetConn(hostPort)
+}
+
 func traceGotConn(req *http.Request, cc *ClientConn) {
 func traceGotConn(req *http.Request, cc *ClientConn) {
 	trace := httptrace.ContextClientTrace(req.Context())
 	trace := httptrace.ContextClientTrace(req.Context())
 	if trace == nil || trace.GotConn == nil {
 	if trace == nil || trace.GotConn == nil {
@@ -104,3 +114,8 @@ func requestTrace(req *http.Request) *clientTrace {
 func (cc *ClientConn) Ping(ctx context.Context) error {
 func (cc *ClientConn) Ping(ctx context.Context) error {
 	return cc.ping(ctx)
 	return cc.ping(ctx)
 }
 }
+
+// Shutdown gracefully closes the client connection, waiting for running streams to complete.
+func (cc *ClientConn) Shutdown(ctx context.Context) error {
+	return cc.shutdown(ctx)
+}

+ 15 - 5
vendor/golang.org/x/net/http2/headermap.go

@@ -7,15 +7,21 @@ package http2
 import (
 import (
 	"net/http"
 	"net/http"
 	"strings"
 	"strings"
+	"sync"
 )
 )
 
 
 var (
 var (
-	commonLowerHeader = map[string]string{} // Go-Canonical-Case -> lower-case
-	commonCanonHeader = map[string]string{} // lower-case -> Go-Canonical-Case
+	commonBuildOnce   sync.Once
+	commonLowerHeader map[string]string // Go-Canonical-Case -> lower-case
+	commonCanonHeader map[string]string // lower-case -> Go-Canonical-Case
 )
 )
 
 
-func init() {
-	for _, v := range []string{
+func buildCommonHeaderMapsOnce() {
+	commonBuildOnce.Do(buildCommonHeaderMaps)
+}
+
+func buildCommonHeaderMaps() {
+	common := []string{
 		"accept",
 		"accept",
 		"accept-charset",
 		"accept-charset",
 		"accept-encoding",
 		"accept-encoding",
@@ -63,7 +69,10 @@ func init() {
 		"vary",
 		"vary",
 		"via",
 		"via",
 		"www-authenticate",
 		"www-authenticate",
-	} {
+	}
+	commonLowerHeader = make(map[string]string, len(common))
+	commonCanonHeader = make(map[string]string, len(common))
+	for _, v := range common {
 		chk := http.CanonicalHeaderKey(v)
 		chk := http.CanonicalHeaderKey(v)
 		commonLowerHeader[chk] = v
 		commonLowerHeader[chk] = v
 		commonCanonHeader[v] = chk
 		commonCanonHeader[v] = chk
@@ -71,6 +80,7 @@ func init() {
 }
 }
 
 
 func lowerHeader(v string) string {
 func lowerHeader(v string) string {
+	buildCommonHeaderMapsOnce()
 	if s, ok := commonLowerHeader[v]; ok {
 	if s, ok := commonLowerHeader[v]; ok {
 		return s
 		return s
 	}
 	}

+ 1 - 1
vendor/golang.org/x/net/http2/hpack/encode.go

@@ -206,7 +206,7 @@ func appendVarInt(dst []byte, n byte, i uint64) []byte {
 }
 }
 
 
 // appendHpackString appends s, as encoded in "String Literal"
 // appendHpackString appends s, as encoded in "String Literal"
-// representation, to dst and returns the the extended buffer.
+// representation, to dst and returns the extended buffer.
 //
 //
 // s will be encoded in Huffman codes only when it produces strictly
 // s will be encoded in Huffman codes only when it produces strictly
 // shorter byte string.
 // shorter byte string.

+ 6 - 0
vendor/golang.org/x/net/http2/hpack/hpack.go

@@ -389,6 +389,12 @@ func (d *Decoder) callEmit(hf HeaderField) error {
 
 
 // (same invariants and behavior as parseHeaderFieldRepr)
 // (same invariants and behavior as parseHeaderFieldRepr)
 func (d *Decoder) parseDynamicTableSizeUpdate() error {
 func (d *Decoder) parseDynamicTableSizeUpdate() error {
+	// RFC 7541, sec 4.2: This dynamic table size update MUST occur at the
+	// beginning of the first header block following the change to the dynamic table size.
+	if d.dynTab.size > 0 {
+		return DecodingError{errors.New("dynamic table size update MUST occur at the beginning of a header block")}
+	}
+
 	buf := d.buf
 	buf := d.buf
 	size, buf, err := readVarInt(5, buf)
 	size, buf, err := readVarInt(5, buf)
 	if err != nil {
 	if err != nil {

+ 15 - 5
vendor/golang.org/x/net/http2/hpack/huffman.go

@@ -47,6 +47,7 @@ var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data")
 // If maxLen is greater than 0, attempts to write more to buf than
 // If maxLen is greater than 0, attempts to write more to buf than
 // maxLen bytes will return ErrStringLength.
 // maxLen bytes will return ErrStringLength.
 func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
 func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
+	rootHuffmanNode := getRootHuffmanNode()
 	n := rootHuffmanNode
 	n := rootHuffmanNode
 	// cur is the bit buffer that has not been fed into n.
 	// cur is the bit buffer that has not been fed into n.
 	// cbits is the number of low order bits in cur that are valid.
 	// cbits is the number of low order bits in cur that are valid.
@@ -106,7 +107,7 @@ func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
 
 
 type node struct {
 type node struct {
 	// children is non-nil for internal nodes
 	// children is non-nil for internal nodes
-	children []*node
+	children *[256]*node
 
 
 	// The following are only valid if children is nil:
 	// The following are only valid if children is nil:
 	codeLen uint8 // number of bits that led to the output of sym
 	codeLen uint8 // number of bits that led to the output of sym
@@ -114,22 +115,31 @@ type node struct {
 }
 }
 
 
 func newInternalNode() *node {
 func newInternalNode() *node {
-	return &node{children: make([]*node, 256)}
+	return &node{children: new([256]*node)}
 }
 }
 
 
-var rootHuffmanNode = newInternalNode()
+var (
+	buildRootOnce       sync.Once
+	lazyRootHuffmanNode *node
+)
+
+func getRootHuffmanNode() *node {
+	buildRootOnce.Do(buildRootHuffmanNode)
+	return lazyRootHuffmanNode
+}
 
 
-func init() {
+func buildRootHuffmanNode() {
 	if len(huffmanCodes) != 256 {
 	if len(huffmanCodes) != 256 {
 		panic("unexpected size")
 		panic("unexpected size")
 	}
 	}
+	lazyRootHuffmanNode = newInternalNode()
 	for i, code := range huffmanCodes {
 	for i, code := range huffmanCodes {
 		addDecoderNode(byte(i), code, huffmanCodeLen[i])
 		addDecoderNode(byte(i), code, huffmanCodeLen[i])
 	}
 	}
 }
 }
 
 
 func addDecoderNode(sym byte, code uint32, codeLen uint8) {
 func addDecoderNode(sym byte, code uint32, codeLen uint8) {
-	cur := rootHuffmanNode
+	cur := lazyRootHuffmanNode
 	for codeLen > 8 {
 	for codeLen > 8 {
 		codeLen -= 8
 		codeLen -= 8
 		i := uint8(code >> codeLen)
 		i := uint8(code >> codeLen)

+ 9 - 16
vendor/golang.org/x/net/http2/http2.go

@@ -29,7 +29,7 @@ import (
 	"strings"
 	"strings"
 	"sync"
 	"sync"
 
 
-	"golang.org/x/net/lex/httplex"
+	"golang.org/x/net/http/httpguts"
 )
 )
 
 
 var (
 var (
@@ -179,7 +179,7 @@ var (
 )
 )
 
 
 // validWireHeaderFieldName reports whether v is a valid header field
 // validWireHeaderFieldName reports whether v is a valid header field
-// name (key). See httplex.ValidHeaderName for the base rules.
+// name (key). See httpguts.ValidHeaderName for the base rules.
 //
 //
 // Further, http2 says:
 // Further, http2 says:
 //   "Just as in HTTP/1.x, header field names are strings of ASCII
 //   "Just as in HTTP/1.x, header field names are strings of ASCII
@@ -191,7 +191,7 @@ func validWireHeaderFieldName(v string) bool {
 		return false
 		return false
 	}
 	}
 	for _, r := range v {
 	for _, r := range v {
-		if !httplex.IsTokenRune(r) {
+		if !httpguts.IsTokenRune(r) {
 			return false
 			return false
 		}
 		}
 		if 'A' <= r && r <= 'Z' {
 		if 'A' <= r && r <= 'Z' {
@@ -201,19 +201,12 @@ func validWireHeaderFieldName(v string) bool {
 	return true
 	return true
 }
 }
 
 
-var httpCodeStringCommon = map[int]string{} // n -> strconv.Itoa(n)
-
-func init() {
-	for i := 100; i <= 999; i++ {
-		if v := http.StatusText(i); v != "" {
-			httpCodeStringCommon[i] = strconv.Itoa(i)
-		}
-	}
-}
-
 func httpCodeString(code int) string {
 func httpCodeString(code int) string {
-	if s, ok := httpCodeStringCommon[code]; ok {
-		return s
+	switch code {
+	case 200:
+		return "200"
+	case 404:
+		return "404"
 	}
 	}
 	return strconv.Itoa(code)
 	return strconv.Itoa(code)
 }
 }
@@ -312,7 +305,7 @@ func mustUint31(v int32) uint32 {
 }
 }
 
 
 // bodyAllowedForStatus reports whether a given response status code
 // bodyAllowedForStatus reports whether a given response status code
-// permits a body. See RFC 2616, section 4.4.
+// permits a body. See RFC 7230, section 3.3.
 func bodyAllowedForStatus(status int) bool {
 func bodyAllowedForStatus(status int) bool {
 	switch {
 	switch {
 	case status >= 100 && status <= 199:
 	case status >= 100 && status <= 199:

+ 17 - 0
vendor/golang.org/x/net/http2/not_go111.go

@@ -0,0 +1,17 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.11
+
+package http2
+
+import "net/textproto"
+
+func traceHasWroteHeaderField(trace *clientTrace) bool { return false }
+
+func traceWroteHeaderField(trace *clientTrace, k, v string) {}
+
+func traceGot1xxResponseFunc(trace *clientTrace) func(int, textproto.MIMEHeader) error {
+	return nil
+}

+ 8 - 0
vendor/golang.org/x/net/http2/not_go17.go

@@ -8,6 +8,7 @@ package http2
 
 
 import (
 import (
 	"crypto/tls"
 	"crypto/tls"
+	"errors"
 	"net"
 	"net"
 	"net/http"
 	"net/http"
 	"time"
 	"time"
@@ -18,6 +19,8 @@ type contextContext interface {
 	Err() error
 	Err() error
 }
 }
 
 
+var errCanceled = errors.New("canceled")
+
 type fakeContext struct{}
 type fakeContext struct{}
 
 
 func (fakeContext) Done() <-chan struct{} { return nil }
 func (fakeContext) Done() <-chan struct{} { return nil }
@@ -34,6 +37,7 @@ func setResponseUncompressed(res *http.Response) {
 type clientTrace struct{}
 type clientTrace struct{}
 
 
 func requestTrace(*http.Request) *clientTrace { return nil }
 func requestTrace(*http.Request) *clientTrace { return nil }
+func traceGetConn(*http.Request, string)      {}
 func traceGotConn(*http.Request, *ClientConn) {}
 func traceGotConn(*http.Request, *ClientConn) {}
 func traceFirstResponseByte(*clientTrace)     {}
 func traceFirstResponseByte(*clientTrace)     {}
 func traceWroteHeaders(*clientTrace)          {}
 func traceWroteHeaders(*clientTrace)          {}
@@ -84,4 +88,8 @@ func (cc *ClientConn) Ping(ctx contextContext) error {
 	return cc.ping(ctx)
 	return cc.ping(ctx)
 }
 }
 
 
+func (cc *ClientConn) Shutdown(ctx contextContext) error {
+	return cc.shutdown(ctx)
+}
+
 func (t *Transport) idleConnTimeout() time.Duration { return 0 }
 func (t *Transport) idleConnTimeout() time.Duration { return 0 }

+ 102 - 69
vendor/golang.org/x/net/http2/server.go

@@ -46,6 +46,7 @@ import (
 	"sync"
 	"sync"
 	"time"
 	"time"
 
 
+	"golang.org/x/net/http/httpguts"
 	"golang.org/x/net/http2/hpack"
 	"golang.org/x/net/http2/hpack"
 )
 )
 
 
@@ -220,12 +221,15 @@ func ConfigureServer(s *http.Server, conf *Server) error {
 	} else if s.TLSConfig.CipherSuites != nil {
 	} else if s.TLSConfig.CipherSuites != nil {
 		// If they already provided a CipherSuite list, return
 		// If they already provided a CipherSuite list, return
 		// an error if it has a bad order or is missing
 		// an error if it has a bad order or is missing
-		// ECDHE_RSA_WITH_AES_128_GCM_SHA256.
-		const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+		// ECDHE_RSA_WITH_AES_128_GCM_SHA256 or ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.
 		haveRequired := false
 		haveRequired := false
 		sawBad := false
 		sawBad := false
 		for i, cs := range s.TLSConfig.CipherSuites {
 		for i, cs := range s.TLSConfig.CipherSuites {
-			if cs == requiredCipher {
+			switch cs {
+			case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+				// Alternative MTI cipher to not discourage ECDSA-only servers.
+				// See http://golang.org/cl/30721 for further information.
+				tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
 				haveRequired = true
 				haveRequired = true
 			}
 			}
 			if isBadCipher(cs) {
 			if isBadCipher(cs) {
@@ -235,7 +239,7 @@ func ConfigureServer(s *http.Server, conf *Server) error {
 			}
 			}
 		}
 		}
 		if !haveRequired {
 		if !haveRequired {
-			return fmt.Errorf("http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
+			return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher.")
 		}
 		}
 	}
 	}
 
 
@@ -403,7 +407,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
 			// addresses during development.
 			// addresses during development.
 			//
 			//
 			// TODO: optionally enforce? Or enforce at the time we receive
 			// TODO: optionally enforce? Or enforce at the time we receive
-			// a new request, and verify the the ServerName matches the :authority?
+			// a new request, and verify the ServerName matches the :authority?
 			// But that precludes proxy situations, perhaps.
 			// But that precludes proxy situations, perhaps.
 			//
 			//
 			// So for now, do nothing here again.
 			// So for now, do nothing here again.
@@ -649,7 +653,7 @@ func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
 	if err == nil {
 	if err == nil {
 		return
 		return
 	}
 	}
-	if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) {
+	if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) || err == errPrefaceTimeout {
 		// Boring, expected errors.
 		// Boring, expected errors.
 		sc.vlogf(format, args...)
 		sc.vlogf(format, args...)
 	} else {
 	} else {
@@ -659,6 +663,7 @@ func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
 
 
 func (sc *serverConn) canonicalHeader(v string) string {
 func (sc *serverConn) canonicalHeader(v string) string {
 	sc.serveG.check()
 	sc.serveG.check()
+	buildCommonHeaderMapsOnce()
 	cv, ok := commonCanonHeader[v]
 	cv, ok := commonCanonHeader[v]
 	if ok {
 	if ok {
 		return cv
 		return cv
@@ -853,8 +858,13 @@ func (sc *serverConn) serve() {
 			}
 			}
 		}
 		}
 
 
-		if sc.inGoAway && sc.curOpenStreams() == 0 && !sc.needToSendGoAway && !sc.writingFrame {
-			return
+		// Start the shutdown timer after sending a GOAWAY. When sending GOAWAY
+		// with no error code (graceful shutdown), don't start the timer until
+		// all open streams have been completed.
+		sentGoAway := sc.inGoAway && !sc.needToSendGoAway && !sc.writingFrame
+		gracefulShutdownComplete := sc.goAwayCode == ErrCodeNo && sc.curOpenStreams() == 0
+		if sentGoAway && sc.shutdownTimer == nil && (sc.goAwayCode != ErrCodeNo || gracefulShutdownComplete) {
+			sc.shutDownIn(goAwayTimeout)
 		}
 		}
 	}
 	}
 }
 }
@@ -889,8 +899,11 @@ func (sc *serverConn) sendServeMsg(msg interface{}) {
 	}
 	}
 }
 }
 
 
-// readPreface reads the ClientPreface greeting from the peer
-// or returns an error on timeout or an invalid greeting.
+var errPrefaceTimeout = errors.New("timeout waiting for client preface")
+
+// readPreface reads the ClientPreface greeting from the peer or
+// returns errPrefaceTimeout on timeout, or an error if the greeting
+// is invalid.
 func (sc *serverConn) readPreface() error {
 func (sc *serverConn) readPreface() error {
 	errc := make(chan error, 1)
 	errc := make(chan error, 1)
 	go func() {
 	go func() {
@@ -908,7 +921,7 @@ func (sc *serverConn) readPreface() error {
 	defer timer.Stop()
 	defer timer.Stop()
 	select {
 	select {
 	case <-timer.C:
 	case <-timer.C:
-		return errors.New("timeout waiting for client preface")
+		return errPrefaceTimeout
 	case err := <-errc:
 	case err := <-errc:
 		if err == nil {
 		if err == nil {
 			if VerboseLogs {
 			if VerboseLogs {
@@ -1218,30 +1231,31 @@ func (sc *serverConn) startGracefulShutdown() {
 	sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) })
 	sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) })
 }
 }
 
 
+// After sending GOAWAY, the connection will close after goAwayTimeout.
+// If we close the connection immediately after sending GOAWAY, there may
+// be unsent data in our kernel receive buffer, which will cause the kernel
+// to send a TCP RST on close() instead of a FIN. This RST will abort the
+// connection immediately, whether or not the client had received the GOAWAY.
+//
+// Ideally we should delay for at least 1 RTT + epsilon so the client has
+// a chance to read the GOAWAY and stop sending messages. Measuring RTT
+// is hard, so we approximate with 1 second. See golang.org/issue/18701.
+//
+// This is a var so it can be shorter in tests, where all requests uses the
+// loopback interface making the expected RTT very small.
+//
+// TODO: configurable?
+var goAwayTimeout = 1 * time.Second
+
 func (sc *serverConn) startGracefulShutdownInternal() {
 func (sc *serverConn) startGracefulShutdownInternal() {
-	sc.goAwayIn(ErrCodeNo, 0)
+	sc.goAway(ErrCodeNo)
 }
 }
 
 
 func (sc *serverConn) goAway(code ErrCode) {
 func (sc *serverConn) goAway(code ErrCode) {
-	sc.serveG.check()
-	var forceCloseIn time.Duration
-	if code != ErrCodeNo {
-		forceCloseIn = 250 * time.Millisecond
-	} else {
-		// TODO: configurable
-		forceCloseIn = 1 * time.Second
-	}
-	sc.goAwayIn(code, forceCloseIn)
-}
-
-func (sc *serverConn) goAwayIn(code ErrCode, forceCloseIn time.Duration) {
 	sc.serveG.check()
 	sc.serveG.check()
 	if sc.inGoAway {
 	if sc.inGoAway {
 		return
 		return
 	}
 	}
-	if forceCloseIn != 0 {
-		sc.shutDownIn(forceCloseIn)
-	}
 	sc.inGoAway = true
 	sc.inGoAway = true
 	sc.needToSendGoAway = true
 	sc.needToSendGoAway = true
 	sc.goAwayCode = code
 	sc.goAwayCode = code
@@ -1474,6 +1488,12 @@ func (sc *serverConn) processSettings(f *SettingsFrame) error {
 		}
 		}
 		return nil
 		return nil
 	}
 	}
+	if f.NumSettings() > 100 || f.HasDuplicates() {
+		// This isn't actually in the spec, but hang up on
+		// suspiciously large settings frames or those with
+		// duplicate entries.
+		return ConnectionError(ErrCodeProtocol)
+	}
 	if err := f.ForeachSetting(sc.processSetting); err != nil {
 	if err := f.ForeachSetting(sc.processSetting); err != nil {
 		return err
 		return err
 	}
 	}
@@ -1562,6 +1582,12 @@ func (sc *serverConn) processData(f *DataFrame) error {
 		// type PROTOCOL_ERROR."
 		// type PROTOCOL_ERROR."
 		return ConnectionError(ErrCodeProtocol)
 		return ConnectionError(ErrCodeProtocol)
 	}
 	}
+	// RFC 7540, sec 6.1: If a DATA frame is received whose stream is not in
+	// "open" or "half-closed (local)" state, the recipient MUST respond with a
+	// stream error (Section 5.4.2) of type STREAM_CLOSED.
+	if state == stateClosed {
+		return streamError(id, ErrCodeStreamClosed)
+	}
 	if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued {
 	if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued {
 		// This includes sending a RST_STREAM if the stream is
 		// This includes sending a RST_STREAM if the stream is
 		// in stateHalfClosedLocal (which currently means that
 		// in stateHalfClosedLocal (which currently means that
@@ -1595,7 +1621,10 @@ func (sc *serverConn) processData(f *DataFrame) error {
 	// Sender sending more than they'd declared?
 	// Sender sending more than they'd declared?
 	if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
 	if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
 		st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
 		st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
-		return streamError(id, ErrCodeStreamClosed)
+		// RFC 7540, sec 8.1.2.6: A request or response is also malformed if the
+		// value of a content-length header field does not equal the sum of the
+		// DATA frame payload lengths that form the body.
+		return streamError(id, ErrCodeProtocol)
 	}
 	}
 	if f.Length > 0 {
 	if f.Length > 0 {
 		// Check whether the client has flow control quota.
 		// Check whether the client has flow control quota.
@@ -1705,6 +1734,13 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
 			// processing this frame.
 			// processing this frame.
 			return nil
 			return nil
 		}
 		}
+		// RFC 7540, sec 5.1: If an endpoint receives additional frames, other than
+		// WINDOW_UPDATE, PRIORITY, or RST_STREAM, for a stream that is in
+		// this state, it MUST respond with a stream error (Section 5.4.2) of
+		// type STREAM_CLOSED.
+		if st.state == stateHalfClosedRemote {
+			return streamError(id, ErrCodeStreamClosed)
+		}
 		return st.processTrailerHeaders(f)
 		return st.processTrailerHeaders(f)
 	}
 	}
 
 
@@ -1805,7 +1841,7 @@ func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
 	if st.trailer != nil {
 	if st.trailer != nil {
 		for _, hf := range f.RegularFields() {
 		for _, hf := range f.RegularFields() {
 			key := sc.canonicalHeader(hf.Name)
 			key := sc.canonicalHeader(hf.Name)
-			if !ValidTrailerHeader(key) {
+			if !httpguts.ValidTrailerHeader(key) {
 				// TODO: send more details to the peer somehow. But http2 has
 				// TODO: send more details to the peer somehow. But http2 has
 				// no way to send debug data at a stream level. Discuss with
 				// no way to send debug data at a stream level. Discuss with
 				// HTTP folk.
 				// HTTP folk.
@@ -2272,8 +2308,8 @@ func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) !=
 // written in the trailers at the end of the response.
 // written in the trailers at the end of the response.
 func (rws *responseWriterState) declareTrailer(k string) {
 func (rws *responseWriterState) declareTrailer(k string) {
 	k = http.CanonicalHeaderKey(k)
 	k = http.CanonicalHeaderKey(k)
-	if !ValidTrailerHeader(k) {
-		// Forbidden by RFC 2616 14.40.
+	if !httpguts.ValidTrailerHeader(k) {
+		// Forbidden by RFC 7230, section 4.1.2.
 		rws.conn.logf("ignoring invalid trailer %q", k)
 		rws.conn.logf("ignoring invalid trailer %q", k)
 		return
 		return
 	}
 	}
@@ -2310,7 +2346,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
 			clen = strconv.Itoa(len(p))
 			clen = strconv.Itoa(len(p))
 		}
 		}
 		_, hasContentType := rws.snapHeader["Content-Type"]
 		_, hasContentType := rws.snapHeader["Content-Type"]
-		if !hasContentType && bodyAllowedForStatus(rws.status) {
+		if !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 {
 			ctype = http.DetectContentType(p)
 			ctype = http.DetectContentType(p)
 		}
 		}
 		var date string
 		var date string
@@ -2323,6 +2359,19 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
 			foreachHeaderElement(v, rws.declareTrailer)
 			foreachHeaderElement(v, rws.declareTrailer)
 		}
 		}
 
 
+		// "Connection" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2),
+		// but respect "Connection" == "close" to mean sending a GOAWAY and tearing
+		// down the TCP connection when idle, like we do for HTTP/1.
+		// TODO: remove more Connection-specific header fields here, in addition
+		// to "Connection".
+		if _, ok := rws.snapHeader["Connection"]; ok {
+			v := rws.snapHeader.Get("Connection")
+			delete(rws.snapHeader, "Connection")
+			if v == "close" {
+				rws.conn.startGracefulShutdown()
+			}
+		}
+
 		endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
 		endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
 		err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
 		err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
 			streamID:      rws.stream.id,
 			streamID:      rws.stream.id,
@@ -2394,7 +2443,7 @@ const TrailerPrefix = "Trailer:"
 // after the header has already been flushed. Because the Go
 // after the header has already been flushed. Because the Go
 // ResponseWriter interface has no way to set Trailers (only the
 // ResponseWriter interface has no way to set Trailers (only the
 // Header), and because we didn't want to expand the ResponseWriter
 // Header), and because we didn't want to expand the ResponseWriter
-// interface, and because nobody used trailers, and because RFC 2616
+// interface, and because nobody used trailers, and because RFC 7230
 // says you SHOULD (but not must) predeclare any trailers in the
 // says you SHOULD (but not must) predeclare any trailers in the
 // header, the official ResponseWriter rules said trailers in Go must
 // header, the official ResponseWriter rules said trailers in Go must
 // be predeclared, and then we reuse the same ResponseWriter.Header()
 // be predeclared, and then we reuse the same ResponseWriter.Header()
@@ -2478,6 +2527,24 @@ func (w *responseWriter) Header() http.Header {
 	return rws.handlerHeader
 	return rws.handlerHeader
 }
 }
 
 
+// checkWriteHeaderCode is a copy of net/http's checkWriteHeaderCode.
+func checkWriteHeaderCode(code int) {
+	// Issue 22880: require valid WriteHeader status codes.
+	// For now we only enforce that it's three digits.
+	// In the future we might block things over 599 (600 and above aren't defined
+	// at http://httpwg.org/specs/rfc7231.html#status.codes)
+	// and we might block under 200 (once we have more mature 1xx support).
+	// But for now any three digits.
+	//
+	// We used to send "HTTP/1.1 000 0" on the wire in responses but there's
+	// no equivalent bogus thing we can realistically send in HTTP/2,
+	// so we'll consistently panic instead and help people find their bugs
+	// early. (We can't return an error from WriteHeader even if we wanted to.)
+	if code < 100 || code > 999 {
+		panic(fmt.Sprintf("invalid WriteHeader code %v", code))
+	}
+}
+
 func (w *responseWriter) WriteHeader(code int) {
 func (w *responseWriter) WriteHeader(code int) {
 	rws := w.rws
 	rws := w.rws
 	if rws == nil {
 	if rws == nil {
@@ -2488,6 +2555,7 @@ func (w *responseWriter) WriteHeader(code int) {
 
 
 func (rws *responseWriterState) writeHeader(code int) {
 func (rws *responseWriterState) writeHeader(code int) {
 	if !rws.wroteHeader {
 	if !rws.wroteHeader {
+		checkWriteHeaderCode(code)
 		rws.wroteHeader = true
 		rws.wroteHeader = true
 		rws.status = code
 		rws.status = code
 		if len(rws.handlerHeader) > 0 {
 		if len(rws.handlerHeader) > 0 {
@@ -2759,7 +2827,7 @@ func (sc *serverConn) startPush(msg *startPushRequest) {
 }
 }
 
 
 // foreachHeaderElement splits v according to the "#rule" construction
 // foreachHeaderElement splits v according to the "#rule" construction
-// in RFC 2616 section 2.1 and calls fn for each non-empty element.
+// in RFC 7230 section 7 and calls fn for each non-empty element.
 func foreachHeaderElement(v string, fn func(string)) {
 func foreachHeaderElement(v string, fn func(string)) {
 	v = textproto.TrimString(v)
 	v = textproto.TrimString(v)
 	if v == "" {
 	if v == "" {
@@ -2807,41 +2875,6 @@ func new400Handler(err error) http.HandlerFunc {
 	}
 	}
 }
 }
 
 
-// ValidTrailerHeader reports whether name is a valid header field name to appear
-// in trailers.
-// See: http://tools.ietf.org/html/rfc7230#section-4.1.2
-func ValidTrailerHeader(name string) bool {
-	name = http.CanonicalHeaderKey(name)
-	if strings.HasPrefix(name, "If-") || badTrailer[name] {
-		return false
-	}
-	return true
-}
-
-var badTrailer = map[string]bool{
-	"Authorization":       true,
-	"Cache-Control":       true,
-	"Connection":          true,
-	"Content-Encoding":    true,
-	"Content-Length":      true,
-	"Content-Range":       true,
-	"Content-Type":        true,
-	"Expect":              true,
-	"Host":                true,
-	"Keep-Alive":          true,
-	"Max-Forwards":        true,
-	"Pragma":              true,
-	"Proxy-Authenticate":  true,
-	"Proxy-Authorization": true,
-	"Proxy-Connection":    true,
-	"Range":               true,
-	"Realm":               true,
-	"Te":                  true,
-	"Trailer":             true,
-	"Transfer-Encoding":   true,
-	"Www-Authenticate":    true,
-}
-
 // h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
 // h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
 // disabled. See comments on h1ServerShutdownChan above for why
 // disabled. See comments on h1ServerShutdownChan above for why
 // the code is written this way.
 // the code is written this way.

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 458 - 166
vendor/golang.org/x/net/http2/transport.go


+ 3 - 8
vendor/golang.org/x/net/http2/write.go

@@ -10,10 +10,9 @@ import (
 	"log"
 	"log"
 	"net/http"
 	"net/http"
 	"net/url"
 	"net/url"
-	"time"
 
 
+	"golang.org/x/net/http/httpguts"
 	"golang.org/x/net/http2/hpack"
 	"golang.org/x/net/http2/hpack"
-	"golang.org/x/net/lex/httplex"
 )
 )
 
 
 // writeFramer is implemented by any type that is used to write frames.
 // writeFramer is implemented by any type that is used to write frames.
@@ -90,11 +89,7 @@ type writeGoAway struct {
 
 
 func (p *writeGoAway) writeFrame(ctx writeContext) error {
 func (p *writeGoAway) writeFrame(ctx writeContext) error {
 	err := ctx.Framer().WriteGoAway(p.maxStreamID, p.code, nil)
 	err := ctx.Framer().WriteGoAway(p.maxStreamID, p.code, nil)
-	if p.code != 0 {
-		ctx.Flush() // ignore error: we're hanging up on them anyway
-		time.Sleep(50 * time.Millisecond)
-		ctx.CloseConn()
-	}
+	ctx.Flush() // ignore error: we're hanging up on them anyway
 	return err
 	return err
 }
 }
 
 
@@ -355,7 +350,7 @@ func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
 		}
 		}
 		isTE := k == "transfer-encoding"
 		isTE := k == "transfer-encoding"
 		for _, v := range vv {
 		for _, v := range vv {
-			if !httplex.ValidHeaderFieldValue(v) {
+			if !httpguts.ValidHeaderFieldValue(v) {
 				// TODO: return an error? golang.org/issue/14048
 				// TODO: return an error? golang.org/issue/14048
 				// For now just omit it.
 				// For now just omit it.
 				continue
 				continue

+ 35 - 31
vendor/vendor.json

@@ -273,10 +273,10 @@
 			"revisionTime": "2017-10-27T16:34:21Z"
 			"revisionTime": "2017-10-27T16:34:21Z"
 		},
 		},
 		{
 		{
-			"checksumSHA1": "FUvpp4RI9ZqYdH46mt1bjojuuo0=",
+			"checksumSHA1": "cqsGwyZE3NAuWLn5lEBrZc99ZKc=",
 			"path": "github.com/lucas-clemente/quic-go",
 			"path": "github.com/lucas-clemente/quic-go",
-			"revision": "4d2d2420a4389e2af24d96337feff51951839b22",
-			"revisionTime": "2018-08-20T11:33:42Z"
+			"revision": "ffdfa1f6760a75b2f919eb495fd99aa5ff1c6ad1",
+			"revisionTime": "2018-08-28T08:02:33Z"
 		},
 		},
 		{
 		{
 			"checksumSHA1": "OA9E+y7g05x/mWJJHmA7oPxWKQo=",
 			"checksumSHA1": "OA9E+y7g05x/mWJJHmA7oPxWKQo=",
@@ -287,56 +287,56 @@
 		{
 		{
 			"checksumSHA1": "xofp3Exz+2Bna8U2fSFil8aeNK4=",
 			"checksumSHA1": "xofp3Exz+2Bna8U2fSFil8aeNK4=",
 			"path": "github.com/lucas-clemente/quic-go/internal/ackhandler",
 			"path": "github.com/lucas-clemente/quic-go/internal/ackhandler",
-			"revision": "4d2d2420a4389e2af24d96337feff51951839b22",
-			"revisionTime": "2018-08-20T11:33:42Z"
+			"revision": "ffdfa1f6760a75b2f919eb495fd99aa5ff1c6ad1",
+			"revisionTime": "2018-08-28T08:02:33Z"
 		},
 		},
 		{
 		{
 			"checksumSHA1": "i1yfut7QQqMehw5yE9llhWNnrxk=",
 			"checksumSHA1": "i1yfut7QQqMehw5yE9llhWNnrxk=",
 			"path": "github.com/lucas-clemente/quic-go/internal/congestion",
 			"path": "github.com/lucas-clemente/quic-go/internal/congestion",
-			"revision": "4d2d2420a4389e2af24d96337feff51951839b22",
-			"revisionTime": "2018-08-20T11:33:42Z"
+			"revision": "ffdfa1f6760a75b2f919eb495fd99aa5ff1c6ad1",
+			"revisionTime": "2018-08-28T08:02:33Z"
 		},
 		},
 		{
 		{
 			"checksumSHA1": "iDyiuv67gAM4KKfl51vU3QtOFz8=",
 			"checksumSHA1": "iDyiuv67gAM4KKfl51vU3QtOFz8=",
 			"path": "github.com/lucas-clemente/quic-go/internal/crypto",
 			"path": "github.com/lucas-clemente/quic-go/internal/crypto",
-			"revision": "4d2d2420a4389e2af24d96337feff51951839b22",
-			"revisionTime": "2018-08-20T11:33:42Z"
+			"revision": "ffdfa1f6760a75b2f919eb495fd99aa5ff1c6ad1",
+			"revisionTime": "2018-08-28T08:02:33Z"
 		},
 		},
 		{
 		{
 			"checksumSHA1": "hLazAfY6qHoV3USMxA7pSPnTqy8=",
 			"checksumSHA1": "hLazAfY6qHoV3USMxA7pSPnTqy8=",
 			"path": "github.com/lucas-clemente/quic-go/internal/flowcontrol",
 			"path": "github.com/lucas-clemente/quic-go/internal/flowcontrol",
-			"revision": "4d2d2420a4389e2af24d96337feff51951839b22",
-			"revisionTime": "2018-08-20T11:33:42Z"
+			"revision": "ffdfa1f6760a75b2f919eb495fd99aa5ff1c6ad1",
+			"revisionTime": "2018-08-28T08:02:33Z"
 		},
 		},
 		{
 		{
 			"checksumSHA1": "1EPOPYxoK/ZVqB91d7329CMSsE8=",
 			"checksumSHA1": "1EPOPYxoK/ZVqB91d7329CMSsE8=",
 			"path": "github.com/lucas-clemente/quic-go/internal/handshake",
 			"path": "github.com/lucas-clemente/quic-go/internal/handshake",
-			"revision": "4d2d2420a4389e2af24d96337feff51951839b22",
-			"revisionTime": "2018-08-20T11:33:42Z"
+			"revision": "ffdfa1f6760a75b2f919eb495fd99aa5ff1c6ad1",
+			"revisionTime": "2018-08-28T08:02:33Z"
 		},
 		},
 		{
 		{
-			"checksumSHA1": "vh1QIciVIx9N+0C7J4hQfdAW4iY=",
+			"checksumSHA1": "jG7h6FwuKQgXQI+pgymjud5m3Co=",
 			"path": "github.com/lucas-clemente/quic-go/internal/protocol",
 			"path": "github.com/lucas-clemente/quic-go/internal/protocol",
-			"revision": "4d2d2420a4389e2af24d96337feff51951839b22",
-			"revisionTime": "2018-08-20T11:33:42Z"
+			"revision": "ffdfa1f6760a75b2f919eb495fd99aa5ff1c6ad1",
+			"revisionTime": "2018-08-28T08:02:33Z"
 		},
 		},
 		{
 		{
 			"checksumSHA1": "0vSbWIQ7O34u4kDMR+FHr7/FINk=",
 			"checksumSHA1": "0vSbWIQ7O34u4kDMR+FHr7/FINk=",
 			"path": "github.com/lucas-clemente/quic-go/internal/utils",
 			"path": "github.com/lucas-clemente/quic-go/internal/utils",
-			"revision": "4d2d2420a4389e2af24d96337feff51951839b22",
-			"revisionTime": "2018-08-20T11:33:42Z"
+			"revision": "ffdfa1f6760a75b2f919eb495fd99aa5ff1c6ad1",
+			"revisionTime": "2018-08-28T08:02:33Z"
 		},
 		},
 		{
 		{
-			"checksumSHA1": "bBhsaiBWBOUTXJoj2Rju7Q8BXnU=",
+			"checksumSHA1": "KCuro1tWjpbE8Xj91Fl1H2i4Ekw=",
 			"path": "github.com/lucas-clemente/quic-go/internal/wire",
 			"path": "github.com/lucas-clemente/quic-go/internal/wire",
-			"revision": "4d2d2420a4389e2af24d96337feff51951839b22",
-			"revisionTime": "2018-08-20T11:33:42Z"
+			"revision": "ffdfa1f6760a75b2f919eb495fd99aa5ff1c6ad1",
+			"revisionTime": "2018-08-28T08:02:33Z"
 		},
 		},
 		{
 		{
 			"checksumSHA1": "bFSC4TOZGOZGBJEFmLAT3V4ieoo=",
 			"checksumSHA1": "bFSC4TOZGOZGBJEFmLAT3V4ieoo=",
 			"path": "github.com/lucas-clemente/quic-go/qerr",
 			"path": "github.com/lucas-clemente/quic-go/qerr",
-			"revision": "4d2d2420a4389e2af24d96337feff51951839b22",
-			"revisionTime": "2018-08-20T11:33:42Z"
+			"revision": "ffdfa1f6760a75b2f919eb495fd99aa5ff1c6ad1",
+			"revisionTime": "2018-08-28T08:02:33Z"
 		},
 		},
 		{
 		{
 			"checksumSHA1": "sY8sshVIEXnJgg3S6C5FcN33Vq4=",
 			"checksumSHA1": "sY8sshVIEXnJgg3S6C5FcN33Vq4=",
@@ -616,19 +616,23 @@
 			"revisionTime": "2018-05-30T06:29:46Z"
 			"revisionTime": "2018-05-30T06:29:46Z"
 		},
 		},
 		{
 		{
-			"checksumSHA1": "kKuxyoDujo5CopTxAvvZ1rrLdd0=",
+			"checksumSHA1": "pCY4YtdNKVBYRbNvODjx8hj0hIs=",
+			"path": "golang.org/x/net/http/httpguts",
+			"revision": "8a410e7b638dca158bf9e766925842f6651ff828",
+			"revisionTime": "2018-08-25T16:15:26Z"
+		},
+		{
+			"checksumSHA1": "3p4xISa2iLZULxYfVsIUlHJ+PUk=",
 			"path": "golang.org/x/net/http2",
 			"path": "golang.org/x/net/http2",
-			"revision": "ab5485076ff3407ad2d02db054635913f017b0ed",
-			"revisionTime": "2017-07-19T21:11:51Z",
-			"version": "=release-branch.go1.9",
+			"revision": "8a410e7b638dca158bf9e766925842f6651ff828",
+			"revisionTime": "2018-08-25T16:15:26Z",
 			"versionExact": "release-branch.go1.9"
 			"versionExact": "release-branch.go1.9"
 		},
 		},
 		{
 		{
-			"checksumSHA1": "ezWhc7n/FtqkLDQKeU2JbW+80tE=",
+			"checksumSHA1": "KZniwnfpWkaTPhUQDUTvgex/7y0=",
 			"path": "golang.org/x/net/http2/hpack",
 			"path": "golang.org/x/net/http2/hpack",
-			"revision": "ab5485076ff3407ad2d02db054635913f017b0ed",
-			"revisionTime": "2017-07-19T21:11:51Z",
-			"version": "=release-branch.go1.9",
+			"revision": "8a410e7b638dca158bf9e766925842f6651ff828",
+			"revisionTime": "2018-08-25T16:15:26Z",
 			"versionExact": "release-branch.go1.9"
 			"versionExact": "release-branch.go1.9"
 		},
 		},
 		{
 		{

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio