Browse Source

Merge branch 'master' into staging-client

Rod Hynes 3 years ago
parent
commit
2c2e4fb076

+ 4 - 5
MobileLibrary/Android/PsiphonTunnel/PsiphonTunnel.java

@@ -127,7 +127,7 @@ public class PsiphonTunnel {
         default public void onStoppedWaitingForNetworkConnectivity() {}
         default public void onStoppedWaitingForNetworkConnectivity() {}
         default public void onActiveAuthorizationIDs(List<String> authorizations) {}
         default public void onActiveAuthorizationIDs(List<String> authorizations) {}
         default public void onTrafficRateLimits(long upstreamBytesPerSecond, long downstreamBytesPerSecond) {}
         default public void onTrafficRateLimits(long upstreamBytesPerSecond, long downstreamBytesPerSecond) {}
-        default public void onApplicationParameter(String key, Object value) {}
+        default public void onApplicationParameters(Object parameters) {}
         default public void onServerAlert(String reason, String subject, List<String> actionURLs) {}
         default public void onServerAlert(String reason, String subject, List<String> actionURLs) {}
         default public void onExiting() {}
         default public void onExiting() {}
     }
     }
@@ -1011,10 +1011,9 @@ public class PsiphonTunnel {
                       enableUdpGwKeepalive();
                       enableUdpGwKeepalive();
                     }
                     }
                 }
                 }
-            } else if (noticeType.equals("ApplicationParameter")) {
-                mHostService.onApplicationParameter(
-                    notice.getJSONObject("data").getString("key"),
-                    notice.getJSONObject("data").get("value"));
+            } else if (noticeType.equals("ApplicationParameters")) {
+                mHostService.onApplicationParameters(
+                    notice.getJSONObject("data").get("parameters"));
             } else if (noticeType.equals("ServerAlert")) {
             } else if (noticeType.equals("ServerAlert")) {
                 JSONArray actionURLs = notice.getJSONObject("data").getJSONArray("actionURLs");
                 JSONArray actionURLs = notice.getJSONObject("data").getJSONArray("actionURLs");
                 ArrayList<String> actionURLsList = new ArrayList<String>();
                 ArrayList<String> actionURLsList = new ArrayList<String>();

+ 1 - 1
MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h

@@ -297,7 +297,7 @@ WWAN or vice versa or VPN state changed
 /*!
 /*!
  Called when tunnel-core receives "ApplicationParameters" from the server.
  Called when tunnel-core receives "ApplicationParameters" from the server.
  */
  */
-- (void)onApplicationParameter:(NSString * _Nonnull)key :(id _Nonnull)value;
+- (void)onApplicationParameters:(NSDictionary * _Nonnull)parameters;
 
 
 @end
 @end
 
 

+ 6 - 15
MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.m

@@ -1146,26 +1146,17 @@ typedef NS_ERROR_ENUM(PsiphonTunnelErrorDomain, PsiphonTunnelErrorCode) {
             });
             });
         }
         }
     }
     }
-    else if ([noticeType isEqualToString:@"ApplicationParameter"]) {
+    else if ([noticeType isEqualToString:@"ApplicationParameters"]) {
         
         
-        id key = [notice valueForKeyPath:@"data.key"];
-        if (![key isKindOfClass:[NSString class]]) {
-            [self logMessage:[NSString stringWithFormat: @"ApplicationParameter notice missing data.key: %@", noticeJSON]];
+        id parameters = [notice valueForKeyPath:@"data.parameters"];
+        if (![parameters isKindOfClass:[NSDictionary class]]) {
+            [self logMessage:[NSString stringWithFormat: @"ApplicationParameters notice missing data.parameters: %@", noticeJSON]];
             return;
             return;
         }
         }
 
 
-        id maybeValue = [notice valueForKeyPath:@"data.value"];
-        if (!maybeValue) {
-            [self logMessage:[NSString stringWithFormat: @"ApplicationParameter notice missing data.value: %@", noticeJSON]];
-            return;
-        }
-
-        // value is nil if data.value is NSNull.
-        id value = maybeValue == [NSNull null] ? nil : maybeValue;
-
-        if ([self.tunneledAppDelegate respondsToSelector:@selector(onApplicationParameter::)]) {
+        if ([self.tunneledAppDelegate respondsToSelector:@selector(onApplicationParameters:)]) {
             dispatch_sync(self->callbackQueue, ^{
             dispatch_sync(self->callbackQueue, ^{
-                [self.tunneledAppDelegate onApplicationParameter:(NSString *)key :value];
+                [self.tunneledAppDelegate onApplicationParameters:parameters];
             });
             });
         }
         }
     }
     }

+ 7 - 8
psiphon/common/parameters/parameters.go

@@ -32,10 +32,10 @@ snapshot so that related parameters, such as two Ints representing a range; or
 a more complex series of related parameters; may be read in an atomic and
 a more complex series of related parameters; may be read in an atomic and
 consistent way. For example:
 consistent way. For example:
 
 
