From 0a419c94436082f9964d8887a1e26f122e2d4248 Mon Sep 17 00:00:00 2001 From: Gabriel Aszalos Date: Thu, 22 Oct 2020 15:40:26 +0300 Subject: [PATCH 1/3] pkg/trace/api: enable Windows pipe support Windows pipes are now supported by means of: * `DD_APM_WINDOWS_PIPE_NAME` defines the pipe name to be used. * `DD_APM_WINDOWS_PIPE_BUFFER_SIZE` defines the input buffer size (defaults to 1MB). --- pkg/config/apm.go | 2 ++ pkg/trace/api/api.go | 17 +++++++++++++++++ pkg/trace/api/pipe.go | 20 ++++++++++++++++++++ pkg/trace/api/pipe_off.go | 17 +++++++++++++++++ 4 files changed, 56 insertions(+) create mode 100644 pkg/trace/api/pipe.go create mode 100644 pkg/trace/api/pipe_off.go diff --git a/pkg/config/apm.go b/pkg/config/apm.go index c73a5ad8897e43..c8595ee5d55fd7 100644 --- a/pkg/config/apm.go +++ b/pkg/config/apm.go @@ -43,6 +43,7 @@ func setupAPM(config Config) { } config.BindEnvAndSetDefault("apm_config.receiver_port", 8126, "DD_APM_RECEIVER_PORT", "DD_RECEIVER_PORT") + config.BindEnvAndSetDefault("apm_config.windows_pipe_buffer_size", 1_000_000, "DD_APM_WINDOWS_PIPE_BUFFER_SIZE") //nolint:errcheck config.BindEnv("apm_config.receiver_timeout", "DD_APM_RECEIVER_TIMEOUT") //nolint:errcheck config.BindEnv("apm_config.max_payload_size", "DD_APM_MAX_PAYLOAD_SIZE") //nolint:errcheck @@ -63,6 +64,7 @@ func setupAPM(config Config) { config.BindEnv("apm_config.analyzed_spans", "DD_APM_ANALYZED_SPANS") //nolint:errcheck config.BindEnv("apm_config.ignore_resources", "DD_APM_IGNORE_RESOURCES", "DD_IGNORE_RESOURCE") //nolint:errcheck config.BindEnv("apm_config.receiver_socket", "DD_APM_RECEIVER_SOCKET") //nolint:errcheck + config.BindEnv("apm_config.windows_pipe_name", "DD_APM_WINDOWS_PIPE_NAME") //nolint:errcheck config.SetEnvKeyTransformer("apm_config.ignore_resources", func(in string) interface{} { r, err := splitCSVString(in, ',') diff --git a/pkg/trace/api/api.go b/pkg/trace/api/api.go index 577acd3e26c963..63c7afb6abba48 100644 --- a/pkg/trace/api/api.go +++ b/pkg/trace/api/api.go @@ -121,6 +121,7 @@ func (r *HTTPReceiver) Start() { go func() { defer watchdog.LogOnPanic() r.server.Serve(ln) + ln.Close() }() log.Infof("Listening for traces at http://%s", addr) @@ -132,10 +133,26 @@ func (r *HTTPReceiver) Start() { go func() { defer watchdog.LogOnPanic() r.server.Serve(ln) + ln.Close() }() log.Infof("Listening for traces at unix://%s", path) } + if path := mainconfig.Datadog.GetString("apm_config.windows_pipe_name"); path != "" { + pipepath := `\\.\pipe\` + path + bufferSize := mainconfig.Datadog.GetInt("apm_config.windows_pipe_buffer_size") + ln, err := listenPipe(pipepath, bufferSize) + if err != nil { + killProcess("Error creating %q named pipe: %v", pipepath, err) + } + go func() { + defer watchdog.LogOnPanic() + r.server.Serve(ln) + ln.Close() + }() + log.Infof("Listening for traces on Windowes pipe %s", pipepath) + } + go r.RateLimiter.Run() go func() { diff --git a/pkg/trace/api/pipe.go b/pkg/trace/api/pipe.go new file mode 100644 index 00000000000000..9f7347726dbe07 --- /dev/null +++ b/pkg/trace/api/pipe.go @@ -0,0 +1,20 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-2020 Datadog, Inc. + +// +build windows + +package api + +import ( + "net" + + "github.com/Microsoft/go-winio" +) + +func listenPipe(path string, bufferSize int) (net.Listener, error) { + return winio.ListenPipe(path, &winio.PipeConfig{ + InputBufferSize: int32(bufferSize), + }) +} diff --git a/pkg/trace/api/pipe_off.go b/pkg/trace/api/pipe_off.go new file mode 100644 index 00000000000000..8308a16aceeb55 --- /dev/null +++ b/pkg/trace/api/pipe_off.go @@ -0,0 +1,17 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-2020 Datadog, Inc. + +// +build !windows + +package api + +import ( + "errors" + "net" +) + +func listenPipe(path string, bufferSize int) (net.Listener, error) { + return nil, errors.New("Windows named pipes are only supported on Windows operating systems") +} From b37d15a3dd345bf2ae9344ac1625ed44e399e7ae Mon Sep 17 00:00:00 2001 From: Gabriel Aszalos Date: Mon, 23 Nov 2020 14:11:52 +0200 Subject: [PATCH 2/3] pkg/trace/api: allow setting security descriptor and have a default --- pkg/config/apm.go | 3 ++- pkg/trace/api/api.go | 5 +++-- pkg/trace/api/pipe.go | 5 +++-- pkg/trace/api/pipe_off.go | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/pkg/config/apm.go b/pkg/config/apm.go index c8595ee5d55fd7..cb3a622d6dd3f6 100644 --- a/pkg/config/apm.go +++ b/pkg/config/apm.go @@ -43,7 +43,8 @@ func setupAPM(config Config) { } config.BindEnvAndSetDefault("apm_config.receiver_port", 8126, "DD_APM_RECEIVER_PORT", "DD_RECEIVER_PORT") - config.BindEnvAndSetDefault("apm_config.windows_pipe_buffer_size", 1_000_000, "DD_APM_WINDOWS_PIPE_BUFFER_SIZE") //nolint:errcheck + config.BindEnvAndSetDefault("apm_config.windows_pipe_buffer_size", 1_000_000, "DD_APM_WINDOWS_PIPE_BUFFER_SIZE") //nolint:errcheck + config.BindEnvAndSetDefault("apm_config.windows_pipe_security_descriptor", "D:AI(A;;GA;;;WD)", "DD_APM_WINDOWS_PIPE_SECURITY_DESCRIPTOR") //nolint:errcheck config.BindEnv("apm_config.receiver_timeout", "DD_APM_RECEIVER_TIMEOUT") //nolint:errcheck config.BindEnv("apm_config.max_payload_size", "DD_APM_MAX_PAYLOAD_SIZE") //nolint:errcheck diff --git a/pkg/trace/api/api.go b/pkg/trace/api/api.go index 63c7afb6abba48..da5adb077263ce 100644 --- a/pkg/trace/api/api.go +++ b/pkg/trace/api/api.go @@ -141,7 +141,8 @@ func (r *HTTPReceiver) Start() { if path := mainconfig.Datadog.GetString("apm_config.windows_pipe_name"); path != "" { pipepath := `\\.\pipe\` + path bufferSize := mainconfig.Datadog.GetInt("apm_config.windows_pipe_buffer_size") - ln, err := listenPipe(pipepath, bufferSize) + secdec := mainconfig.Datadog.GetString("apm_config.windows_pipe_security_descriptor") + ln, err := listenPipe(pipepath, secdec, bufferSize) if err != nil { killProcess("Error creating %q named pipe: %v", pipepath, err) } @@ -150,7 +151,7 @@ func (r *HTTPReceiver) Start() { r.server.Serve(ln) ln.Close() }() - log.Infof("Listening for traces on Windowes pipe %s", pipepath) + log.Infof("Listening for traces on Windowes pipe %q. Security descriptor is %q", pipepath, secdec) } go r.RateLimiter.Run() diff --git a/pkg/trace/api/pipe.go b/pkg/trace/api/pipe.go index 9f7347726dbe07..bdf9039e3b69ee 100644 --- a/pkg/trace/api/pipe.go +++ b/pkg/trace/api/pipe.go @@ -13,8 +13,9 @@ import ( "github.com/Microsoft/go-winio" ) -func listenPipe(path string, bufferSize int) (net.Listener, error) { +func listenPipe(path string, secdec string, bufferSize int) (net.Listener, error) { return winio.ListenPipe(path, &winio.PipeConfig{ - InputBufferSize: int32(bufferSize), + SecurityDescriptor: secdec, + InputBufferSize: int32(bufferSize), }) } diff --git a/pkg/trace/api/pipe_off.go b/pkg/trace/api/pipe_off.go index 8308a16aceeb55..545fb03dae746d 100644 --- a/pkg/trace/api/pipe_off.go +++ b/pkg/trace/api/pipe_off.go @@ -12,6 +12,6 @@ import ( "net" ) -func listenPipe(path string, bufferSize int) (net.Listener, error) { +func listenPipe(_, _ string, _ int) (net.Listener, error) { return nil, errors.New("Windows named pipes are only supported on Windows operating systems") } From 0a23711c2d5e27ccb3463145e293969f4ef95891 Mon Sep 17 00:00:00 2001 From: Gabriel Aszalos Date: Wed, 2 Dec 2020 10:12:47 +0200 Subject: [PATCH 3/3] releasenotes: added release note --- .../notes/apm-windows-pipe-c8de92ce85fd930b.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 releasenotes/notes/apm-windows-pipe-c8de92ce85fd930b.yaml diff --git a/releasenotes/notes/apm-windows-pipe-c8de92ce85fd930b.yaml b/releasenotes/notes/apm-windows-pipe-c8de92ce85fd930b.yaml new file mode 100644 index 00000000000000..6b825ea576af47 --- /dev/null +++ b/releasenotes/notes/apm-windows-pipe-c8de92ce85fd930b.yaml @@ -0,0 +1,12 @@ +# Each section from every releasenote are combined when the +# CHANGELOG.rst is rendered. So the text needs to be worded so that +# it does not depend on any information only available in another +# section. This may mean repeating some details, but each section +# must be readable independently of the other. +# +# Each section note must be formatted as reStructuredText. +--- +features: + - | + APM: Added support for Windows pipes. To enable it, set the pipe path using + DD_APM_WINDOWS_PIPE_NAME. For more details check https://github.com/DataDog/datadog-agent/pull/6615