goftp
goftp copied to clipboard
When the FTP server is deployed on the LVS, goftp can't make a data connection.
Consider when A FTP Server is on Linux LVS, which means the VIP(Virtual IP) != RealIP.
func (ftp *FTP) Pasv() (port int, err error) only return a port, and func (ftp *FTP) newConnection(port int) (conn net.Conn, err error) will combine the VIP of LVS and returned Port instead of RealIP and Port.
func (ftp *FTP) Pasv() (port int, err error) {
var line string
if line, err = ftp.cmd("227", "PASV"); err != nil {
return
}
re, err := regexp.Compile(`\((.*)\)`)
res := re.FindAllStringSubmatch(line, -1)
s := strings.Split(res[0][1], ",")
l1, _ := strconv.Atoi(s[len(s)-2])
l2, _ := strconv.Atoi(s[len(s)-1])
port = l1<<8 + l2
return
}
// open new data connection
func (ftp *FTP) newConnection(port int) (conn net.Conn, err error) {
addr := fmt.Sprintf("%s:%d", strings.Split(ftp.addr, ":")[0], port)
if ftp.debug {
log.Printf("Connecting to %s\n", addr)
}
if conn, err = net.Dial("tcp", addr); err != nil {
return
}
if ftp.tlsconfig != nil {
conn = tls.Client(conn, ftp.tlsconfig)
}
return
}
I suggest use func (ftp *FTP) Pasv() (host string, port int, err error) and func (ftp *FTP) newConnection(host string, port int) (conn net.Conn, err error)
If you want it , I will push a request pull.