|
|
@@ -80,17 +80,22 @@ func SetNoticeOutput(output io.Writer) {
|
|
|
noticeLogger = log.New(output, "", 0)
|
|
|
}
|
|
|
|
|
|
+const (
|
|
|
+ noticeIsDiagnostic = 1
|
|
|
+ noticeShowUser = 2
|
|
|
+)
|
|
|
+
|
|
|
// outputNotice encodes a notice in JSON and writes it to the output writer.
|
|
|
-func outputNotice(noticeType string, isDiagnostic, showUser bool, args ...interface{}) {
|
|
|
+func outputNotice(noticeType string, noticeFlags uint32, args ...interface{}) {
|
|
|
|
|
|
- if isDiagnostic && !GetEmitDiagnoticNotices() {
|
|
|
+ if (noticeFlags¬iceIsDiagnostic != 0) && !GetEmitDiagnoticNotices() {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
obj := make(map[string]interface{})
|
|
|
noticeData := make(map[string]interface{})
|
|
|
obj["noticeType"] = noticeType
|
|
|
- obj["showUser"] = showUser
|
|
|
+ obj["showUser"] = (noticeFlags¬iceShowUser != 0)
|
|
|
obj["data"] = noticeData
|
|
|
obj["timestamp"] = time.Now().UTC().Format(time.RFC3339)
|
|
|
for i := 0; i < len(args)-1; i += 2 {
|
|
|
@@ -114,22 +119,22 @@ func outputNotice(noticeType string, isDiagnostic, showUser bool, args ...interf
|
|
|
|
|
|
// NoticeInfo is an informational message
|
|
|
func NoticeInfo(format string, args ...interface{}) {
|
|
|
- outputNotice("Info", true, false, "message", fmt.Sprintf(format, args...))
|
|
|
+ outputNotice("Info", noticeIsDiagnostic, "message", fmt.Sprintf(format, args...))
|
|
|
}
|
|
|
|
|
|
// NoticeAlert is an alert message; typically a recoverable error condition
|
|
|
func NoticeAlert(format string, args ...interface{}) {
|
|
|
- outputNotice("Alert", true, false, "message", fmt.Sprintf(format, args...))
|
|
|
+ outputNotice("Alert", noticeIsDiagnostic, "message", fmt.Sprintf(format, args...))
|
|
|
}
|
|
|
|
|
|
// NoticeError is an error message; typically an unrecoverable error condition
|
|
|
func NoticeError(format string, args ...interface{}) {
|
|
|
- outputNotice("Error", true, false, "message", fmt.Sprintf(format, args...))
|
|
|
+ outputNotice("Error", noticeIsDiagnostic, "message", fmt.Sprintf(format, args...))
|
|
|
}
|
|
|
|
|
|
// NoticeCandidateServers is how many possible servers are available for the selected region and protocol
|
|
|
func NoticeCandidateServers(region, protocol string, count int) {
|
|
|
- outputNotice("CandidateServers", false, false, "region", region, "protocol", protocol, "count", count)
|
|
|
+ outputNotice("CandidateServers", 0, "region", region, "protocol", protocol, "count", count)
|
|
|
}
|
|
|
|
|
|
// NoticeAvailableEgressRegions is what regions are available for egress from.
|
|
|
@@ -140,19 +145,19 @@ func NoticeAvailableEgressRegions(regions []string) {
|
|
|
repetitionMessage := strings.Join(sortedRegions, "")
|
|
|
outputRepetitiveNotice(
|
|
|
"AvailableEgressRegions", repetitionMessage, 0,
|
|
|
- "AvailableEgressRegions", false, false, "regions", sortedRegions)
|
|
|
+ "AvailableEgressRegions", 0, "regions", sortedRegions)
|
|
|
}
|
|
|
|
|
|
// NoticeConnectingServer is details on a connection attempt
|
|
|
func NoticeConnectingServer(ipAddress, region, protocol, directTCPDialAddress string, meekConfig *MeekConfig) {
|
|
|
if meekConfig == nil {
|
|
|
- outputNotice("ConnectingServer", true, false,
|
|
|
+ outputNotice("ConnectingServer", noticeIsDiagnostic,
|
|
|
"ipAddress", ipAddress,
|
|
|
"region", region,
|
|
|
"protocol", protocol,
|
|
|
"directTCPDialAddress", directTCPDialAddress)
|
|
|
} else {
|
|
|
- outputNotice("ConnectingServer", true, false,
|
|
|
+ outputNotice("ConnectingServer", noticeIsDiagnostic,
|
|
|
"ipAddress", ipAddress,
|
|
|
"region", region,
|
|
|
"protocol", protocol,
|
|
|
@@ -166,74 +171,74 @@ func NoticeConnectingServer(ipAddress, region, protocol, directTCPDialAddress st
|
|
|
|
|
|
// NoticeActiveTunnel is a successful connection that is used as an active tunnel for port forwarding
|
|
|
func NoticeActiveTunnel(ipAddress, protocol string) {
|
|
|
- outputNotice("ActiveTunnel", true, false, "ipAddress", ipAddress, "protocol", protocol)
|
|
|
+ outputNotice("ActiveTunnel", noticeIsDiagnostic, "ipAddress", ipAddress, "protocol", protocol)
|
|
|
}
|
|
|
|
|
|
// NoticeSocksProxyPortInUse is a failure to use the configured LocalSocksProxyPort
|
|
|
func NoticeSocksProxyPortInUse(port int) {
|
|
|
- outputNotice("SocksProxyPortInUse", false, true, "port", port)
|
|
|
+ outputNotice("SocksProxyPortInUse", noticeShowUser, "port", port)
|
|
|
}
|
|
|
|
|
|
// NoticeListeningSocksProxyPort is the selected port for the listening local SOCKS proxy
|
|
|
func NoticeListeningSocksProxyPort(port int) {
|
|
|
- outputNotice("ListeningSocksProxyPort", false, false, "port", port)
|
|
|
+ outputNotice("ListeningSocksProxyPort", 0, "port", port)
|
|
|
}
|
|
|
|
|
|
// NoticeSocksProxyPortInUse is a failure to use the configured LocalHttpProxyPort
|
|
|
func NoticeHttpProxyPortInUse(port int) {
|
|
|
- outputNotice("HttpProxyPortInUse", false, true, "port", port)
|
|
|
+ outputNotice("HttpProxyPortInUse", noticeShowUser, "port", port)
|
|
|
}
|
|
|
|
|
|
// NoticeListeningSocksProxyPort is the selected port for the listening local HTTP proxy
|
|
|
func NoticeListeningHttpProxyPort(port int) {
|
|
|
- outputNotice("ListeningHttpProxyPort", false, false, "port", port)
|
|
|
+ outputNotice("ListeningHttpProxyPort", 0, "port", port)
|
|
|
}
|
|
|
|
|
|
// NoticeClientUpgradeAvailable is an available client upgrade, as per the handshake. The
|
|
|
// client should download and install an upgrade.
|
|
|
func NoticeClientUpgradeAvailable(version string) {
|
|
|
- outputNotice("ClientUpgradeAvailable", false, false, "version", version)
|
|
|
+ outputNotice("ClientUpgradeAvailable", 0, "version", version)
|
|
|
}
|
|
|
|
|
|
// NoticeClientIsLatestVersion reports that an upgrade check was made and the client
|
|
|
// is already the latest version. availableVersion is the version available for download,
|
|
|
// if known.
|
|
|
func NoticeClientIsLatestVersion(availableVersion string) {
|
|
|
- outputNotice("ClientIsLatestVersion", false, false, "availableVersion", availableVersion)
|
|
|
+ outputNotice("ClientIsLatestVersion", 0, "availableVersion", availableVersion)
|
|
|
}
|
|
|
|
|
|
// NoticeHomepage is a sponsor homepage, as per the handshake. The client
|
|
|
// should display the sponsor's homepage.
|
|
|
func NoticeHomepage(url string) {
|
|
|
- outputNotice("Homepage", false, false, "url", url)
|
|
|
+ outputNotice("Homepage", 0, "url", url)
|
|
|
}
|
|
|
|
|
|
// NoticeClientVerificationRequired indicates that client verification is required, as
|
|
|
// indicated bythe handshake. The client should submit a client verification payload.
|
|
|
func NoticeClientVerificationRequired() {
|
|
|
- outputNotice("ClientVerificationRequired", false, false)
|
|
|
+ outputNotice("ClientVerificationRequired", 0)
|
|
|
}
|
|
|
|
|
|
// NoticeClientRegion is the client's region, as determined by the server and
|
|
|
// reported to the client in the handshake.
|
|
|
func NoticeClientRegion(region string) {
|
|
|
- outputNotice("ClientRegion", true, false, "region", region)
|
|
|
+ outputNotice("ClientRegion", 0, "region", region)
|
|
|
}
|
|
|
|
|
|
// NoticeTunnels is how many active tunnels are available. The client should use this to
|
|
|
// determine connecting/unexpected disconnect state transitions. When count is 0, the core is
|
|
|
// disconnected; when count > 1, the core is connected.
|
|
|
func NoticeTunnels(count int) {
|
|
|
- outputNotice("Tunnels", false, false, "count", count)
|
|
|
+ outputNotice("Tunnels", 0, "count", count)
|
|
|
}
|
|
|
|
|
|
// NoticeSessionId is the session ID used across all tunnels established by the controller.
|
|
|
func NoticeSessionId(sessionId string) {
|
|
|
- outputNotice("SessionId", true, false, "sessionId", sessionId)
|
|
|
+ outputNotice("SessionId", noticeIsDiagnostic, "sessionId", sessionId)
|
|
|
}
|
|
|
|
|
|
func NoticeImpairedProtocolClassification(impairedProtocolClassification map[string]int) {
|
|
|
- outputNotice("ImpairedProtocolClassification", false, false,
|
|
|
+ outputNotice("ImpairedProtocolClassification", noticeIsDiagnostic,
|
|
|
"classification", impairedProtocolClassification)
|
|
|
}
|
|
|
|
|
|
@@ -244,29 +249,29 @@ func NoticeImpairedProtocolClassification(impairedProtocolClassification map[str
|
|
|
// users, not for diagnostics logs.
|
|
|
//
|
|
|
func NoticeUntunneled(address string) {
|
|
|
- outputNotice("Untunneled", false, true, "address", address)
|
|
|
+ outputNotice("Untunneled", noticeShowUser, "address", address)
|
|
|
}
|
|
|
|
|
|
// NoticeSplitTunnelRegion reports that split tunnel is on for the given region.
|
|
|
func NoticeSplitTunnelRegion(region string) {
|
|
|
- outputNotice("SplitTunnelRegion", false, true, "region", region)
|
|
|
+ outputNotice("SplitTunnelRegion", noticeShowUser, "region", region)
|
|
|
}
|
|
|
|
|
|
// NoticeUpstreamProxyError reports an error when connecting to an upstream proxy. The
|
|
|
// user may have input, for example, an incorrect address or incorrect credentials.
|
|
|
func NoticeUpstreamProxyError(err error) {
|
|
|
- outputNotice("UpstreamProxyError", false, true, "message", err.Error())
|
|
|
+ outputNotice("UpstreamProxyError", noticeShowUser, "message", err.Error())
|
|
|
}
|
|
|
|
|
|
// NoticeClientUpgradeDownloadedBytes reports client upgrade download progress.
|
|
|
func NoticeClientUpgradeDownloadedBytes(bytes int64) {
|
|
|
- outputNotice("ClientUpgradeDownloadedBytes", true, false, "bytes", bytes)
|
|
|
+ outputNotice("ClientUpgradeDownloadedBytes", noticeIsDiagnostic, "bytes", bytes)
|
|
|
}
|
|
|
|
|
|
// NoticeClientUpgradeDownloaded indicates that a client upgrade download
|
|
|
// is complete and available at the destination specified.
|
|
|
func NoticeClientUpgradeDownloaded(filename string) {
|
|
|
- outputNotice("ClientUpgradeDownloaded", false, false, "filename", filename)
|
|
|
+ outputNotice("ClientUpgradeDownloaded", 0, "filename", filename)
|
|
|
}
|
|
|
|
|
|
// NoticeBytesTransferred reports how many tunneled bytes have been
|
|
|
@@ -274,10 +279,10 @@ func NoticeClientUpgradeDownloaded(filename string) {
|
|
|
// to the server at ipAddress.
|
|
|
func NoticeBytesTransferred(ipAddress string, sent, received int64) {
|
|
|
if GetEmitDiagnoticNotices() {
|
|
|
- outputNotice("BytesTransferred", true, false, "ipAddress", ipAddress, "sent", sent, "received", received)
|
|
|
+ outputNotice("BytesTransferred", noticeIsDiagnostic, "ipAddress", ipAddress, "sent", sent, "received", received)
|
|
|
} else {
|
|
|
// This case keeps the EmitBytesTransferred and EmitDiagnosticNotices config options independent
|
|
|
- outputNotice("BytesTransferred", false, false, "sent", sent, "received", received)
|
|
|
+ outputNotice("BytesTransferred", 0, "sent", sent, "received", received)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -286,10 +291,10 @@ func NoticeBytesTransferred(ipAddress string, sent, received int64) {
|
|
|
// at ipAddress.
|
|
|
func NoticeTotalBytesTransferred(ipAddress string, sent, received int64) {
|
|
|
if GetEmitDiagnoticNotices() {
|
|
|
- outputNotice("TotalBytesTransferred", true, false, "ipAddress", ipAddress, "sent", sent, "received", received)
|
|
|
+ outputNotice("TotalBytesTransferred", noticeIsDiagnostic, "ipAddress", ipAddress, "sent", sent, "received", received)
|
|
|
} else {
|
|
|
// This case keeps the EmitBytesTransferred and EmitDiagnosticNotices config options independent
|
|
|
- outputNotice("TotalBytesTransferred", false, false, "sent", sent, "received", received)
|
|
|
+ outputNotice("TotalBytesTransferred", 0, "sent", sent, "received", received)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -310,12 +315,12 @@ func NoticeLocalProxyError(proxyType string, err error) {
|
|
|
|
|
|
outputRepetitiveNotice(
|
|
|
"LocalProxyError"+proxyType, repetitionMessage, 1,
|
|
|
- "LocalProxyError", true, false, "message", err.Error())
|
|
|
+ "LocalProxyError", noticeIsDiagnostic, "message", err.Error())
|
|
|
}
|
|
|
|
|
|
// NoticeConnectedMeekStats reports extra network details for a meek tunnel connection.
|
|
|
func NoticeConnectedMeekStats(ipAddress string, meekStats *MeekStats) {
|
|
|
- outputNotice("ConnectedMeekStats", true, false,
|
|
|
+ outputNotice("ConnectedMeekStats", noticeIsDiagnostic,
|
|
|
"ipAddress", ipAddress,
|
|
|
"dialAddress", meekStats.DialAddress,
|
|
|
"resolvedIPAddress", meekStats.ResolvedIPAddress,
|
|
|
@@ -326,7 +331,7 @@ func NoticeConnectedMeekStats(ipAddress string, meekStats *MeekStats) {
|
|
|
|
|
|
// NoticeBuildInfo reports build version info.
|
|
|
func NoticeBuildInfo(buildDate, buildRepo, buildRev, goVersion, gomobileVersion string) {
|
|
|
- outputNotice("BuildInfo", false, false,
|
|
|
+ outputNotice("BuildInfo", 0,
|
|
|
"buildDate", buildDate,
|
|
|
"buildRepo", buildRepo,
|
|
|
"buildRev", buildRev,
|
|
|
@@ -336,22 +341,22 @@ func NoticeBuildInfo(buildDate, buildRepo, buildRev, goVersion, gomobileVersion
|
|
|
|
|
|
// NoticeExiting indicates that tunnel-core is exiting imminently.
|
|
|
func NoticeExiting() {
|
|
|
- outputNotice("Exiting", false, false)
|
|
|
+ outputNotice("Exiting", 0)
|
|
|
}
|
|
|
|
|
|
// NoticeRemoteServerListDownloadedBytes reports remote server list download progress.
|
|
|
func NoticeRemoteServerListDownloadedBytes(bytes int64) {
|
|
|
- outputNotice("RemoteServerListDownloadedBytes", true, false, "bytes", bytes)
|
|
|
+ outputNotice("RemoteServerListDownloadedBytes", noticeIsDiagnostic, "bytes", bytes)
|
|
|
}
|
|
|
|
|
|
// NoticeRemoteServerListDownloaded indicates that a remote server list download
|
|
|
// completed successfully.
|
|
|
func NoticeRemoteServerListDownloaded(filename string) {
|
|
|
- outputNotice("RemoteServerListDownloaded", false, false, "filename", filename)
|
|
|
+ outputNotice("RemoteServerListDownloaded", noticeIsDiagnostic, "filename", filename)
|
|
|
}
|
|
|
|
|
|
func NoticeClientVerificationRequestCompleted(ipAddress string) {
|
|
|
- outputNotice("NoticeClientVerificationRequestCompleted", true, false, "ipAddress", ipAddress)
|
|
|
+ outputNotice("NoticeClientVerificationRequestCompleted", noticeIsDiagnostic, "ipAddress", ipAddress)
|
|
|
}
|
|
|
|
|
|
type repetitiveNoticeState struct {
|
|
|
@@ -368,7 +373,7 @@ var repetitiveNoticeStates = make(map[string]*repetitiveNoticeState)
|
|
|
// until the repetitionMessage differs.
|
|
|
func outputRepetitiveNotice(
|
|
|
repetitionKey, repetitionMessage string, repeatLimit int,
|
|
|
- noticeType string, isDiagnostic, showUser bool, args ...interface{}) {
|
|
|
+ noticeType string, noticeFlags uint32, args ...interface{}) {
|
|
|
|
|
|
repetitiveNoticeMutex.Lock()
|
|
|
defer repetitiveNoticeMutex.Unlock()
|
|
|
@@ -394,7 +399,7 @@ func outputRepetitiveNotice(
|
|
|
if state.repeats > 0 {
|
|
|
args = append(args, "repeats", state.repeats)
|
|
|
}
|
|
|
- outputNotice(noticeType, isDiagnostic, showUser, args...)
|
|
|
+ outputNotice(noticeType, noticeFlags, args...)
|
|
|
}
|
|
|
}
|
|
|
|