Procházet zdrojové kódy

Merge pull request #87 from adam-p/windows-ui2

Added notice that displays the available server egress regions.
Rod Hynes před 11 roky
rodič
revize
feca90914b
4 změnil soubory, kde provedl 52 přidání a 4 odebrání
  1. 1 0
      psiphon/controller.go
  2. 34 0
      psiphon/dataStore.go
  3. 5 0
      psiphon/notice.go
  4. 12 4
      psiphon/serverApi.go

+ 1 - 0
psiphon/controller.go

@@ -116,6 +116,7 @@ func NewController(config *Config) (controller *Controller, err error) {
 func (controller *Controller) Run(shutdownBroadcast <-chan struct{}) {
 	NoticeBuildInfo()
 	NoticeCoreVersion(VERSION)
+	ReportAvailableRegions()
 
 	// Start components
 

+ 34 - 0
psiphon/dataStore.go

@@ -79,6 +79,7 @@ func InitDataStore(config *Config) (err error) {
              rank integer not null unique,
              region text not null,
              data blob not null);
+        create index if not exists idx_serverEntry_region on serverEntry(region);
         create table if not exists serverEntryProtocol
             (serverEntryId text not null,
              protocol text not null,
@@ -256,6 +257,11 @@ func StoreServerEntries(serverEntries []*ServerEntry, replaceIfExists bool) erro
 			return ContextError(err)
 		}
 	}
+
+	// Since there has possibly been a significant change in the server entries,
+	// take this opportunity to update the available egress regions.
+	ReportAvailableRegions()
+
 	return nil
 }
 
@@ -517,6 +523,34 @@ func CountServerEntries(region, protocol string) int {
 	return count
 }
 
+// ReportAvailableRegions prints a notice with the available egress regions.
+func ReportAvailableRegions() {
+	checkInitDataStore()
+
+	// TODO: For consistency, regions-per-protocol should be used
+
+	rows, err := singleton.db.Query("select distinct(region) from serverEntry;")
+	if err != nil {
+		NoticeAlert("failed to query data store for available regions: %s", ContextError(err))
+		return
+	}
+	defer rows.Close()
+
+	var regions []string
+
+	for rows.Next() {
+		var region string
+		err = rows.Scan(&region)
+		if err != nil {
+			NoticeAlert("failed to retrieve available regions from data store: %s", ContextError(err))
+			return
+		}
+		regions = append(regions, region)
+	}
+
+	NoticeAvailableEgressRegions(regions)
+}
+
 // GetServerEntryIpAddresses returns an array containing
 // all stored server IP addresses.
 func GetServerEntryIpAddresses() (ipAddresses []string, err error) {

+ 5 - 0
psiphon/notice.go

@@ -109,6 +109,11 @@ func NoticeCandidateServers(region, protocol string, count int) {
 	outputNotice("CandidateServers", false, "region", region, "protocol", protocol, "count", count)
 }
 
+// NoticeAvailableEgressRegions is what regions are available for egress from
+func NoticeAvailableEgressRegions(regions []string) {
+	outputNotice("AvailableEgressRegions", false, "regions", regions)
+}
+
 // NoticeConnectingServer is details on a connection attempt
 func NoticeConnectingServer(ipAddress, region, protocol, frontingAddress string) {
 	outputNotice("ConnectingServer", false, "ipAddress", ipAddress, "region",

+ 12 - 4
psiphon/serverApi.go

@@ -216,6 +216,8 @@ func (session *Session) doHandshakeRequest() error {
 
 	session.clientRegion = handshakeConfig.ClientRegion
 
+	var decodedServerEntries []*ServerEntry
+
 	// Store discovered server entries
 	for _, encodedServerEntry := range handshakeConfig.EncodedServerList {
 		serverEntry, err := DecodeServerEntry(encodedServerEntry)
@@ -227,10 +229,16 @@ func (session *Session) doHandshakeRequest() error {
 			// Skip this entry and continue with the next one
 			continue
 		}
-		err = StoreServerEntry(serverEntry, true)
-		if err != nil {
-			return ContextError(err)
-		}
+
+		decodedServerEntries = append(decodedServerEntries, serverEntry)
+	}
+
+	// The reason we are storing the entire array of server entries at once rather
+	// than one at a time is that some desirable side-effects get triggered by
+	// StoreServerEntries that don't get triggered by StoreServerEntry.
+	err = StoreServerEntries(decodedServerEntries, true)
+	if err != nil {
+		return ContextError(err)
 	}
 
 	// TODO: formally communicate the sponsor and upgrade info to an