|
|
@@ -1811,7 +1811,7 @@ func (sshServer *sshServer) handleClient(
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- sshClient := newSshClient(
|
|
|
+ sshClient, err := newSshClient(
|
|
|
sshServer,
|
|
|
sshListener,
|
|
|
tunnelProtocol,
|
|
|
@@ -1820,6 +1820,12 @@ func (sshServer *sshServer) handleClient(
|
|
|
replayedServerPacketManipulation,
|
|
|
peerAddr,
|
|
|
peerGeoIPData)
|
|
|
+ if err != nil {
|
|
|
+ conn.Close()
|
|
|
+ log.WithTraceFields(LogFields{"error": err}).Warning(
|
|
|
+ "newSshClient failed")
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
// sshClient.run _must_ call onSSHHandshakeFinished to release the semaphore:
|
|
|
// in any error case; or, as soon as the SSH handshake phase has successfully
|
|
|
@@ -1924,6 +1930,7 @@ type sshClient struct {
|
|
|
replayedServerPacketManipulation bool
|
|
|
peerAddr net.Addr
|
|
|
peerGeoIPData GeoIPData
|
|
|
+ clientIP string
|
|
|
clientGeoIPData GeoIPData
|
|
|
sessionID string
|
|
|
isFirstTunnelInSession bool
|
|
|
@@ -2291,7 +2298,7 @@ func newSshClient(
|
|
|
serverPacketManipulation string,
|
|
|
replayedServerPacketManipulation bool,
|
|
|
peerAddr net.Addr,
|
|
|
- peerGeoIPData GeoIPData) *sshClient {
|
|
|
+ peerGeoIPData GeoIPData) (*sshClient, error) {
|
|
|
|
|
|
runCtx, stopRunning := context.WithCancel(context.Background())
|
|
|
|
|
|
@@ -2308,6 +2315,7 @@ func newSshClient(
|
|
|
serverPacketManipulation: serverPacketManipulation,
|
|
|
replayedServerPacketManipulation: replayedServerPacketManipulation,
|
|
|
peerAddr: peerAddr,
|
|
|
+ peerGeoIPData: peerGeoIPData,
|
|
|
isFirstTunnelInSession: true,
|
|
|
qualityMetrics: newQualityMetrics(),
|
|
|
tcpPortForwardLRU: common.NewLRUConns(),
|
|
|
@@ -2322,17 +2330,35 @@ func newSshClient(
|
|
|
client.tcpTrafficState.availablePortForwardCond = sync.NewCond(new(sync.Mutex))
|
|
|
client.udpTrafficState.availablePortForwardCond = sync.NewCond(new(sync.Mutex))
|
|
|
|
|
|
- // In the case of in-proxy tunnel protocols, clientGeoIPData is not set
|
|
|
- // until the original client IP is relayed from the broker during the
|
|
|
- // handshake. In other cases, clientGeoIPData is the peerGeoIPData
|
|
|
- // (this includes fronted meek).
|
|
|
+ if peerAddr == nil {
|
|
|
+ return nil, errors.TraceNew("missing peerAddr")
|
|
|
+ }
|
|
|
+ peerIP, _, err := net.SplitHostPort(peerAddr.String())
|
|
|
+ if err != nil {
|
|
|
+ return nil, errors.Trace(err)
|
|
|
+ }
|
|
|
+ if net.ParseIP(peerIP) == nil {
|
|
|
+ return nil, errors.TraceNew("invalid peerIP")
|
|
|
+ }
|
|
|
+
|
|
|
+ // In the case of in-proxy tunnel protocols, clientIP and clientGeoIPData
|
|
|
+ // are not set until the original client IP is relayed from the broker
|
|
|
+ // during the handshake. In other cases, clientGeoIPData is the
|
|
|
+ // peerGeoIPData (this includes fronted meek).
|
|
|
|
|
|
- client.peerGeoIPData = peerGeoIPData
|
|
|
if !client.isInproxyTunnelProtocol {
|
|
|
+ client.clientIP = peerIP
|
|
|
client.clientGeoIPData = peerGeoIPData
|
|
|
}
|
|
|
|
|
|
- return client
|
|
|
+ return client, nil
|
|
|
+}
|
|
|
+
|
|
|
+// getClientP gets sshClient.clientIP. See getClientGeoIPData comment.
|
|
|
+func (sshClient *sshClient) getClientIP() string {
|
|
|
+ sshClient.Lock()
|
|
|
+ defer sshClient.Unlock()
|
|
|
+ return sshClient.clientIP
|
|
|
}
|
|
|
|
|
|
// getClientGeoIPData gets sshClient.clientGeoIPData. Use this helper when
|
|
|
@@ -4106,9 +4132,11 @@ func (sshClient *sshClient) setHandshakeState(
|
|
|
|
|
|
if sshClient.isInproxyTunnelProtocol {
|
|
|
|
|
|
- // Set the client GeoIP data to the value obtained using the
|
|
|
- // original client IP, from the broker, in the handshake. Also
|
|
|
- // update the GeoIP session hash to use the client GeoIP data.
|
|
|
+ // Set the client IP and GeoIP data to the value obtained using
|
|
|
+ // the original client IP, from the broker, in the handshake.
|
|
|
+ // Also update the GeoIP session hash to use the client GeoIP data.
|
|
|
+
|
|
|
+ sshClient.clientIP = sshClient.handshakeState.inproxyClientIP
|
|
|
|
|
|
sshClient.clientGeoIPData =
|
|
|
sshClient.handshakeState.inproxyClientGeoIPData
|