mirror of https://gogs.blitter.com/RLabs/xs
				
				
				
			File copy remote close signal to ensure completed tar pipe data
This commit is contained in:
		
							parent
							
								
									0586f306c0
								
							
						
					
					
						commit
						b419b2e002
					
				| 
						 | 
					@ -92,7 +92,8 @@ func (hc Conn) GetStatus() uint8 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (hc *Conn) SetStatus(stat uint8) {
 | 
					func (hc *Conn) SetStatus(stat uint8) {
 | 
				
			||||||
	*hc.closeStat = stat
 | 
						*hc.closeStat = stat
 | 
				
			||||||
	log.Println("closeStat:", *hc.closeStat)
 | 
						fmt.Println("closeStat:", *hc.closeStat)
 | 
				
			||||||
 | 
						//log.Println("closeStat:", *hc.closeStat)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ConnOpts returns the cipher/hmac options value, which is sent to the
 | 
					// ConnOpts returns the cipher/hmac options value, which is sent to the
 | 
				
			||||||
| 
						 | 
					@ -209,7 +210,7 @@ func Dial(protocol string, ipport string, extensions ...string) (hc *Conn, err e
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Close a hkex.Conn
 | 
					// Close a hkex.Conn
 | 
				
			||||||
func (hc Conn) Close() (err error) {
 | 
					func (hc *Conn) Close() (err error) {
 | 
				
			||||||
	hc.DisableChaff()
 | 
						hc.DisableChaff()
 | 
				
			||||||
	hc.WritePacket([]byte{byte(*hc.closeStat)}, CSOExitStatus)
 | 
						hc.WritePacket([]byte{byte(*hc.closeStat)}, CSOExitStatus)
 | 
				
			||||||
	*hc.closeStat = 0
 | 
						*hc.closeStat = 0
 | 
				
			||||||
| 
						 | 
					@ -219,12 +220,12 @@ func (hc Conn) Close() (err error) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// LocalAddr returns the local network address.
 | 
					// LocalAddr returns the local network address.
 | 
				
			||||||
func (hc Conn) LocalAddr() net.Addr {
 | 
					func (hc *Conn) LocalAddr() net.Addr {
 | 
				
			||||||
	return hc.c.LocalAddr()
 | 
						return hc.c.LocalAddr()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RemoteAddr returns the remote network address.
 | 
					// RemoteAddr returns the remote network address.
 | 
				
			||||||
func (hc Conn) RemoteAddr() net.Addr {
 | 
					func (hc *Conn) RemoteAddr() net.Addr {
 | 
				
			||||||
	return hc.c.RemoteAddr()
 | 
						return hc.c.RemoteAddr()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -243,7 +244,7 @@ func (hc Conn) RemoteAddr() net.Addr {
 | 
				
			||||||
// the deadline after successful Read or Write calls.
 | 
					// the deadline after successful Read or Write calls.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// A zero value for t means I/O operations will not time out.
 | 
					// A zero value for t means I/O operations will not time out.
 | 
				
			||||||
func (hc Conn) SetDeadline(t time.Time) error {
 | 
					func (hc *Conn) SetDeadline(t time.Time) error {
 | 
				
			||||||
	return hc.c.SetDeadline(t)
 | 
						return hc.c.SetDeadline(t)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -252,14 +253,14 @@ func (hc Conn) SetDeadline(t time.Time) error {
 | 
				
			||||||
// Even if write times out, it may return n > 0, indicating that
 | 
					// Even if write times out, it may return n > 0, indicating that
 | 
				
			||||||
// some of the data was successfully written.
 | 
					// some of the data was successfully written.
 | 
				
			||||||
// A zero value for t means Write will not time out.
 | 
					// A zero value for t means Write will not time out.
 | 
				
			||||||
func (hc Conn) SetWriteDeadline(t time.Time) error {
 | 
					func (hc *Conn) SetWriteDeadline(t time.Time) error {
 | 
				
			||||||
	return hc.c.SetWriteDeadline(t)
 | 
						return hc.c.SetWriteDeadline(t)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetReadDeadline sets the deadline for future Read calls
 | 
					// SetReadDeadline sets the deadline for future Read calls
 | 
				
			||||||
// and any currently-blocked Read call.
 | 
					// and any currently-blocked Read call.
 | 
				
			||||||
// A zero value for t means Read will not time out.
 | 
					// A zero value for t means Read will not time out.
 | 
				
			||||||
func (hc Conn) SetReadDeadline(t time.Time) error {
 | 
					func (hc *Conn) SetReadDeadline(t time.Time) error {
 | 
				
			||||||
	return hc.c.SetReadDeadline(t)
 | 
						return hc.c.SetReadDeadline(t)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -304,7 +305,7 @@ func (hl HKExListener) Addr() net.Addr {
 | 
				
			||||||
// Accept a client connection, conforming to net.Listener.Accept()
 | 
					// Accept a client connection, conforming to net.Listener.Accept()
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// See go doc net.Listener.Accept
 | 
					// See go doc net.Listener.Accept
 | 
				
			||||||
func (hl HKExListener) Accept() (hc Conn, err error) {
 | 
					func (hl *HKExListener) Accept() (hc Conn, err error) {
 | 
				
			||||||
	// Open raw Conn c
 | 
						// Open raw Conn c
 | 
				
			||||||
	c, err := hl.l.Accept()
 | 
						c, err := hl.l.Accept()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
| 
						 | 
					@ -405,7 +406,10 @@ func (hc Conn) Read(b []byte) (n int, err error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var payloadBytes = make([]byte, payloadLen)
 | 
							var payloadBytes = make([]byte, payloadLen)
 | 
				
			||||||
		n, err = io.ReadFull(hc.c, payloadBytes)
 | 
							n, err = io.ReadFull(hc.c, payloadBytes)
 | 
				
			||||||
		//log.Print(" << Read ", n, " payloadBytes")
 | 
							//!fmt.Println(" << Read ", n, " payloadBytes")
 | 
				
			||||||
 | 
							//time.Sleep(100 * time.Millisecond)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//log.Println(" << Read ", n, " payloadBytes")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Normal client 'exit' from interactive session will cause
 | 
							// Normal client 'exit' from interactive session will cause
 | 
				
			||||||
		// (on server side) err.Error() == "<iface/addr info ...>: use of closed network connection"
 | 
							// (on server side) err.Error() == "<iface/addr info ...>: use of closed network connection"
 | 
				
			||||||
| 
						 | 
					@ -442,6 +446,11 @@ func (hc Conn) Read(b []byte) (n int, err error) {
 | 
				
			||||||
		} else if ctrlStatOp == CSOExitStatus {
 | 
							} else if ctrlStatOp == CSOExitStatus {
 | 
				
			||||||
			if len(payloadBytes) > 0 {
 | 
								if len(payloadBytes) > 0 {
 | 
				
			||||||
				*hc.closeStat = uint8(payloadBytes[0])
 | 
									*hc.closeStat = uint8(payloadBytes[0])
 | 
				
			||||||
 | 
									// If remote end is closing (255), reply we're closing ours
 | 
				
			||||||
 | 
									if payloadBytes[0] == 255 {
 | 
				
			||||||
 | 
										hc.SetStatus(255)
 | 
				
			||||||
 | 
										hc.Close()
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				log.Println("[truncated payload, cannot determine CSOExitStatus]")
 | 
									log.Println("[truncated payload, cannot determine CSOExitStatus]")
 | 
				
			||||||
				*hc.closeStat = 98
 | 
									*hc.closeStat = 98
 | 
				
			||||||
| 
						 | 
					@ -487,7 +496,7 @@ func (hc Conn) Write(b []byte) (n int, err error) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Write a byte slice with specified ctrlStatusOp byte
 | 
					// Write a byte slice with specified ctrlStatusOp byte
 | 
				
			||||||
func (hc Conn) WritePacket(b []byte, op byte) (n int, err error) {
 | 
					func (hc *Conn) WritePacket(b []byte, op byte) (n int, err error) {
 | 
				
			||||||
	//log.Printf("[Encrypting...]\r\n")
 | 
						//log.Printf("[Encrypting...]\r\n")
 | 
				
			||||||
	var hmacOut []uint8
 | 
						var hmacOut []uint8
 | 
				
			||||||
	var payloadLen uint32
 | 
						var payloadLen uint32
 | 
				
			||||||
| 
						 | 
					@ -500,16 +509,10 @@ func (hc Conn) WritePacket(b []byte, op byte) (n int, err error) {
 | 
				
			||||||
	//
 | 
						//
 | 
				
			||||||
	// Would be nice to determine if the mutex scope
 | 
						// Would be nice to determine if the mutex scope
 | 
				
			||||||
	// could be tightened.
 | 
						// could be tightened.
 | 
				
			||||||
	for uint32(len(b)) > 0 {
 | 
					 | 
				
			||||||
	hc.m.Lock()
 | 
						hc.m.Lock()
 | 
				
			||||||
		fmt.Printf("--== TOTAL payloadLen (b):%d\n", len(b))
 | 
						//fmt.Printf("--== TOTAL payloadLen (b):%d\n", len(b))
 | 
				
			||||||
	payloadLen = uint32(len(b))
 | 
						payloadLen = uint32(len(b))
 | 
				
			||||||
		if payloadLen > MAX_PAYLOAD_LEN {
 | 
						//!fmt.Printf("  --== payloadLen:%d\n", payloadLen)
 | 
				
			||||||
			payloadLen = MAX_PAYLOAD_LEN
 | 
					 | 
				
			||||||
			//fmt.Printf("--== payloadLen:%d\n", payloadLen)
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			//fmt.Printf("--== payloadLen:%d\n", payloadLen)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	log.Printf("  :>ptext:\r\n%s\r\n", hex.Dump(b[0:payloadLen]))
 | 
						log.Printf("  :>ptext:\r\n%s\r\n", hex.Dump(b[0:payloadLen]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Calculate hmac on payload
 | 
						// Calculate hmac on payload
 | 
				
			||||||
| 
						 | 
					@ -537,17 +540,20 @@ func (hc Conn) WritePacket(b []byte, op byte) (n int, err error) {
 | 
				
			||||||
			err = binary.Write(hc.c, binary.BigEndian, payloadLen)
 | 
								err = binary.Write(hc.c, binary.BigEndian, payloadLen)
 | 
				
			||||||
			if err == nil {
 | 
								if err == nil {
 | 
				
			||||||
				n, err = hc.c.Write(wb.Bytes())
 | 
									n, err = hc.c.Write(wb.Bytes())
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									//fmt.Println("[c]WriteError!")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								//fmt.Println("[b]WriteError!")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							//fmt.Println("[a]WriteError!")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		//Advance to next full (or final, partial) chunk of payload
 | 
					 | 
				
			||||||
		b = b[payloadLen:]
 | 
					 | 
				
			||||||
	hc.m.Unlock()
 | 
						hc.m.Unlock()
 | 
				
			||||||
		//time.Sleep(200 * time.Millisecond)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		//panic(err)
 | 
							//panic(err)
 | 
				
			||||||
 | 
							fmt.Println(err)
 | 
				
			||||||
		log.Println(err)
 | 
							log.Println(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -168,7 +168,10 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			fmt.Println("*** client->server cp finished ***")
 | 
								//fmt.Println("*** client->server cp finished ***")
 | 
				
			||||||
 | 
								// Signal other end transfer is complete
 | 
				
			||||||
 | 
								conn.WritePacket([]byte{byte(255)}, hkexnet.CSOExitStatus)
 | 
				
			||||||
 | 
								_, _ = conn.Read(nil /*ackByte*/)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		fmt.Println("remote filepath:", string(rec.cmd), "local files:", files)
 | 
							fmt.Println("remote filepath:", string(rec.cmd), "local files:", files)
 | 
				
			||||||
| 
						 | 
					@ -212,7 +215,7 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			fmt.Println("*** server->client cp finished ***")
 | 
								//fmt.Println("*** server->client cp finished ***")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -115,7 +115,7 @@ func runClientToServerCopyAs(who string, conn hkexnet.Conn, fpath string, chaffi
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fmt.Println("*** client->server cp finished ***")
 | 
							//fmt.Println("*** client->server cp finished ***")
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -192,7 +192,7 @@ func runServerToClientCopyAs(who string, conn hkexnet.Conn, srcPath string, chaf
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fmt.Println("*** server->client cp finished ***")
 | 
							//fmt.Println("*** server->client cp finished ***")
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -519,6 +519,12 @@ func main() {
 | 
				
			||||||
						log.Printf("[Command completed for %s@%s, status %d]\n", rec.who, hname, cmdStatus)
 | 
											log.Printf("[Command completed for %s@%s, status %d]\n", rec.who, hname, cmdStatus)
 | 
				
			||||||
						hc.SetStatus(uint8(cmdStatus))
 | 
											hc.SetStatus(uint8(cmdStatus))
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
										// Signal other end transfer is complete
 | 
				
			||||||
 | 
										hc.WritePacket([]byte{byte(255)}, hkexnet.CSOExitStatus)
 | 
				
			||||||
 | 
										//fmt.Println("Waiting for EOF from other end.")
 | 
				
			||||||
 | 
										//ackByte := make([]byte, 1, 1)
 | 
				
			||||||
 | 
										_, _ = hc.Read(nil /*ackByte*/)
 | 
				
			||||||
 | 
										//fmt.Println("Got remote end ack.")
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					log.Println("[Bad cmdSpec]")
 | 
										log.Println("[Bad cmdSpec]")
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue