diff --git a/cmd/commands/server/command_server.go b/cmd/commands/server/command_server.go index 65a01a48c8..7b7a9ab880 100644 --- a/cmd/commands/server/command_server.go +++ b/cmd/commands/server/command_server.go @@ -43,7 +43,7 @@ type Command struct { ipResolver ip.Resolver mysteriumClient server.Client natService nat.NATService - locationDetector location.Detector + locationResolver location.Resolver dialogWaiterFactory func(identity identity.Identity) communication.DialogWaiter dialogWaiter communication.DialogWaiter @@ -54,6 +54,7 @@ type Command struct { vpnServer openvpn.Process checkOpenvpn func() error + openvpnServiceAddress func(string, string) string protocol string proposalAnnouncementStopped *sync.WaitGroup } @@ -75,15 +76,20 @@ func (cmd *Command) Start() (err error) { cmd.dialogWaiter = cmd.dialogWaiterFactory(providerID) providerContact, err := cmd.dialogWaiter.Start() + publicIP, err := cmd.ipResolver.GetPublicIP() + if err != nil { + return err + } + // if for some reason we will need truly external IP, use GetPublicIP() - vpnServerIP, err := cmd.ipResolver.GetOutboundIP() + outboundIP, err := cmd.ipResolver.GetOutboundIP() if err != nil { return err } cmd.natService.Add(nat.RuleForwarding{ SourceAddress: "10.8.0.0/24", - TargetIP: vpnServerIP, + TargetIP: outboundIP, }) err = cmd.natService.Start() @@ -91,12 +97,12 @@ func (cmd *Command) Start() (err error) { log.Warn("received nat service error: ", err, " trying to proceed.") } - currentLocation, err := cmd.locationDetector.DetectLocation() + currentCountry, err := cmd.locationResolver.ResolveCountry(publicIP) if err != nil { return err } - log.Info("Country detected: ", currentLocation.Country) - serviceLocation := dto_discovery.Location{Country: currentLocation.Country} + log.Info("Country detected: ", currentCountry) + serviceLocation := dto_discovery.Location{Country: currentCountry} proposal := discovery.NewServiceProposalWithLocation(providerID, providerContact, serviceLocation, cmd.protocol) @@ -105,7 +111,7 @@ func (cmd *Command) Start() (err error) { return err } - sessionManager := cmd.sessionManagerFactory(primitives, vpnServerIP) + sessionManager := cmd.sessionManagerFactory(primitives, cmd.openvpnServiceAddress(outboundIP, publicIP)) dialogHandler := session.NewDialogHandler(proposal.ID, sessionManager) if err := cmd.dialogWaiter.ServeDialogs(dialogHandler); err != nil { diff --git a/cmd/commands/server/factory.go b/cmd/commands/server/factory.go index 5c84b22f13..cb3ecdfc3e 100644 --- a/cmd/commands/server/factory.go +++ b/cmd/commands/server/factory.go @@ -18,6 +18,8 @@ package server import ( + "fmt" + log "github.com/cihub/seelog" "github.com/ethereum/go-ethereum/accounts/keystore" identity_handler "github.com/mysterium/node/cmd/commands/server/identity" "github.com/mysterium/node/communication" @@ -73,23 +75,14 @@ func NewCommandWith( createSigner, ) - var locationResolver location.Resolver - if options.LocationCountry != "" { - locationResolver = location.NewResolverFake(options.LocationCountry) - } else if options.LocationDatabase != "" { - locationResolver = location.NewResolver(filepath.Join(options.DirectoryConfig, options.LocationDatabase)) - } else { - locationResolver = location.NewResolver(filepath.Join(options.DirectoryConfig, defaultLocationDatabase)) - } - - locationDetector := location.NewDetectorWithLocationResolver(ipResolver, locationResolver) + locationResolver := locationResolver(options) return &Command{ identityLoader: func() (identity.Identity, error) { return identity_handler.LoadIdentity(identityHandler, options.Identity, options.Passphrase) }, createSigner: createSigner, - locationDetector: locationDetector, + locationResolver: locationResolver, ipResolver: ipResolver, mysteriumClient: mysteriumClient, natService: natService, @@ -137,11 +130,36 @@ func NewCommandWith( checkOpenvpn: func() error { return openvpn.CheckOpenvpnBinary(options.OpenvpnBinary) }, + openvpnServiceAddress: func(outboundIP, publicIP string) string { + //TODO public ip could be overriden by arg options if needed + if publicIP != outboundIP { + forwardInfo := fmt.Sprintf("%s:%v -> %s:%v", publicIP, options.OpenvpnPort, outboundIP, options.OpenvpnPort) + log.Warnf( + `WARNING: It seems that publicaly visible ip: [%s] does not match your local machines ip: [%s]. +You should probaly need to do port forwarding on your router: %s.`, + publicIP, + outboundIP, + forwardInfo, + ) + + } + + return publicIP + }, protocol: options.Protocol, proposalAnnouncementStopped: &sync.WaitGroup{}, } } +func locationResolver(options CommandOptions) location.Resolver { + switch { + case options.LocationCountry != "": + return location.NewResolverFake(options.LocationCountry) + default: + return location.NewResolver(filepath.Join(options.DirectoryConfig, options.LocationDatabase)) + } +} + // TODO this function can be aligned with client function when client and server options will merge into func getNetworkDefinition(options CommandOptions) metadata.NetworkDefinition { network := metadata.DefaultNetwork diff --git a/cmd/commands/server/options.go b/cmd/commands/server/options.go index c09f88366d..15b04caab7 100644 --- a/cmd/commands/server/options.go +++ b/cmd/commands/server/options.go @@ -53,8 +53,6 @@ type CommandOptions struct { Localnet bool } -const defaultLocationDatabase = "GeoLite2-Country.mmdb" - // ParseArguments parses CLI flags and adds to CommandOptions structure func ParseArguments(args []string) (options CommandOptions, err error) { flags := flag.NewFlagSet(args[0], flag.ContinueOnError) @@ -112,7 +110,7 @@ func ParseArguments(args []string) (options CommandOptions, err error) { flags.StringVar( &options.LocationDatabase, "location.database", - defaultLocationDatabase, + "GeoLite2-Country.mmdb", "Service location autodetect database of GeoLite2 format e.g. http://dev.maxmind.com/geoip/geoip2/geolite2/", ) flags.StringVar(