Browse Source

Stub in psinet database component

Rod Hynes 9 years ago
parent
commit
92f92b3aa1

+ 24 - 3
psiphon/server/api.go

@@ -49,7 +49,11 @@ type requestJSONObject map[string]interface{}
 // clients.
 //
 func sshAPIRequestHandler(
-	config *Config, geoIPData GeoIPData, name string, requestPayload []byte) ([]byte, error) {
+	config *Config,
+	psinetDatabase *PsinetDatabase,
+	geoIPData GeoIPData,
+	name string,
+	requestPayload []byte) ([]byte, error) {
 
 	// Note: for SSH requests, MAX_API_PARAMS_SIZE is implicitly enforced
 	// by max SSH reqest packet size.
@@ -62,7 +66,7 @@ func sshAPIRequestHandler(
 
 	switch name {
 	case psiphon.SERVER_API_HANDSHAKE_REQUEST_NAME:
-		return handshakeAPIRequestHandler(config, geoIPData, params)
+		return handshakeAPIRequestHandler(config, psinetDatabase, geoIPData, params)
 	case psiphon.SERVER_API_CONNECTED_REQUEST_NAME:
 		return connectedAPIRequestHandler(config, geoIPData, params)
 	case psiphon.SERVER_API_STATUS_REQUEST_NAME:
@@ -79,7 +83,10 @@ func sshAPIRequestHandler(
 // connection; the response tells the client what homepage to open, what
 // stats to record, etc.
 func handshakeAPIRequestHandler(
-	config *Config, geoIPData GeoIPData, params requestJSONObject) ([]byte, error) {
+	config *Config,
+	psinetDatabase *PsinetDatabase,
+	geoIPData GeoIPData,
+	params requestJSONObject) ([]byte, error) {
 
 	// Note: ignoring "known_servers" params
 
@@ -110,6 +117,20 @@ func handshakeAPIRequestHandler(
 		ServerTimestamp      string              `json:"server_timestamp"`
 	}
 
+	handshakeResponse.Homepages = psinetDatabase.GetHomepages(
+		"", "", "") // TODO: sponsorID, clientRegion, clientPlatform)
+
+	handshakeResponse.UpgradeClientVersion = psinetDatabase.GetUpgradeClientVersion(
+		"") // TODO: clientVersion)
+
+	handshakeResponse.HttpsRequestRegexes = psinetDatabase.GetHttpsRequestRegexes(
+		"", "", "") // TODO: sponsorID, clientRegion, clientPlatform)
+
+	handshakeResponse.EncodedServerList = psinetDatabase.DiscoverServers(
+		"", 0) // TODO: propagationChannelID, discoveryValue)
+
+	handshakeResponse.ClientRegion = geoIPData.Country
+
 	handshakeResponse.ServerTimestamp = psiphon.GetCurrentTimestamp()
 
 	responsePayload, err := json.Marshal(handshakeResponse)

+ 4 - 0
psiphon/server/config.go

@@ -105,6 +105,10 @@ type Config struct {
 	// set, redis is used to store per-session GeoIP information.
 	RedisServerAddress string
 
+	// PsinetDatabaseFilename is the path of the Psiphon automation
+	// jsonpickle format Psiphon API data file.
+	PsinetDatabaseFilename string
+
 	// HostID is the ID of the server host; this is used for API
 	// event logging.
 	HostID string

+ 72 - 0
psiphon/server/psinet.go

@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016, Psiphon Inc.
+ * All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package server
+
+// PsinetDatabase serves Psiphon API data requests. It's safe for
+// concurrent usage.
+type PsinetDatabase struct {
+}
+
+// NewPsinetDatabase initializes a PsinetDatabase. It loads the specified
+// file, which should be in the Psiphon automation jsonpickle format, and
+// prepares to serve data requests.
+// The input "" is valid and returns a functional PsinetDatabase with no
+// data.
+func NewPsinetDatabase(filename string) (*PsinetDatabase, error) {
+
+	// TODO: implement
+
+	return &PsinetDatabase{}, nil
+}
+
+// GetHomepages returns a list of  home pages for the specified sponsor,
+// region, and platform.
+func (psinet *PsinetDatabase) GetHomepages(sponsorID, clientRegion, clientPlatform string) []string {
+
+	// TODO: implement
+
+	return make([]string, 0)
+}
+
+// GetUpgradeClientVersion returns a new client version when an upgrade is
+// indicated for the specified client current version. The result is "" when
+// no upgrade is available.
+func (psinet *PsinetDatabase) GetUpgradeClientVersion(clientVersion string) string {
+
+	// TODO: implement
+
+	return ""
+}
+
+// GetHttpsRequestRegexes returns bytes transferred stats regexes for the
+// specified client inputs.
+func (psinet *PsinetDatabase) GetHttpsRequestRegexes(sponsorID, clientRegion, clientPlatform string) []map[string]string {
+
+	return make([]map[string]string, 0)
+}
+
+// DiscoverServers selects new encoded server entries to be "discovered" by
+// the client, using the discoveryValue as the input into the discovery algorithm.
+func (psinet *PsinetDatabase) DiscoverServers(propagationChannelID string, discoveryValue int) []string {
+
+	// TODO: implement
+
+	return make([]string, 0)
+}

+ 8 - 2
psiphon/server/services.go

@@ -58,6 +58,12 @@ func RunServices(encodedConfigs [][]byte) error {
 		return psiphon.ContextError(err)
 	}
 
+	psinetDatabase, err := NewPsinetDatabase(config.PsinetDatabaseFilename)
+	if err != nil {
+		log.WithContextFields(LogFields{"error": err}).Error("init PsinetDatabase failed")
+		return psiphon.ContextError(err)
+	}
+
 	if config.UseRedis() {
 		err = InitRedis(config)
 		if err != nil {
@@ -70,7 +76,7 @@ func RunServices(encodedConfigs [][]byte) error {
 	shutdownBroadcast := make(chan struct{})
 	errors := make(chan error)
 
-	tunnelServer, err := NewTunnelServer(config, shutdownBroadcast)
+	tunnelServer, err := NewTunnelServer(config, psinetDatabase, shutdownBroadcast)
 	if err != nil {
 		log.WithContextFields(LogFields{"error": err}).Error("init tunnel server failed")
 		return psiphon.ContextError(err)
@@ -97,7 +103,7 @@ func RunServices(encodedConfigs [][]byte) error {
 		waitGroup.Add(1)
 		go func() {
 			defer waitGroup.Done()
-			err := RunWebServer(config, shutdownBroadcast)
+			err := RunWebServer(config, psinetDatabase, shutdownBroadcast)
 			select {
 			case errors <- err:
 			default:

+ 13 - 3
psiphon/server/tunnelServer.go

@@ -52,9 +52,12 @@ type TunnelServer struct {
 
 // NewTunnelServer initializes a new tunnel server.
 func NewTunnelServer(
-	config *Config, shutdownBroadcast <-chan struct{}) (*TunnelServer, error) {
+	config *Config,
+	psinetDatabase *PsinetDatabase,
+	shutdownBroadcast <-chan struct{}) (*TunnelServer, error) {
 
-	sshServer, err := newSSHServer(config, shutdownBroadcast)
+	sshServer, err := newSSHServer(
+		config, psinetDatabase, shutdownBroadcast)
 	if err != nil {
 		return nil, psiphon.ContextError(err)
 	}
@@ -180,6 +183,7 @@ type sshClientID uint64
 
 type sshServer struct {
 	config            *Config
+	psinetDatabase    *PsinetDatabase
 	shutdownBroadcast <-chan struct{}
 	sshHostKey        ssh.Signer
 	nextClientID      sshClientID
@@ -190,6 +194,7 @@ type sshServer struct {
 
 func newSSHServer(
 	config *Config,
+	psinetDatabase *PsinetDatabase,
 	shutdownBroadcast <-chan struct{}) (*sshServer, error) {
 
 	privateKey, err := ssh.ParseRawPrivateKey([]byte(config.SSHPrivateKey))
@@ -205,6 +210,7 @@ func newSSHServer(
 
 	return &sshServer{
 		config:            config,
+		psinetDatabase:    psinetDatabase,
 		shutdownBroadcast: shutdownBroadcast,
 		sshHostKey:        signer,
 		nextClientID:      1,
@@ -606,7 +612,11 @@ func (sshClient *sshClient) runClient(
 
 			// requests are processed serially; responses must be sent in request order.
 			responsePayload, err := sshAPIRequestHandler(
-				sshClient.sshServer.config, sshClient.geoIPData, request.Type, request.Payload)
+				sshClient.sshServer.config,
+				sshClient.sshServer.psinetDatabase,
+				sshClient.geoIPData,
+				request.Type,
+				request.Payload)
 
 			if err == nil {
 				err = request.Reply(true, responsePayload)

+ 13 - 5
psiphon/server/webServer.go

@@ -33,8 +33,9 @@ import (
 )
 
 type webServer struct {
-	serveMux *http.ServeMux
-	config   *Config
+	serveMux       *http.ServeMux
+	config         *Config
+	psinetDatabase *PsinetDatabase
 }
 
 // RunWebServer runs a web server which supports tunneled and untunneled
@@ -51,10 +52,14 @@ type webServer struct {
 // The API is compatible with all tunnel-core clients but not backwards
 // compatible with older clients.
 //
-func RunWebServer(config *Config, shutdownBroadcast <-chan struct{}) error {
+func RunWebServer(
+	config *Config,
+	psinetDatabase *PsinetDatabase,
+	shutdownBroadcast <-chan struct{}) error {
 
 	webServer := &webServer{
-		config: config,
+		config:         config,
+		psinetDatabase: psinetDatabase,
 	}
 
 	serveMux := http.NewServeMux()
@@ -188,7 +193,10 @@ func (webServer *webServer) handshakeHandler(w http.ResponseWriter, r *http.Requ
 	var responsePayload []byte
 	if err == nil {
 		responsePayload, err = handshakeAPIRequestHandler(
-			webServer.config, webServer.lookupGeoIPData(params), params)
+			webServer.config,
+			webServer.psinetDatabase,
+			webServer.lookupGeoIPData(params),
+			params)
 	}
 
 	if err != nil {