goftp icon indicating copy to clipboard operation
goftp copied to clipboard

When the FTP server is deployed on the LVS, goftp can't make a data connection.

Open mohanson opened this issue 9 years ago • 0 comments

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.

mohanson avatar Nov 21 '16 09:11 mohanson