diff options
author | Dave Pacheco <dap@joyent.com> | 2011-06-04 18:04:38 +0400 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2011-06-04 18:05:01 +0400 |
commit | e142fe2be6ef3e5cd27b89d59175a3937b9fdb31 (patch) | |
tree | 067bdfdcd56a15e274c3fbefa43da1b413a67733 /src/node.d | |
parent | b6a742d76fa8a598f24c8c2ec5b18d0cdc22ef4a (diff) |
DTrace probes: support X-Forwarded-For
INTRO-385
Diffstat (limited to 'src/node.d')
-rw-r--r-- | src/node.d | 90 |
1 files changed, 78 insertions, 12 deletions
diff --git a/src/node.d b/src/node.d index b81930c813a..c666127fffc 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)))); }; |