@@ -91,6 +91,32 @@ func addFreeIndex(i int) {
9191 freeList = append (freeList , i )
9292 connPool [i ] = "" // RESET
9393}
94+
95+ // Accepts incoming connection and establishes bidirectional communication between pod and user request
96+ func listenAndAccept (ctx context.Context , listener net.Listener , fw forwarder.Forwarder ) {
97+ for {
98+ select {
99+ case <- ctx .Done ():
100+ return
101+ default :
102+ hostConn , err := listener .Accept ()
103+ if err != nil {
104+ if errors .Is (err , net .ErrClosed ) {
105+ return // Prolly exiting
106+ }
107+ fmt .Printf ("Accept error: %v" , err )
108+ continue
109+ }
110+ podConn , err := getPodConnection (fw )
111+ if err != nil {
112+ fmt .Printf ("Pod connection error: %v" , err )
113+ continue
114+ }
115+ forwardToPod (hostConn , podConn )
116+ }
117+
118+ }
119+ }
94120func NewCommand () * cobra.Command {
95121 cmd := & cobra.Command {
96122 Use : "port-forward" ,
@@ -106,30 +132,8 @@ func NewCommand() *cobra.Command {
106132 }
107133 ctx , cancel := context .WithCancel (context .Background ())
108134 defer cancel ()
109- go func () {
110- for {
111- select {
112- case <- ctx .Done ():
113- return
114- default :
115- hostConn , err := listener .Accept ()
116- if err != nil {
117- if errors .Is (err , net .ErrClosed ) {
118- return // Prolly exiting
119- }
120- fmt .Printf ("Accept error: %v" , err )
121- continue
122- }
123- podConn , err := getPodConnection (fw )
124- if err != nil {
125- fmt .Printf ("Pod connection error: %v" , err )
126- continue
127- }
128- forwardToPod (hostConn , podConn )
129- }
135+ go listenAndAccept (ctx , listener , fw )
130136
131- }
132- }()
133137 kubeconfig := clientcmd .NewDefaultClientConfigLoadingRules ().GetDefaultFilename ()
134138 config , err := clientcmd .BuildConfigFromFlags ("" , kubeconfig )
135139 if err != nil {
@@ -145,16 +149,18 @@ func NewCommand() *cobra.Command {
145149 panic ("Exiting runner..." + err .Error ())
146150 }
147151 pods := initialList .Items
148- connPool = make ([]string , len (pods ))
149- podNameToPoolIndex = make (map [string ]int , len (pods ))
152+ connPool = make ([]string , len (pods )) // This maintains list of available addresses that be used to forward traffic
153+ podNameToPoolIndex = make (map [string ]int , len (pods )) // This is used to free the connpool when pod is terminated
150154 fmt .Printf (pkg .ColorLine (fmt .Sprintf ("listening on %s using %s policy across %d pods\n " , hostport , policy , len (pods )), pkg .ColorGreen ))
151- startPortForward := func (i int , pod v1.Pod ) (string , error ) {
152- if i == fromWatch {
153- i = getFreeIndex ()
155+
156+ startPortForward := func (iConnPool int , pod v1.Pod ) (string , error ) {
157+ if iConnPool == fromWatch {
158+ iConnPool = getFreeIndex ()
154159 }
155- if stopChan , exists := indexToStopChan [i ]; exists {
160+ // Stop any previous port forwards, if running for any previous connections in the connection pool
161+ if stopChan , exists := indexToStopChan [iConnPool ]; exists {
156162 close (stopChan )
157- delete (indexToStopChan , i )
163+ delete (indexToStopChan , iConnPool )
158164 }
159165 req := cs .CoreV1 ().RESTClient ().Post ().
160166 Resource ("pods" ).
@@ -167,17 +173,17 @@ func NewCommand() *cobra.Command {
167173 }
168174 dialer := spdy .NewDialer (upgrader , & http.Client {Transport : transporter }, "POST" , req .URL ())
169175 stopChan := make (chan struct {})
170- indexToStopChan [i ] = stopChan // Track new stop channel
176+ indexToStopChan [iConnPool ] = stopChan // Track new stop channel
171177 readyChan := make (chan struct {})
172- hostPort := startingHostPort + i
178+ hostPort := startingHostPort + iConnPool
173179
174180 hostPortStr := fmt .Sprintf ("%s:%s" , strconv .Itoa (hostPort ), containerPort )
175- connPool [i ] = strconv .Itoa (hostPort )
176- podNameToPoolIndex [pod .Name ] = i
181+ connPool [iConnPool ] = strconv .Itoa (hostPort )
182+ podNameToPoolIndex [pod .Name ] = iConnPool
177183 forwarder , err := portforward .New (dialer , []string {hostPortStr }, stopChan , readyChan , os .Stdout , os .Stderr )
178184 if err != nil {
179- connPool [i ] = "" // Reset connPool entry
180- addFreeIndex (i ) // Return index to freeList
185+ connPool [iConnPool ] = "" // Reset connPool entry
186+ addFreeIndex (iConnPool ) // Return index to freeList
181187 return "" , fmt .Errorf ("port-forward setup failed: %v" , err )
182188 }
183189 go func () {
0 commit comments