Преглед изворни кода

Library enhancements for Android app integration

- Explicitly enable/disable VpnService/BindToDevice mode
- Asynchronous embedded server list import
Rod Hynes пре 10 година
родитељ
комит
bb37ebde10
1 измењених фајлова са 43 додато и 11 уклоњено
  1. 43 11
      AndroidLibrary/psi/psi.go

+ 43 - 11
AndroidLibrary/psi/psi.go

@@ -26,7 +26,6 @@ package psi
 
 import (
 	"fmt"
-	"log"
 	"sync"
 
 	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon"
@@ -43,7 +42,10 @@ var controller *psiphon.Controller
 var shutdownBroadcast chan struct{}
 var controllerWaitGroup *sync.WaitGroup
 
-func Start(configJson, embeddedServerEntryList string, provider PsiphonProvider) error {
+func Start(
+	configJson, embeddedServerEntryList string,
+	provider PsiphonProvider,
+	useDeviceBinder bool) error {
 
 	if controller != nil {
 		return fmt.Errorf("already started")
@@ -54,8 +56,11 @@ func Start(configJson, embeddedServerEntryList string, provider PsiphonProvider)
 		return fmt.Errorf("error loading configuration file: %s", err)
 	}
 	config.NetworkConnectivityChecker = provider
-	config.DeviceBinder = provider
-	config.DnsServerGetter = provider
+
+	if useDeviceBinder {
+		config.DeviceBinder = provider
+		config.DnsServerGetter = provider
+	}
 
 	psiphon.SetNoticeOutput(psiphon.NewNoticeReceiver(
 		func(notice []byte) {
@@ -69,13 +74,40 @@ func Start(configJson, embeddedServerEntryList string, provider PsiphonProvider)
 		return fmt.Errorf("error initializing datastore: %s", err)
 	}
 
-	serverEntries, err := psiphon.DecodeAndValidateServerEntryList(embeddedServerEntryList)
-	if err != nil {
-		log.Fatalf("error decoding embedded server entry list: %s", err)
-	}
-	err = psiphon.StoreServerEntries(serverEntries, false)
-	if err != nil {
-		log.Fatalf("error storing embedded server entry list: %s", err)
+	// If specified, the embedded server list is loaded and stored. When there
+	// are no server candidates at all, we wait for this import to complete
+	// before starting the Psiphon controller. Otherwise, we import while
+	// concurrently starting the controller to minimize delay before attempting
+	// to connect to existing candidate servers.
+	// If the import fails, an error notice is emitted, but the controller is
+	// still started: either existing candidate servers may suffice, or the
+	// remote server list fetch may obtain candidate servers.
+	// TODO: duplicates logic in psiphonClient.go -- refactor?
+	if embeddedServerEntryList != "" {
+		embeddedServerListWaitGroup := new(sync.WaitGroup)
+		embeddedServerListWaitGroup.Add(1)
+		go func() {
+			defer embeddedServerListWaitGroup.Done()
+			// TODO: stream embedded server list data?
+			serverEntries, err := psiphon.DecodeAndValidateServerEntryList(embeddedServerEntryList)
+			if err != nil {
+				psiphon.NoticeError("error decoding embedded server entry list file: %s", err)
+				return
+			}
+			// Since embedded server list entries may become stale, they will not
+			// overwrite existing stored entries for the same server.
+			err = psiphon.StoreServerEntries(serverEntries, false)
+			if err != nil {
+				psiphon.NoticeError("error storing embedded server entry list data: %s", err)
+				return
+			}
+		}()
+
+		if psiphon.CountServerEntries(config.EgressRegion, config.TunnelProtocol) == 0 {
+			embeddedServerListWaitGroup.Wait()
+		} else {
+			defer embeddedServerListWaitGroup.Wait()
+		}
 	}
 
 	controller, err = psiphon.NewController(config)