I have a 1st ftp server on VDS # 1 (primary), which can sometimes be disabled by hosting. We have created a second VDS # 2 (secondary) that can help with fault tolerance when VDS # 1 is unreachable. VDS # 2 always has the same list of users with VDS # 1, with their usernames, passwords and directory tree.
When users cannot access VDS # 1, we want to automatically redirect them to VDS # 2. I wrote the GOlang code (code below), but it does not work correctly, I do n't know why, I am new to FTP issues.
Can you help me? Perhaps there is a way to easily redirect the FTP request through a special server response or something like that? Big thanks to all!
func proxyConn(connection net.Conn) {
defer connection.Close()
remoteServer, remoteServerError := getActiveServer()
if remoteServerError != nil {
Error{}.PrintAndSave(remoteServerError.Error())
return
}
remoteConnection, remoteError := net.DialTCP("tcp", nil, remoteServer)
if remoteError != nil {
Error{}.PrintAndSave(remoteError.Error())
return
}
defer remoteConnection.Close()
io.Copy(remoteConnection, connection)
io.Copy(connection, remoteConnection)
}
func getActiveServer() (*net.TCPAddr, error) {
connectedServerIndex := -1
for ftpServerIndex, ftpServer := range FTP_SERVERS {
connectedServer, serverError := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ftpServer, FTP_DEFAULT_PORT), CONNECTION_TIMEOUT)
if serverError != nil {
if ftpServerIndex == 0 {
// Send e-mail "Server unreachable"
}
} else {
connectedServerIndex = ftpServerIndex
connectedServer.Close()
break
}
}
if connectedServerIndex == -1 {
return nil, errors.New("active servers not found")
}
return net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", FTP_SERVERS[connectedServerIndex], FTP_DEFAULT_PORT))
}
func main() {
localAddress, localAddressErr := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", LOCAL_ADDRESS, FTP_DEFAULT_PORT))
if localAddressErr != nil {
Error{}.PrintAndSave(localAddressErr.Error())
}
server, serverError := net.ListenTCP("tcp", localAddress)
if serverError != nil {
Error{}.PrintAndSave(serverError.Error())
return
}
for {
connection, connectionError := server.Accept()
if connectionError != nil {
Error{}.PrintAndSave(fmt.Sprintf("failed to accept listener: %v", connectionError))
}
go proxyConn(connection)
}
}