Explorar el Código

Merge pull request #176 from mfallone/master

Added -interface flag for server generate.  Refactored GetInterfaceIPAddress
Rod Hynes hace 9 años
padre
commit
410cd9ef7e
Se han modificado 4 ficheros con 39 adiciones y 35 borrados
  1. 8 0
      Server/main.go
  2. 0 1
      psiphon/config.go
  3. 18 33
      psiphon/networkInterface.go
  4. 13 1
      psiphon/server/config.go

+ 8 - 0
Server/main.go

@@ -32,6 +32,7 @@ import (
 func main() {
 
 	var generateServerIPaddress, newConfigFilename, newServerEntryFilename string
+	var networkInterface string
 	var generateWebServerPort, generateSSHServerPort, generateObfuscatedSSHServerPort int
 	var runConfigFilenames stringListFlag
 
@@ -47,6 +48,12 @@ func main() {
 		server.SERVER_ENTRY_FILENAME,
 		"generate new server entry with this `filename`")
 
+	flag.StringVar(
+		&networkInterface,
+		"interface",
+		"",
+		"generate server entry with this `network-interface`")
+
 	flag.StringVar(
 		&generateServerIPaddress,
 		"ipaddress",
@@ -97,6 +104,7 @@ func main() {
 		configFileContents, serverEntryFileContents, err := server.GenerateConfig(
 			&server.GenerateConfigParams{
 				ServerIPAddress:         generateServerIPaddress,
+				ServerNetworkInterface:  networkInterface,
 				WebServerPort:           generateWebServerPort,
 				SSHServerPort:           generateSSHServerPort,
 				ObfuscatedSSHServerPort: generateObfuscatedSSHServerPort,

+ 0 - 1
psiphon/config.go

@@ -168,7 +168,6 @@ type Config struct {
 
 	// ListenInterface specifies which interface to listen on.  If no interface
 	// is provided then listen on 127.0.0.1.
-	// If an invalid interface is provided then listen on localhost (127.0.0.1).
 	// If 'any' is provided then use 0.0.0.0.
 	// If there are multiple IP addresses on an interface use the first IPv4 address.
 	ListenInterface string

+ 18 - 33
psiphon/networkInterface.go

@@ -20,60 +20,45 @@
 package psiphon
 
 import (
+	"errors"
 	"net"
 )
 
 // Take in an interface name ("lo", "eth0", "any") passed from either
-// a config setting or by -interface command line flag and return the IP
+// a config setting, by using the -listenInterface flag on client or
+// -interface flag on server from the command line and return the IP
 // address associated with it.
 // If no interface is provided use the default loopback interface (127.0.0.1).
-// If "any" is passed then listen on 0.0.0.0
+// If "any" is passed then listen on 0.0.0.0 for client (invalid with server)
 func GetInterfaceIPAddress(listenInterface string) (string, error) {
 	var ip net.IP
-
 	if listenInterface == "" {
 		ip = net.ParseIP("127.0.0.1")
+		return ip.String(), nil
 	} else if listenInterface == "any" {
 		ip = net.ParseIP("0.0.0.0")
+		return ip.String(), nil
 	} else {
-		//Get a list of interfaces
-		availableInterfaces, err := net.Interfaces()
+		availableInterfaces, err := net.InterfaceByName(listenInterface)
 		if err != nil {
 			return "", ContextError(err)
 		}
 
-		var selectedInterface net.Interface
-		found := false
-		for _, networkInterface := range availableInterfaces {
-			if listenInterface == networkInterface.Name {
-				NoticeInfo("Using interface: %s", networkInterface.Name)
-				selectedInterface = networkInterface
-				found = true
-				break
-			}
+		addrs, err := availableInterfaces.Addrs()
+		if err != nil {
+			return "", ContextError(err)
 		}
-		if !found {
-			NoticeAlert("Interface not found: %s", listenInterface)
-			ip = net.ParseIP("127.0.0.1")
-		} else {
-			netAddrs, err := selectedInterface.Addrs()
-			if err != nil {
-				return "", ContextError(err)
-			}
-
-			for _, ipAddr := range netAddrs {
-				ip, _, err = net.ParseCIDR(ipAddr.String())
-				if err != nil {
-					return "", ContextError(err)
-				}
-				if ip.To4() != nil {
-					break
-				}
+		for _, addr := range addrs {
+			iptype := addr.(*net.IPNet)
+			if iptype == nil {
+				continue
 			}
+			// TODO: IPv6 support
+			ip = iptype.IP.To4()
+			return ip.String(), nil
 		}
 	}
 
-	NoticeInfo("Listening on IP address: %s", ip.String())
+	return "", ContextError(errors.New("Could not find IP address of specified interface"))
 
-	return ip.String(), nil
 }

+ 13 - 1
psiphon/server/config.go

@@ -355,6 +355,10 @@ type GenerateConfigParams struct {
 	// ServerIPAddress is the public IP address of the server.
 	ServerIPAddress string
 
+	// ServerNetworkInterface is the (optional) nic to expose the server on
+	// when running in unprivileged mode but want to allow external clients to connect.
+	ServerNetworkInterface string
+
 	// WebServerPort is the listening port of the web server.
 	// When <= 0, no web server component is run.
 	WebServerPort int
@@ -453,6 +457,14 @@ func GenerateConfig(params *GenerateConfigParams) ([]byte, []byte, error) {
 		return nil, nil, psiphon.ContextError(err)
 	}
 
+	// Find IP address of the network interface (if not loopback)
+	serverNetworkInterface := params.ServerNetworkInterface
+	serverNetworkInterfaceIP, err := psiphon.GetInterfaceIPAddress(serverNetworkInterface)
+	if err != nil {
+		serverNetworkInterfaceIP = serverIPaddress
+		fmt.Printf("Could not find IP address of nic.  Falling back to %s\n", serverIPaddress)
+	}
+
 	// Assemble config and server entry
 
 	config := &Config{
@@ -492,7 +504,7 @@ func GenerateConfig(params *GenerateConfigParams) ([]byte, []byte, error) {
 	}
 
 	serverEntry := &psiphon.ServerEntry{
-		IpAddress:            serverIPaddress,
+		IpAddress:            serverNetworkInterfaceIP,
 		WebServerPort:        fmt.Sprintf("%d", webServerPort),
 		WebServerSecret:      webServerSecret,
 		WebServerCertificate: strippedWebServerCertificate,