瀏覽代碼

Fixes:
- server_test SLOK test now passes
- web server sends status response
- client status response handler deals with
legacy non-JSON case
- tunnel.IsClosed() checks, which blocked
final status requests, are removed

Rod Hynes 9 年之前
父節點
當前提交
95f20f49a0
共有 4 個文件被更改,包括 32 次插入38 次删除
  1. 10 6
      psiphon/server/server_test.go
  2. 3 1
      psiphon/server/webServer.go
  3. 18 15
      psiphon/serverApi.go
  4. 1 16
      psiphon/tunnel.go

+ 10 - 6
psiphon/server/server_test.go

@@ -287,6 +287,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
 	clientConfig.TunnelProtocol = runConfig.tunnelProtocol
 	clientConfig.LocalSocksProxyPort = localSOCKSProxyPort
 	clientConfig.LocalHttpProxyPort = localHTTPProxyPort
+	clientConfig.ReportSLOKs = true
 
 	err = psiphon.InitDataStore(clientConfig)
 	if err != nil {
@@ -347,7 +348,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
 		defer controllerWaitGroup.Done()
 		controller.Run(controllerShutdownBroadcast)
 	}()
-	defer func() {
+	stopClient := func() {
 		close(controllerShutdownBroadcast)
 
 		shutdownTimeout := time.NewTimer(20 * time.Second)
@@ -363,7 +364,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
 		case <-shutdownTimeout.C:
 			t.Fatalf("controller shutdown timeout exceeded")
 		}
-	}()
+	}
 
 	// Test: tunnels must be established, and correct homepage
 	// must be received, within 30 seconds
@@ -410,6 +411,9 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
 		}
 	}
 
+	// Stop client to trigger a final status request and receive SLOK payload
+	stopClient()
+
 	if !runConfig.denyTrafficRules {
 		waitOnNotification(t, slokSeeded, timeoutSignal, "SLOK seeded timeout exceeded")
 	}