-    p := params.Get()
-    min := p.Int("Min")
-    max := p.Int("Max")
-    p = nil
+	p := params.Get()
+	min := p.Int("Min")
+	max := p.Int("Max")
+	p = nil
 
 
 For long-running operations, it is recommended to set any pointer to the
 For long-running operations, it is recommended to set any pointer to the
 snapshot to nil to allow garbage collection of old snaphots in cases where the
 snapshot to nil to allow garbage collection of old snaphots in cases where the
@@ -508,7 +508,7 @@ var defaultParameters = map[string]struct {
 	//
 	//
 	// MeekCookieMaxPadding cannot exceed common.OBFUSCATE_SEED_LENGTH.
 	// MeekCookieMaxPadding cannot exceed common.OBFUSCATE_SEED_LENGTH.
 	//
 	//
-	// MeekMinTLSPadding/MeekMinTLSPadding are subject to TLS server limitations.
+	// MeekMinTLSPadding/MeekMaxTLSPadding are subject to TLS server limitations.
 	//
 	//
 	// MeekMinLimitRequestPayloadLength/MeekMaxLimitRequestPayloadLength
 	// MeekMinLimitRequestPayloadLength/MeekMaxLimitRequestPayloadLength
 	// cannot exceed server.MEEK_MAX_REQUEST_PAYLOAD_LENGTH.
 	// cannot exceed server.MEEK_MAX_REQUEST_PAYLOAD_LENGTH.
@@ -1119,9 +1119,8 @@ func (p *Parameters) Get() ParametersAccessor {
 //
 //
 // Customizations include:
 // Customizations include:
 //
 //
-// - customNetworkLatencyMultiplier, which overrides NetworkLatencyMultiplier
-//   for this instance only.
-//
+//   - customNetworkLatencyMultiplier, which overrides NetworkLatencyMultiplier
+//     for this instance only.
 func (p *Parameters) GetCustom(
 func (p *Parameters) GetCustom(
 	customNetworkLatencyMultiplier float64) ParametersAccessor {
 	customNetworkLatencyMultiplier float64) ParametersAccessor {
 
 

+ 10 - 2
psiphon/common/quic/gquic-go/packet_packer.go

@@ -21,7 +21,11 @@ type packer interface {
 	PackConnectionClose(*wire.ConnectionCloseFrame) (*packedPacket, error)
 	PackConnectionClose(*wire.ConnectionCloseFrame) (*packedPacket, error)
 
 
 	HandleTransportParameters(*handshake.TransportParameters)
 	HandleTransportParameters(*handshake.TransportParameters)
-	ChangeDestConnectionID(protocol.ConnectionID)
+
+	// [Psiphon]
+	// - Add error return value.
+	ChangeDestConnectionID(protocol.ConnectionID) error
+	// [Psiphon]
 }
 }
 
 
 type packedPacket struct {
 type packedPacket struct {
@@ -477,8 +481,12 @@ func (p *packetPacker) canSendData(encLevel protocol.EncryptionLevel) bool {
 	return encLevel == protocol.EncryptionForwardSecure
 	return encLevel == protocol.EncryptionForwardSecure
 }
 }
 
 
-func (p *packetPacker) ChangeDestConnectionID(connID protocol.ConnectionID) {
+func (p *packetPacker) ChangeDestConnectionID(connID protocol.ConnectionID) error {
 	p.destConnID = connID
 	p.destConnID = connID
+
+	// [Psiphon]
+	return nil
+	// [Psiphon]
 }
 }
 
 
 func (p *packetPacker) HandleTransportParameters(params *handshake.TransportParameters) {
 func (p *packetPacker) HandleTransportParameters(params *handshake.TransportParameters) {

+ 6 - 2
psiphon/common/quic/gquic-go/packet_packer_legacy.go

@@ -459,8 +459,12 @@ func (p *packetPackerLegacy) canSendData(encLevel protocol.EncryptionLevel) bool
 	return encLevel == protocol.EncryptionForwardSecure
 	return encLevel == protocol.EncryptionForwardSecure
 }
 }
 
 
-func (p *packetPackerLegacy) ChangeDestConnectionID(connID protocol.ConnectionID) {
-	panic("changing connection IDs not supported by gQUIC")
+func (p *packetPackerLegacy) ChangeDestConnectionID(connID protocol.ConnectionID) error {
+	// [Psiphon]
+	// - Don't panic, since this may be invoked due to invalid input.
+	//panic("changing connection IDs not supported by gQUIC")
+	return errors.New("changing connection IDs not supported by gQUIC")
+	// [Psiphon]
 }
 }
 
 
 func (p *packetPackerLegacy) HandleTransportParameters(params *handshake.TransportParameters) {
 func (p *packetPackerLegacy) HandleTransportParameters(params *handshake.TransportParameters) {

+ 7 - 1
psiphon/common/quic/gquic-go/session.go

@@ -663,7 +663,13 @@ func (s *session) handlePacketImpl(p *receivedPacket) error {
 	if s.perspective == protocol.PerspectiveClient && !s.receivedFirstPacket && hdr.IsLongHeader && !hdr.SrcConnectionID.Equal(s.destConnID) {
 	if s.perspective == protocol.PerspectiveClient && !s.receivedFirstPacket && hdr.IsLongHeader && !hdr.SrcConnectionID.Equal(s.destConnID) {
 		s.logger.Debugf("Received first packet. Switching destination connection ID to: %s", hdr.SrcConnectionID)
 		s.logger.Debugf("Received first packet. Switching destination connection ID to: %s", hdr.SrcConnectionID)
 		s.destConnID = hdr.SrcConnectionID
 		s.destConnID = hdr.SrcConnectionID
-		s.packer.ChangeDestConnectionID(s.destConnID)
+		err = s.packer.ChangeDestConnectionID(s.destConnID)
+		// [Psiphon]
+		// - Check error return value.
+		if err != nil {
+			return err
+		}
+		// [Psiphon]
 	}
 	}
 
 
 	s.receivedFirstPacket = true
 	s.receivedFirstPacket = true

+ 23 - 25
psiphon/notice.go

@@ -111,7 +111,6 @@ func GetEmitNetworkParameters() bool {
 // - "timestamp": UTC timezone, RFC3339Milli format timestamp for notice event
 // - "timestamp": UTC timezone, RFC3339Milli format timestamp for notice event
 //
 //
 // See the Notice* functions for details on each notice meaning and payload.
 // See the Notice* functions for details on each notice meaning and payload.
-//
 func SetNoticeWriter(writer io.Writer) {
 func SetNoticeWriter(writer io.Writer) {
 
 
 	singletonNoticeLogger.mutex.Lock()
 	singletonNoticeLogger.mutex.Lock()
@@ -122,25 +121,24 @@ func SetNoticeWriter(writer io.Writer) {
 
 
 // setNoticeFiles configures files for notice writing.
 // setNoticeFiles configures files for notice writing.
 //
 //
-// - When homepageFilename is not "", homepages are written to the specified file
-//   and omitted from the writer. The file may be read after the Tunnels notice
-//   with count of 1. The file should be opened read-only for reading.
+//   - When homepageFilename is not "", homepages are written to the specified file
+//     and omitted from the writer. The file may be read after the Tunnels notice
+//     with count of 1. The file should be opened read-only for reading.
 //
 //
-// - When rotatingFilename is not "", all notices are are written to the specified
-//   file. Diagnostic notices are omitted from the writer. The file is rotated
-//   when its size exceeds rotatingFileSize. One rotated older file,
-//   <rotatingFilename>.1, is retained. The files may be read at any time; and
-//   should be opened read-only for reading. rotatingSyncFrequency specifies how
-//   many notices are written before syncing the file.
-//   If either rotatingFileSize or rotatingSyncFrequency are <= 0, default values
-//   are used.
+//   - When rotatingFilename is not "", all notices are are written to the specified
+//     file. Diagnostic notices are omitted from the writer. The file is rotated
+//     when its size exceeds rotatingFileSize. One rotated older file,
+//     <rotatingFilename>.1, is retained. The files may be read at any time; and
+//     should be opened read-only for reading. rotatingSyncFrequency specifies how
+//     many notices are written before syncing the file.
+//     If either rotatingFileSize or rotatingSyncFrequency are <= 0, default values
+//     are used.
 //
 //
-// - If an error occurs when writing to a file, an InternalError notice is emitted to
-//   the writer.
+//   - If an error occurs when writing to a file, an InternalError notice is emitted to
+//     the writer.
 //
 //
 // setNoticeFiles closes open homepage or rotating files before applying the new
 // setNoticeFiles closes open homepage or rotating files before applying the new
 // configuration.
 // configuration.
-//
 func setNoticeFiles(
 func setNoticeFiles(
 	homepageFilename string,
 	homepageFilename string,
 	rotatingFilename string,
 	rotatingFilename string,
@@ -952,18 +950,18 @@ func NoticeFragmentor(diagnosticID string, message string) {
 	}
 	}
 }
 }
 
 
-// NoticeApplicationParameters reports application parameters. Each key/value
-// parameter pair is emitted in a distinct notice, and each key/value pair is
-// reported at most once per session for a fixed value.
+// NoticeApplicationParameters reports application parameters.
 func NoticeApplicationParameters(keyValues parameters.KeyValues) {
 func NoticeApplicationParameters(keyValues parameters.KeyValues) {
-	for key, value := range keyValues {
-		repetitionKey := fmt.Sprintf("ApplicationParameterKey-%s", key)
-		outputRepetitiveNotice(
-			repetitionKey, string(value), 0,
-			"ApplicationParameter", 0,
-			"key", key,
-			"value", value)
+
+	// Never emit 'null' instead of empty object
+	if keyValues == nil {
+		keyValues = parameters.KeyValues{}
 	}
 	}
+
+	outputRepetitiveNotice(
+		"ApplicationParameters", fmt.Sprintf("%+v", keyValues), 0,
+		"ApplicationParameters", 0,
+		"parameters", keyValues)
 }
 }
 
 
 // NoticeServerAlert reports server alerts. Each distinct server alert is
 // NoticeServerAlert reports server alerts. Each distinct server alert is