diff --git a/controller/api/destination/endpoint_translator.go b/controller/api/destination/endpoint_translator.go index 803a8fd8af167..c3d04a802a3ce 100644 --- a/controller/api/destination/endpoint_translator.go +++ b/controller/api/destination/endpoint_translator.go @@ -385,14 +385,10 @@ func createWeightedAddr(address watcher.Address, opaquePorts map[uint32]struct{} // translation) weightedAddr.ProtocolHint = &pb.ProtocolHint{} if controllerNSLabel != "" && !isSkippedInboundPort { - if enableH2Upgrade { - weightedAddr.ProtocolHint.Protocol = &pb.ProtocolHint_H2_{ - H2: &pb.ProtocolHint_H2{}, - } - } // If address is set as opaque by a Server, or its port is set as // opaque by annotation or default value, then hint its proxy's - // inbound port. + // inbound port, and set the hinted protocol to Opaque, so that the + // client proxy does not send a SessionProtocol. _, opaquePort := opaquePorts[address.Port] if address.OpaqueProtocol || opaquePort { port, err := getInboundPort(&address.Pod.Spec) @@ -402,6 +398,13 @@ func createWeightedAddr(address watcher.Address, opaquePorts map[uint32]struct{} weightedAddr.ProtocolHint.OpaqueTransport = &pb.ProtocolHint_OpaqueTransport{ InboundPort: port, } + weightedAddr.ProtocolHint.Protocol = &pb.ProtocolHint_Opaque_{ + Opaque: &pb.ProtocolHint_Opaque{}, + } + } + } else if enableH2Upgrade { + weightedAddr.ProtocolHint.Protocol = &pb.ProtocolHint_H2_{ + H2: &pb.ProtocolHint_H2{}, } } } diff --git a/controller/api/destination/endpoint_translator_test.go b/controller/api/destination/endpoint_translator_test.go index f2b1cc092deed..71f094bf96607 100644 --- a/controller/api/destination/endpoint_translator_test.go +++ b/controller/api/destination/endpoint_translator_test.go @@ -69,6 +69,38 @@ var ( }, } + podOpaque = watcher.Address{ + IP: "1.1.1.4", + Port: 4, + Pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod4", + Namespace: "ns", + Labels: map[string]string{ + k8s.ControllerNSLabel: "linkerd", + k8s.ProxyDeploymentLabel: "deployment-name", + }, + Annotations: map[string]string{ + k8s.ProxyOpaquePortsAnnotation: "4", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: k8s.ProxyContainerName, + Env: []corev1.EnvVar{ + { + Name: envInboundListenAddr, + Value: "0.0.0.0:4143", + }, + }, + }, + }, + }, + }, + OpaqueProtocol: true, + } + remoteGateway1 = watcher.Address{ IP: "1.1.1.1", Port: 1, @@ -340,6 +372,31 @@ func TestEndpointTranslatorForPods(t *testing.T) { t.Fatalf("Expected TlsIdentity to be [%v] but was [%v]", expectedTLSIdentity, actualTLSIdentity) } }) + + t.Run("Sends Opaque ProtocolHint for opaque ports", func(t *testing.T) { + expectedProtocolHint := &pb.ProtocolHint{ + Protocol: &pb.ProtocolHint_Opaque_{ + Opaque: &pb.ProtocolHint_Opaque{}, + }, + OpaqueTransport: &pb.ProtocolHint_OpaqueTransport{ + InboundPort: 4143, + }, + } + + mockGetServer, translator := makeEndpointTranslator(t) + + translator.Add(mkAddressSetForServices(podOpaque)) + + addrs := mockGetServer.updatesReceived[0].GetAdd().GetAddrs() + if len(addrs) != 1 { + t.Fatalf("Expected [1] address returned, got %v", addrs) + } + + actualProtocolHint := addrs[0].GetProtocolHint() + if diff := deep.Equal(actualProtocolHint, expectedProtocolHint); diff != nil { + t.Fatalf("ProtocolHint: %v", diff) + } + }) } func TestEndpointTranslatorForZonedAddresses(t *testing.T) {