From 53579ccf9fd56e3ca0efa012249e0b6fcab425df Mon Sep 17 00:00:00 2001 From: omrikiei Date: Sun, 9 Feb 2020 23:30:57 +0200 Subject: [PATCH] issued a fix for trim prefix(#13) --- cmd/expose.go | 10 +++--- cmd/inject.go | 14 ++++---- cmd/root.go | 2 +- cmd/server.go | 2 +- ktunnel.rb | 17 +++++++--- pkg/client/client.go | 14 ++++---- pkg/common/common.go | 17 +++++----- pkg/k8s/common.go | 72 +++++++++++++++++++--------------------- pkg/k8s/exposer.go | 6 ++-- pkg/k8s/injector.go | 17 +++++----- pkg/k8s/injector_test.go | 48 +++++++++++++++++---------- pkg/server/server.go | 16 ++++----- 12 files changed, 125 insertions(+), 110 deletions(-) diff --git a/cmd/expose.go b/cmd/expose.go index 8e0e1b7..59d3e8f 100644 --- a/cmd/expose.go +++ b/cmd/expose.go @@ -15,9 +15,9 @@ import ( var exposeCmd = &cobra.Command{ Use: "expose [flags] SERVICE_NAME [ports]", Short: "Expose local machine as a service on the kubernetes cluster", - Long: `This command would inject a new service and deployment to the cluster, and open the tunnel to the server + Long: `This command would inject a new service and deployment to the cluster, and open the tunnel to the server forwarding tunnel ingress traffic to the the same port on localhost`, - Args: cobra.MinimumNArgs(2), + Args: cobra.MinimumNArgs(2), Example: ` # Expose a local application running on port 8000 via http ktunnel expose kewlapp 80:8000 @@ -55,7 +55,7 @@ ktunnel expose redis 6379 }() log.Info("waiting for deployment to be ready") - <- readyChan + <-readyChan // Port-Forward strPort := strconv.FormatInt(int64(Port), 10) @@ -75,7 +75,7 @@ ktunnel expose redis 6379 log.Fatalf("Failed to run client: %v", err) } prt := int(p) - err = client.RunClient(&Host, &prt, Scheme ,&Tls, &CaFile, &ServerHostOverride, args[1:], closeChan) + err = client.RunClient(&Host, &prt, Scheme, &Tls, &CaFile, &ServerHostOverride, args[1:], closeChan) if err != nil { log.Fatalf("Failed to run client: %v", err) } @@ -89,6 +89,6 @@ func init() { exposeCmd.Flags().StringVarP(&CaFile, "ca-file", "c", "", "TLS cert auth file") exposeCmd.Flags().StringVarP(&Scheme, "scheme", "s", "tcp", "Connection scheme") exposeCmd.Flags().StringVarP(&ServerHostOverride, "server-host-override", "o", "", "Server name use to verify the hostname returned by the TLS handshake") - exposeCmd.Flags().StringVarP(&Namespace, "namespace","n", "default", "Namespace") + exposeCmd.Flags().StringVarP(&Namespace, "namespace", "n", "default", "Namespace") rootCmd.AddCommand(exposeCmd) } diff --git a/cmd/inject.go b/cmd/inject.go index 7c73583..e84c6b3 100644 --- a/cmd/inject.go +++ b/cmd/inject.go @@ -17,14 +17,14 @@ var Namespace string var injectCmd = &cobra.Command{ Use: "inject", Short: "Inject server sidecar to the cluster and run the ktunnel client to establish a connection", - Long: `This command accepts a pod/deployment and injects the tunnel sidecar to that artifact, + Long: `This command accepts a pod/deployment and injects the tunnel sidecar to that artifact, it then establishes a reverse tunnel`, } var injectDeploymentCmd = &cobra.Command{ - Use: "deployment [flags] DEPLOYMENT_NAME [ports]", + Use: "deployment [flags] DEPLOYMENT_NAME [ports]", Short: "Inject server sidecar to a deployment and run the ktunnel client to establish a connection", - Args: cobra.MinimumNArgs(2), + Args: cobra.MinimumNArgs(2), Example: ` # Inject a back tunnel from a running deployment to local mysql and redis ktunnel inject deploymeny mydeployment 3306 6379 @@ -48,7 +48,7 @@ ktunnel inject deploymeny mydeployment 3306 6379 stopChan := make(chan struct{}, 1) go func() { - o.Do(func(){ + o.Do(func() { <-sigs log.Info("Stopping streams") close(closeChan) @@ -85,7 +85,7 @@ ktunnel inject deploymeny mydeployment 3306 6379 log.Fatalf("Failed to run client: %v", err) } prt := int(p) - err = client.RunClient(&Host, &prt, Scheme ,&Tls, &CaFile, &ServerHostOverride, args[1:], closeChan) + err = client.RunClient(&Host, &prt, Scheme, &Tls, &CaFile, &ServerHostOverride, args[1:], closeChan) if err != nil { log.Fatalf("Failed to run client: %v", err) } @@ -99,11 +99,11 @@ func init() { injectCmd.Flags().StringVarP(&CaFile, "ca-file", "c", "", "TLS cert auth file") injectCmd.Flags().StringVarP(&Scheme, "scheme", "s", "tcp", "Connection scheme") injectCmd.Flags().StringVarP(&ServerHostOverride, "server-host-override", "o", "", "Server name use to verify the hostname returned by the TLS handshake") - injectCmd.Flags().StringVarP(&Namespace, "namespace","n", "default", "Namespace") + injectCmd.Flags().StringVarP(&Namespace, "namespace", "n", "default", "Namespace") injectDeploymentCmd.Flags().StringVarP(&CaFile, "ca-file", "c", "", "TLS cert auth file") injectDeploymentCmd.Flags().StringVarP(&Scheme, "scheme", "s", "tcp", "Connection scheme") injectDeploymentCmd.Flags().StringVarP(&ServerHostOverride, "server-host-override", "o", "", "Server name use to verify the hostname returned by the TLS handshake") - injectDeploymentCmd.Flags().StringVarP(&Namespace, "namespace","n", "default", "Namespace") + injectDeploymentCmd.Flags().StringVarP(&Namespace, "namespace", "n", "default", "Namespace") injectCmd.AddCommand(injectDeploymentCmd) rootCmd.AddCommand(injectCmd) } diff --git a/cmd/root.go b/cmd/root.go index f2e5bca..e13cf61 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -11,7 +11,7 @@ import ( ) const ( - version = "1.1.8" + version = "1.1.9" ) var Port int diff --git a/cmd/server.go b/cmd/server.go index 24d4f87..af5178e 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -29,4 +29,4 @@ func init() { serverCmd.Flags().StringVar(&CertFile, "cert", "", "tls certificate file") serverCmd.Flags().StringVar(&KeyFile, "key", "", "tls key file") rootCmd.AddCommand(serverCmd) -} \ No newline at end of file +} diff --git a/ktunnel.rb b/ktunnel.rb index 99d5edc..c8a9d2f 100644 --- a/ktunnel.rb +++ b/ktunnel.rb @@ -2,16 +2,23 @@ class Ktunnel < Formula desc "Network tunneling tool for kubernetes." homepage "https://github.com/omrikiei/ktunnel" - version "1.1.8" + version "1.1.9" bottle :unneeded if OS.mac? - url "https://github.com/omrikiei/ktunnel/releases/download/v1.1.8/ktunnel_1.1.8_Darwin_x86_64.tar.gz" - sha256 "dceadbf708b76ffc49edcf4cdae7cba0534df724a298cf4d4f8e231d5fbc29f6" + url "https://github.com/omrikiei/ktunnel/releases/download/v1.1.9/ktunnel_1.1.9_Darwin_x86_64.tar.gz" + sha256 "da35758a40f97f9f0d8498776fbba67e3deaaadef5f9f9e26d9611672b323140" elsif OS.linux? if Hardware::CPU.intel? - url "https://github.com/omrikiei/ktunnel/releases/download/v1.1.8/ktunnel_1.1.8_Linux_x86_64.tar.gz" - sha256 "ff4380b114d68ed673c1ea74fa2641a6ca72d0bdd8f0462cbce47d9e70b1a490" + url "https://github.com/omrikiei/ktunnel/releases/download/v1.1.9/ktunnel_1.1.9_Linux_x86_64.tar.gz" + sha256 "e3821abb032b39ee5c86b31248d86ec6c68d4e017476f44884fd574b084723c9" + end + if Hardware::CPU.arm? + if Hardware::CPU.is_64_bit? + url "https://github.com/omrikiei/ktunnel/releases/download/v1.1.9/ktunnel_1.1.9_Linux_arm64.tar.gz" + sha256 "de80e6100bdd82e4c9e3b572ee34fbfe83f6c477693333f4a53c4eb459650133" + else + end end end diff --git a/pkg/client/client.go b/pkg/client/client.go index 7956395..80bb7c3 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -16,7 +16,7 @@ import ( ) const ( - bufferSize = 1024*32 + bufferSize = 1024 * 32 ) type Message struct { @@ -47,7 +47,7 @@ func ReceiveData(st *pb.Tunnel_InitTunnelClient, closeStream <-chan bool, sessio if m.ShouldClose != true { log.Infof("%s; new session; connecting to port %d", m.RequestId, port) // new session - conn ,err := net.Dial(strings.ToLower(scheme), fmt.Sprintf("localhost:%d", port)) + conn, err := net.Dial(strings.ToLower(scheme), fmt.Sprintf("localhost:%d", port)) if err != nil { log.Errorf("failed connecting to localhost on port %d scheme %s", port, scheme) continue @@ -187,9 +187,9 @@ func RunClient(host *string, port *int, scheme string, tls *bool, caFile, server log.Fatalf("unsupported connection scheme %s", scheme) } req := &pb.SocketDataRequest{ - Port: tunnelData.Source, - LogLevel: 0, - Scheme: pb.TunnelScheme(tunnelScheme), + Port: tunnelData.Source, + LogLevel: 0, + Scheme: pb.TunnelScheme(tunnelScheme), } stream, err := client.InitTunnel(ctx) if err != nil { @@ -203,7 +203,7 @@ func RunClient(host *string, port *int, scheme string, tls *bool, caFile, server //closeStream := make(chan bool, 1) go ReceiveData(&stream, closeStream, sessions, tunnelData.Target, scheme) go SendData(&stream, sessions, closeStream) - <- closeStream + <-closeStream _ = stream.CloseSend() } } @@ -213,4 +213,4 @@ func RunClient(host *string, port *int, scheme string, tls *bool, caFile, server } wg.Wait() return nil -} \ No newline at end of file +} diff --git a/pkg/common/common.go b/pkg/common/common.go index 84f95e8..4f91f5b 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -10,13 +10,12 @@ import ( "strconv" "strings" "sync" - ) type Session struct { - Id uuid.UUID + Id uuid.UUID Conn *net.Conn - Buf *bytes.Buffer + Buf *bytes.Buffer Open bool Lock sync.Mutex } @@ -29,8 +28,8 @@ type RedirectRequest struct { func NewSession(conn *net.Conn) *Session { r := &Session{ Id: uuid.New(), - Conn: conn, - Buf: &bytes.Buffer{}, + Conn: conn, + Buf: &bytes.Buffer{}, Open: true, } ok, err := AddSession(r) @@ -43,8 +42,8 @@ func NewSession(conn *net.Conn) *Session { func NewSessionFromStream(id *uuid.UUID, conn *net.Conn) *Session { r := &Session{ Id: *id, - Conn: conn, - Buf: &bytes.Buffer{}, + Conn: conn, + Buf: &bytes.Buffer{}, Open: true, } ok, err := AddSession(r) @@ -62,7 +61,7 @@ func AddSession(r *Session) (bool, error) { return true, nil } -func GetSession(id *uuid.UUID) (*Session, bool){ +func GetSession(id *uuid.UUID) (*Session, bool) { request, ok := openSessions[id.String()] return request, ok } @@ -112,4 +111,4 @@ func ParsePorts(s string) (*RedirectRequest, error) { }, nil } return nil, errors.New(fmt.Sprintf("Error, bad tunnel format: %s", s)) -} \ No newline at end of file +} diff --git a/pkg/k8s/common.go b/pkg/k8s/common.go index 272c0a6..6bd4de3 100644 --- a/pkg/k8s/common.go +++ b/pkg/k8s/common.go @@ -49,7 +49,7 @@ func getKubeConfig() *rest.Config { } func getClients(namespace *string) { - deploymentOnce.Do(func(){ + deploymentOnce.Do(func() { clientset, err := kubernetes.NewForConfig(kubeconfig) if err != nil { log.Errorf("Failed to get k8s client: %v", err) @@ -72,24 +72,24 @@ func getAllPods(namespace, deployment *string) (*apiv1.PodList, error) { return pods, nil } -func waitForReady(name *string, ti *time.Time, numPods int32, readyChan chan<-bool) { +func waitForReady(name *string, ti *time.Time, numPods int32, readyChan chan<- bool) { go func() { /* - watcher, err := podsClient.Watch(metav1.ListOptions{ - TypeMeta: metav1.TypeMeta{ - Kind: "pod", - }, - Watch: true, - }) - if err != nil { - return - } - - for e := range watcher.ResultChan(){ - if e.Type == watch.Deleted { - break + watcher, err := podsClient.Watch(metav1.ListOptions{ + TypeMeta: metav1.TypeMeta{ + Kind: "pod", + }, + Watch: true, + }) + if err != nil { + return } - }*/ + + for e := range watcher.ResultChan(){ + if e.Type == watch.Deleted { + break + } + }*/ for { count := int32(0) pods, err := podsClient.List(metav1.ListOptions{}) @@ -106,7 +106,7 @@ func waitForReady(name *string, ti *time.Time, numPods int32, readyChan chan<-bo break } } - time.Sleep(time.Millisecond*300) + time.Sleep(time.Millisecond * 300) } }() } @@ -120,16 +120,16 @@ func hasSidecar(podSpec apiv1.PodSpec) bool { return false } -func newContainer(port int) *apiv1.Container{ - args := []string{ "server", "-p", strconv.FormatInt(int64(port), 10)} +func newContainer(port int) *apiv1.Container { + args := []string{"server", "-p", strconv.FormatInt(int64(port), 10)} if Verbose == true { args = append(args, "-v") } return &apiv1.Container{ - Name: "ktunnel", - Image: image, + Name: "ktunnel", + Image: image, Command: []string{"/ktunnel/ktunnel"}, - Args: args, + Args: args, } } @@ -137,31 +137,31 @@ func newDeployment(namespace, name string, port int) *appsv1.Deployment { replicas := int32(1) co := newContainer(port) return &appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{}, + TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ - Name: name, + Name: name, Namespace: namespace, Labels: map[string]string{ - "app.kubernetes.io/name": name, + "app.kubernetes.io/name": name, "app.kubernetes.io/instance": name, }, }, - Spec: appsv1.DeploymentSpec{ + Spec: appsv1.DeploymentSpec{ Replicas: &replicas, Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "app.kubernetes.io/name": name, + MatchLabels: map[string]string{ + "app.kubernetes.io/name": name, "app.kubernetes.io/instance": name, }, }, Template: apiv1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ - "app.kubernetes.io/name": name, + "app.kubernetes.io/name": name, "app.kubernetes.io/instance": name, }, }, - Spec: apiv1.PodSpec{ + Spec: apiv1.PodSpec{ Containers: []apiv1.Container{ *co, }, @@ -173,21 +173,19 @@ func newDeployment(namespace, name string, port int) *appsv1.Deployment { func newService(namespace, name string, ports []apiv1.ServicePort) *apiv1.Service { return &apiv1.Service{ - TypeMeta: metav1.TypeMeta{ + TypeMeta: metav1.TypeMeta{ Kind: "Service", - }, ObjectMeta: metav1.ObjectMeta{ - Name: name, + Name: name, Namespace: namespace, - }, - Spec: apiv1.ServiceSpec{ + Spec: apiv1.ServiceSpec{ Ports: ports, Selector: map[string]string{ - "app.kubernetes.io/name": name, + "app.kubernetes.io/name": name, "app.kubernetes.io/instance": name, }, }, } -} \ No newline at end of file +} diff --git a/pkg/k8s/exposer.go b/pkg/k8s/exposer.go index 9ba6678..7475765 100644 --- a/pkg/k8s/exposer.go +++ b/pkg/k8s/exposer.go @@ -32,7 +32,7 @@ func ExposeAsService(namespace, name *string, tunnelPort int, scheme string, raw } ports[i] = v12.ServicePort{ Protocol: protocol, - Port: parsed.Source, + Port: parsed.Source, TargetPort: intstr.IntOrString{ Type: intstr.Int, IntVal: parsed.Target, @@ -42,7 +42,7 @@ func ExposeAsService(namespace, name *string, tunnelPort int, scheme string, raw } service := newService(*namespace, *name, ports) - creationTime := time.Now().Add(-1*time.Second) + creationTime := time.Now().Add(-1 * time.Second) _, err := deploymentsClient.Create(deployment) if err != nil { return err @@ -69,4 +69,4 @@ func TeardownExposedService(namespace, name *string) error { return err } return nil -} \ No newline at end of file +} diff --git a/pkg/k8s/injector.go b/pkg/k8s/injector.go index e213f3e..959f04b 100644 --- a/pkg/k8s/injector.go +++ b/pkg/k8s/injector.go @@ -19,7 +19,6 @@ import ( "time" ) - func injectToDeployment(o *appsv1.Deployment, c *apiv1.Container, readyChan chan<- bool) (bool, error) { if hasSidecar(o.Spec.Template.Spec) { log.Warn(fmt.Sprintf("%s already injected to the deplyoment", image)) @@ -38,7 +37,7 @@ func InjectSidecar(namespace, objectName *string, port *int, readyChan chan<- bo log.Infof("Injecting tunnel sidecar to %s/%s", *namespace, *objectName) getClients(namespace) co := newContainer(*port) - creationTime := time.Now().Add(-1*time.Second) + creationTime := time.Now().Add(-1 * time.Second) obj, err := deploymentsClient.Get(*objectName, metav1.GetOptions{}) if err != nil { return false, err @@ -69,7 +68,7 @@ func removeFromSpec(s *apiv1.PodSpec) (bool, error) { if cIndex != -1 { containers := s.Containers - s.Containers = append(containers[:cIndex], containers[cIndex+1:]...) + s.Containers = append(containers[:cIndex], containers[cIndex+1:]...) return true, nil } else { return false, errors.New("container not found on spec") @@ -83,7 +82,7 @@ func RemoveSidecar(namespace, objectName *string, readyChan chan<- bool) (bool, if err != nil { return false, err } - deletionTime := time.Now().Add(-1*time.Second) + deletionTime := time.Now().Add(-1 * time.Second) _, err = removeFromSpec(&obj.Spec.Template.Spec) if err != nil { return false, err @@ -103,7 +102,7 @@ func getPodNames(namespace, deploymentName *string, podsPtr *[]string) error { } pods := *podsPtr pIndex := 0 - for _,p := range allPods.Items { + for _, p := range allPods.Items { if pIndex >= len(pods) { log.Info("All pods located for port-forwarding") break @@ -119,7 +118,7 @@ func getPodNames(namespace, deploymentName *string, podsPtr *[]string) error { } func getPortForwardUrl(config *rest.Config, namespace string, podName string) *url.URL { - host := strings.TrimLeft(config.Host, "https://") + host := strings.TrimPrefix(config.Host, "https://") trailingHostPath := strings.Split(host, "/") hostIp := trailingHostPath[0] trailingPath := "" @@ -129,8 +128,8 @@ func getPortForwardUrl(config *rest.Config, namespace string, podName string) *u path := fmt.Sprintf("%s/api/v1/namespaces/%s/pods/%s/portforward", trailingPath, namespace, podName) return &url.URL{ Scheme: "https", - Path: path, - Host: hostIp, + Path: path, + Host: hostIp, } } @@ -193,4 +192,4 @@ func PortForward(namespace, deploymentName *string, targetPort string, fwdWaitGr }() } return &sourcePorts, nil -} \ No newline at end of file +} diff --git a/pkg/k8s/injector_test.go b/pkg/k8s/injector_test.go index cb162c7..22431be 100644 --- a/pkg/k8s/injector_test.go +++ b/pkg/k8s/injector_test.go @@ -12,9 +12,9 @@ import ( type TestCase struct { Containers []v14.Container - Replicas int32 + Replicas int32 BoolResult bool - ErrResult error + ErrResult error } func createMockClient() { @@ -27,10 +27,10 @@ func createMockClient() { func createDeployment(c v1.DeploymentInterface, replicas int32, containers *[]v14.Container) error { d := v12.Deployment{ - Spec: v12.DeploymentSpec{ + Spec: v12.DeploymentSpec{ Replicas: &replicas, Template: v14.PodTemplateSpec{ - Spec: v14.PodSpec{ + Spec: v14.PodSpec{ Containers: *containers, }, }, @@ -44,34 +44,46 @@ func createDeployment(c v1.DeploymentInterface, replicas int32, containers *[]v1 } func TestGetPortForwardUrl(t *testing.T) { - tables := []struct{ - Config rest.Config + tables := []struct { + Config rest.Config Namespace string - Pod string - Expected *url.URL + Pod string + Expected *url.URL }{ { - Config: rest.Config{ + Config: rest.Config{ Host: "https://api.qa.kube.com", }, Namespace: "default", - Pod: "test", + Pod: "test", Expected: &url.URL{ - Scheme: "https", - Host: "api.qa.kube.com", - Path: "/api/v1/namespaces/default/pods/test/portforward", + Scheme: "https", + Host: "api.qa.kube.com", + Path: "/api/v1/namespaces/default/pods/test/portforward", }, }, { - Config: rest.Config{ + Config: rest.Config{ Host: "https://rancher.xyz.io/k8s/clusters/c-wfdqx", }, Namespace: "default", - Pod: "test", + Pod: "test", Expected: &url.URL{ Scheme: "https", - Host: "rancher.xyz.io", - Path: "/k8s/clusters/c-wfdqx/api/v1/namespaces/default/pods/test/portforward", + Host: "rancher.xyz.io", + Path: "/k8s/clusters/c-wfdqx/api/v1/namespaces/default/pods/test/portforward", + }, + }, + { + Config: rest.Config{ + Host: "https://srv01.mydomain.de:6443", + }, + Pod: "myapp-5b65c8777b-dd54r", + Namespace: "default", + Expected: &url.URL{ + Scheme: "https", + Host: "srv01.mydomain.de:6443", + Path: "/api/v1/namespaces/default/pods/myapp-5b65c8777b-dd54r/portforward", }, }, } @@ -86,4 +98,4 @@ func TestGetPortForwardUrl(t *testing.T) { func TestInjectSidecar(t *testing.T) { createMockClient() -} \ No newline at end of file +} diff --git a/pkg/server/server.go b/pkg/server/server.go index 4116e58..7a915c4 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -15,10 +15,10 @@ import ( ) const ( - bufferSize = 1024*32 + bufferSize = 1024 * 32 ) -type tunnelServer struct {} +type tunnelServer struct{} func NewServer() *tunnelServer { return &tunnelServer{} @@ -101,8 +101,8 @@ func (t *tunnelServer) InitTunnel(stream pb.Tunnel_InitTunnelServer) error { err := stream.Send(&pb.SocketDataResponse{ HasErr: true, LogMessage: &pb.LogMessage{ - LogLevel: pb.LogLevel_ERROR, - Message: "missing port", + LogLevel: pb.LogLevel_ERROR, + Message: "missing port", }, }) if err != nil { @@ -119,8 +119,8 @@ func (t *tunnelServer) InitTunnel(stream pb.Tunnel_InitTunnelServer) error { _ = stream.Send(&pb.SocketDataResponse{ HasErr: true, LogMessage: &pb.LogMessage{ - LogLevel: pb.LogLevel_ERROR, - Message: fmt.Sprintf("failed opening listener type %s on port %d: %v", request.GetScheme(), request.GetPort(), err), + LogLevel: pb.LogLevel_ERROR, + Message: fmt.Sprintf("failed opening listener type %s on port %d: %v", request.GetScheme(), request.GetPort(), err), }, }) return err @@ -128,7 +128,7 @@ func (t *tunnelServer) InitTunnel(stream pb.Tunnel_InitTunnelServer) error { sessions := make(chan *common.Session) closeChan := make(chan bool, 1) - go func(close <-chan bool){ + go func(close <-chan bool) { <-close log.Infof("Closing connection on port %d", port) _ = ln.Close() @@ -197,4 +197,4 @@ func RunServer(port *int, tls *bool, keyFile, certFile *string) error { pb.RegisterTunnelServer(grpcServer, NewServer()) err = grpcServer.Serve(lis) return err -} \ No newline at end of file +}