From e142fe2be6ef3e5cd27b89d59175a3937b9fdb31 Mon Sep 17 00:00:00 2001 From: Dave Pacheco Date: Sat, 4 Jun 2011 16:04:38 +0200 Subject: DTrace probes: support X-Forwarded-For INTRO-385 --- src/node.d | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 12 deletions(-) (limited to 'src/node.d') diff --git a/src/node.d b/src/node.d index b81930c813..c666127fff 100644 --- a/src/node.d +++ b/src/node.d @@ -64,30 +64,96 @@ translator node_connection_t { &((node_dtrace_connection64_t *)nc)->buffered, sizeof (int32_t)); }; +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 { - 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)))); }; -- cgit v1.2.3