summaryrefslogtreecommitdiff
path: root/src/node.d
diff options
context:
space:
mode:
Diffstat (limited to 'src/node.d')
-rw-r--r--src/node.d90
1 files changed, 78 insertions, 12 deletions
diff --git a/src/node.d b/src/node.d
index b81930c813..c666127fff 100644
--- a/src/node.d
+++ b/src/node.d
@@ -65,29 +65,95 @@ translator node_connection_t <node_dtrace_connection_t *nc> {
};
typedef struct {
+ uint32_t version;
+} node_dtrace_http_request_t;
+
+typedef struct {
uint32_t url;
uint32_t method;
-} node_dtrace_http_request_t;
+} node_dtrace_http_request_v0_t;
+
+typedef struct {
+ uint32_t version;
+ uint32_t url;
+ uint32_t method;
+ uint32_t forwardedFor;
+} node_dtrace_http_request_v1_t;
typedef struct {
uint64_t url;
uint64_t method;
-} node_dtrace_http_request64_t;
+} node_dtrace_http_request64_v0_t;
+
+typedef struct {
+ uint32_t version;
+ uint32_t pad;
+ uint64_t url;
+ uint64_t method;
+ uint64_t forwardedFor;
+} node_dtrace_http_request64_v1_t;
typedef struct {
string url;
string method;
+ string forwardedFor;
} node_http_request_t;
+/*
+ * This translator is even filthier than usual owing to our attempts to
+ * maintain backwards compatibility. Previous versions of node used an
+ * http_request struct that had fields for "url" and "method". The current
+ * version also provides a "forwardedFor" field. To distinguish the binary
+ * representations of these structs, the new version also prepends a "version"
+ * member (where the old one has a "url" pointer). So each field that we're
+ * translating below first switches on the value of this "version" field: if
+ * it's larger than 4096, we know we must be looking at the "url" pointer of
+ * the older structure version. Otherwise, we must be looking at the new
+ * version. Besides this, we have the usual switch based on the userland
+ * process data model. This would all be simpler with macros, but those aren't
+ * available in delivered D library files since that would make DTrace
+ * dependent on cpp, which isn't always available.
+ */
translator node_http_request_t <node_dtrace_http_request_t *nd> {
- url = curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
- copyinstr((uintptr_t)*(uint32_t *)copyin((uintptr_t)&nd->url,
- sizeof (int32_t))) :
- copyinstr((uintptr_t)*(uint64_t *)copyin((uintptr_t)
- &((node_dtrace_http_request64_t *)nd)->url, sizeof (int64_t)));
- method = curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
- copyinstr((uintptr_t)*(uint32_t *)copyin((uintptr_t)&nd->method,
- sizeof (int32_t))) :
- copyinstr((uintptr_t)*(uint64_t *)copyin((uintptr_t)
- &((node_dtrace_http_request64_t *)nd)->method, sizeof (int64_t)));
+ url = (*(uint32_t *)copyin((uintptr_t)&nd->version, sizeof (uint32_t))) >= 4096 ?
+ (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
+ copyinstr(*(uint32_t *)copyin((uintptr_t)
+ &((node_dtrace_http_request_v0_t *)nd)->url,
+ sizeof (uint32_t))) :
+ copyinstr(*(uint64_t *)copyin((uintptr_t)
+ &((node_dtrace_http_request64_v0_t *)nd)->url,
+ sizeof (uint64_t)))) :
+ (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
+ copyinstr(*(uint32_t *)copyin((uintptr_t)
+ &((node_dtrace_http_request_v1_t *)nd)->url,
+ sizeof (uint32_t))) :
+ copyinstr(*(uint64_t *)copyin((uintptr_t)
+ &((node_dtrace_http_request64_v1_t *)nd)->url,
+ sizeof (uint64_t))));
+
+ method = (*(uint32_t *)copyin((uintptr_t)&nd->version, sizeof (uint32_t))) >= 4096 ?
+ (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
+ copyinstr(*(uint32_t *)copyin((uintptr_t)
+ &((node_dtrace_http_request_v0_t *)nd)->method,
+ sizeof (uint32_t))) :
+ copyinstr(*(uint64_t *)copyin((uintptr_t)
+ &((node_dtrace_http_request64_v0_t *)nd)->method,
+ sizeof (uint64_t)))) :
+ (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
+ copyinstr(*(uint32_t *)copyin((uintptr_t)
+ &((node_dtrace_http_request_v1_t *)nd)->method,
+ sizeof (uint32_t))) :
+ copyinstr(*(uint64_t *)copyin((uintptr_t)
+ &((node_dtrace_http_request64_v1_t *)nd)->method,
+ sizeof (uint64_t))));
+
+ forwardedFor = (*(uint32_t *)
+ copyin((uintptr_t)&nd->version, sizeof (uint32_t))) >= 4096 ? "" :
+ (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
+ copyinstr(*(uint32_t *)copyin((uintptr_t)
+ &((node_dtrace_http_request_v1_t *)nd)->forwardedFor,
+ sizeof (uint32_t))) :
+ copyinstr(*(uint64_t *)copyin((uintptr_t)
+ &((node_dtrace_http_request64_v1_t *)nd)->forwardedFor,
+ sizeof (uint64_t))));
};