@@ -719,7 +723,7 @@ func paveOSLConfigFile(t *testing.T, oslConfigFilename string) string {
           "SeedSpecs" : [
             {
               "ID" : "IXHWfVgWFkEKvgqsjmnJuN3FpaGuCzQMETya+DSQvsk=",
-              "UpstreamSubnets" : ["0.0.0.0/32"],
+              "UpstreamSubnets" : ["0.0.0.0/0"],
               "Targets" :
               {
                   "BytesRead" : 1,
@@ -729,7 +733,7 @@ func paveOSLConfigFile(t *testing.T, oslConfigFilename string) string {
             },
             {
               "ID" : "qvpIcORLE2Pi5TZmqRtVkEp+OKov0MhfsYPLNV7FYtI=",
-              "UpstreamSubnets" : ["0.0.0.0/32"],
+              "UpstreamSubnets" : ["0.0.0.0/0"],
               "Targets" :
               {
                   "BytesRead" : 1,
@@ -739,7 +743,7 @@ func paveOSLConfigFile(t *testing.T, oslConfigFilename string) string {
             }
           ],
           "SeedSpecThreshold" : 2,
-          "SeedPeriodNanoseconds" : 1000000,
+          "SeedPeriodNanoseconds" : 10000000000,
           "SeedPeriodKeySplits": [
             {
               "Total": 2,
@@ -754,7 +758,7 @@ func paveOSLConfigFile(t *testing.T, oslConfigFilename string) string {
 	propagationChannelID, _ := common.MakeRandomStringHex(8)
 
 	now := time.Now().UTC()
-	epoch := now.Truncate(1 * time.Millisecond)
+	epoch := now.Truncate(10 * time.Second)
 	epochStr := epoch.Format(time.RFC3339Nano)
 
 	oslConfigJSON := fmt.Sprintf(

+ 3 - 1
psiphon/server/webServer.go

@@ -285,8 +285,9 @@ func (webServer *webServer) statusHandler(w http.ResponseWriter, r *http.Request
 
 	params, err := convertHTTPRequestToAPIRequest(w, r, "statusData")
 
+	var responsePayload []byte
 	if err == nil {
-		_, err = dispatchAPIRequestHandler(
+		responsePayload, err = dispatchAPIRequestHandler(
 			webServer.support,
 			protocol.PSIPHON_WEB_API_PROTOCOL,
 			webServer.lookupGeoIPData(params),
@@ -301,6 +302,7 @@ func (webServer *webServer) statusHandler(w http.ResponseWriter, r *http.Request
 	}
 
 	w.WriteHeader(http.StatusOK)
+	w.Write(responsePayload)
 }
 
 func (webServer *webServer) clientVerificationHandler(w http.ResponseWriter, r *http.Request) {

+ 18 - 15
psiphon/serverApi.go

@@ -357,26 +357,29 @@ func (serverContext *ServerContext) DoStatusRequest(tunnel *Tunnel) error {
 
 	confirmStatusRequestPayload(statusPayloadInfo)
 
-	var statusResponse protocol.StatusResponse
-	err = json.Unmarshal(response, &statusResponse)
-	if err != nil {
-		return common.ContextError(err)
-	}
+	if len(response) > 0 {
 
-	for _, slok := range statusResponse.SeedPayload.SLOKs {
-		duplicate, err := SetSLOK(slok.ID, slok.Key)
+		var statusResponse protocol.StatusResponse
+		err = json.Unmarshal(response, &statusResponse)
 		if err != nil {
+			return common.ContextError(err)
+		}
 
-			NoticeAlert("SetSLOK failed: %s", common.ContextError(err))
+		for _, slok := range statusResponse.SeedPayload.SLOKs {
+			duplicate, err := SetSLOK(slok.ID, slok.Key)
+			if err != nil {
 
-			// Proceed with next SLOK. Also, no immediate retry.
-			// For an ongoing session, another status request will occur within
-			// PSIPHON_API_STATUS_REQUEST_PERIOD_MIN/MAX and the server will
-			// resend the same SLOKs, giving another opportunity to store.
-		}
+				NoticeAlert("SetSLOK failed: %s", common.ContextError(err))
+
+				// Proceed with next SLOK. Also, no immediate retry.
+				// For an ongoing session, another status request will occur within
+				// PSIPHON_API_STATUS_REQUEST_PERIOD_MIN/MAX and the server will
+				// resend the same SLOKs, giving another opportunity to store.
+			}
 
-		if tunnel.config.ReportSLOKs {
-			NoticeSLOKSeeded(base64.StdEncoding.EncodeToString(slok.ID), duplicate)
+			if tunnel.config.ReportSLOKs {
+				NoticeSLOKSeeded(base64.StdEncoding.EncodeToString(slok.ID), duplicate)
+			}
 		}
 	}
 

+ 1 - 16
psiphon/tunnel.go

@@ -202,7 +202,7 @@ func EstablishTunnel(
 
 // Close stops operating the tunnel and closes the underlying connection.
 // Supports multiple and/or concurrent calls to Close().
-// When isDicarded is set, operateTunnel will not attempt to send final
+// When isDiscarded is set, operateTunnel will not attempt to send final
 // status requests.
 func (tunnel *Tunnel) Close(isDiscarded bool) {
 
@@ -231,13 +231,6 @@ func (tunnel *Tunnel) Close(isDiscarded bool) {
 	}
 }
 
-// IsClosed returns the tunnel's closed status.
-func (tunnel *Tunnel) IsClosed() bool {
-	tunnel.mutex.Lock()
-	defer tunnel.mutex.Unlock()
-	return tunnel.isClosed
-}
-
 // IsDiscarded returns the tunnel's discarded flag.
 func (tunnel *Tunnel) IsDiscarded() bool {
 	tunnel.mutex.Lock()
@@ -252,10 +245,6 @@ func (tunnel *Tunnel) IsDiscarded() bool {
 func (tunnel *Tunnel) SendAPIRequest(
 	name string, requestPayload []byte) ([]byte, error) {
 
-	if tunnel.IsClosed() {
-		return nil, common.ContextError(errors.New("tunnel is closed"))
-	}
-
 	ok, responsePayload, err := tunnel.sshClient.Conn.SendRequest(
 		name, true, requestPayload)
 
@@ -275,10 +264,6 @@ func (tunnel *Tunnel) SendAPIRequest(
 func (tunnel *Tunnel) Dial(
 	remoteAddr string, alwaysTunnel bool, downstreamConn net.Conn) (conn net.Conn, err error) {
 
-	if tunnel.IsClosed() {
-		return nil, common.ContextError(errors.New("tunnel is closed"))
-	}
-
 	type tunnelDialResult struct {
 		sshPortForwardConn net.Conn
 		err                error