Node.js  v8.x
Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine
node.d
Go to the documentation of this file.
1 /* Copyright Joyent, Inc. and other Node contributors.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a
4  * copy of this software and associated documentation files (the
5  * "Software"), to deal in the Software without restriction, including
6  * without limitation the rights to use, copy, modify, merge, publish,
7  * distribute, sublicense, and/or sell copies of the Software, and to permit
8  * persons to whom the Software is furnished to do so, subject to the
9  * following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17  * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20  * USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 /*
24  * This is the DTrace library file for the node provider, which includes
25  * the necessary translators to get from the args[] to something useful.
26  * Be warned: the mechanics here are seriously ugly -- and one must always
27  * keep in mind that clean abstractions often require filthy systems.
28  */
29 #pragma D depends_on library procfs.d
30 
31 typedef struct {
32  int32_t fd;
33  int32_t port;
34  uint32_t remote;
35  uint32_t buffered;
37 
38 typedef struct {
39  int32_t fd;
40  int32_t port;
41  uint64_t remote;
42  uint32_t buffered;
44 
45 typedef struct {
46  int fd;
47  string remoteAddress;
51 
53  fd = *(int32_t *)copyin((uintptr_t)&nc->fd, sizeof (int32_t));
55  *(int32_t *)copyin((uintptr_t)&nc->port, sizeof (int32_t));
56  remoteAddress = curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
57  copyinstr((uintptr_t)*(uint32_t *)copyin((uintptr_t)&nc->remote,
58  sizeof (int32_t))) :
59  copyinstr((uintptr_t)*(uint64_t *)copyin((uintptr_t)
60  &((node_dtrace_connection64_t *)nc)->remote, sizeof (int64_t)));
61  bufferSize = curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
62  *(uint32_t *)copyin((uintptr_t)&nc->buffered, sizeof (int32_t)) :
63  *(uint32_t *)copyin((uintptr_t)
64  &((node_dtrace_connection64_t *)nc)->buffered, sizeof (int32_t));
65 };
66 
67 /*
68  * 32-bit and 64-bit structures received from node for HTTP client request
69  * probe.
70  */
71 typedef struct {
72  uint32_t url;
73  uint32_t method;
75 
76 typedef struct {
77  uint64_t url;
78  uint64_t method;
80 
81 /*
82  * The following structures are never used directly, but must exist to bind the
83  * types specified in the provider to the translators defined here.
84  * Ultimately, they always get cast to a more specific type inside the
85  * translator. To add to the confusion, the DTrace compiler does not allow
86  * declaring two translators with the same destination type if the source types
87  * are structures with the same size (because libctf says they're compatible,
88  * so dtrace considers them equivalent). Since we must define translators from
89  * node_dtrace_http_client_request_t (above), node_dtrace_http_request_t, and
90  * node_dtrace_http_server_request_t (both below), each of these three structs
91  * must be declared with a different size.
92  */
93 typedef struct {
94  uint32_t version;
95  uint64_t dummy1;
97 
98 typedef struct {
99  uint32_t version;
100  uint64_t dummy2;
101  uint64_t dummy3;
103 
104 /*
105  * Actual 32-bit and 64-bit, v0 and v1 structures received from node for the
106  * HTTP server request probe.
107  */
108 typedef struct {
109  uint32_t url;
110  uint32_t method;
112 
113 typedef struct {
114  uint32_t version;
115  uint32_t url;
116  uint32_t method;
117  uint32_t forwardedFor;
119 
120 typedef struct {
121  uint64_t url;
122  uint64_t method;
124 
125 typedef struct {
126  uint32_t version;
127  uint32_t pad;
128  uint64_t url;
129  uint64_t method;
130  uint64_t forwardedFor;
132 
133 /*
134  * In the end, both client and server request probes from both old and new
135  * binaries translate their arguments to node_http_request_t, which is what the
136  * user's D script ultimately sees.
137  */
138 typedef struct {
139  string url;
140  string method;
141  string forwardedFor;
143 
144 /*
145  * The following translators are particularly filthy for reasons of backwards
146  * compatibility. Stable versions of node prior to 0.6 used a single
147  * http_request struct with fields for "url" and "method" for both client and
148  * server probes. 0.6 added a "forwardedFor" field intended for the server
149  * probe only, and the http_request struct passed by the application was split
150  * first into client_http_request and server_http_request and the latter was
151  * again split for v0 (the old struct) and v1.
152  *
153  * To distinguish the binary representations of the two versions of these
154  * structs, the new version prepends a "version" member (where the old one has
155  * a "url" pointer). Each field that we're translating below first switches on
156  * the value of this "version" field: if it's larger than 4096, we know we must
157  * be looking at the "url" pointer of the older structure version. Otherwise,
158  * we must be looking at the new version. Besides this, we have the usual
159  * switch based on the userland process data model. This would all be simpler
160  * with macros, but those aren't available in D library files since we cannot
161  * rely on cpp being present at runtime.
162  *
163  * In retrospect, the versioning bit might have been unnecessary since the type
164  * of the object passed in should allow DTrace to select which translator to
165  * use. However, DTrace does sometimes use translators whose source types
166  * don't quite match, and since we know this versioning logic works, we just
167  * leave it alone. Each of the translators below is functionally identical
168  * (except that the client -> client translator doesn't bother translating
169  * forwardedFor) and should actually work with any version of any of the client
170  * or server structs transmitted by the application up to this point.
171  */
172 
173 /*
174  * Translate from node_dtrace_http_server_request_t (received from node 0.6 and
175  * later versions) to node_http_request_t.
176  */
178  url = (*(uint32_t *)copyin((uintptr_t)(uint32_t *)nd,
179  sizeof (uint32_t))) >= 4096 ?
180  (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
181  copyinstr(*(uint32_t *)copyin((uintptr_t)
183  sizeof (uint32_t))) :
184  copyinstr(*(uint64_t *)copyin((uintptr_t)
186  sizeof (uint64_t)))) :
187  (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
188  copyinstr(*(uint32_t *)copyin((uintptr_t)
190  sizeof (uint32_t))) :
191  copyinstr(*(uint64_t *)copyin((uintptr_t)
193  sizeof (uint64_t))));
194 
195  method = (*(uint32_t *)copyin((uintptr_t)(uint32_t *)nd,
196  sizeof (uint32_t))) >= 4096 ?
197  (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
198  copyinstr(*(uint32_t *)copyin((uintptr_t)
200  sizeof (uint32_t))) :
201  copyinstr(*(uint64_t *)copyin((uintptr_t)
203  sizeof (uint64_t)))) :
204  (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
205  copyinstr(*(uint32_t *)copyin((uintptr_t)
207  sizeof (uint32_t))) :
208  copyinstr(*(uint64_t *)copyin((uintptr_t)
210  sizeof (uint64_t))));
211 
212  forwardedFor = (*(uint32_t *)copyin((uintptr_t)(uint32_t *)nd,
213  sizeof (uint32_t))) >= 4096 ? "" :
214  (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
215  copyinstr(*(uint32_t *)copyin((uintptr_t)
217  sizeof (uint32_t))) :
218  copyinstr(*(uint64_t *)copyin((uintptr_t)
220  forwardedFor, sizeof (uint64_t))));
221 };
222 
223 /*
224  * Translate from node_dtrace_http_client_request_t (received from node 0.6 and
225  * later versions) to node_http_request_t.
226  */
228  url = (*(uint32_t *)copyin((uintptr_t)(uint32_t *)nd,
229  sizeof (uint32_t))) >= 4096 ?
230  (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
231  copyinstr(*(uint32_t *)copyin((uintptr_t)
233  sizeof (uint32_t))) :
234  copyinstr(*(uint64_t *)copyin((uintptr_t)
236  sizeof (uint64_t)))) :
237  (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
238  copyinstr(*(uint32_t *)copyin((uintptr_t)
240  sizeof (uint32_t))) :
241  copyinstr(*(uint64_t *)copyin((uintptr_t)
243  sizeof (uint64_t))));
244 
245  method = (*(uint32_t *)copyin((uintptr_t)(uint32_t *)nd,
246  sizeof (uint32_t))) >= 4096 ?
247  (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
248  copyinstr(*(uint32_t *)copyin((uintptr_t)
250  sizeof (uint32_t))) :
251  copyinstr(*(uint64_t *)copyin((uintptr_t)
253  sizeof (uint64_t)))) :
254  (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
255  copyinstr(*(uint32_t *)copyin((uintptr_t)
257  sizeof (uint32_t))) :
258  copyinstr(*(uint64_t *)copyin((uintptr_t)
260  sizeof (uint64_t))));
261 
262  forwardedFor = "";
263 };
264 
265 /*
266  * Translate from node_dtrace_http_request_t (received from versions of node
267  * prior to 0.6) to node_http_request_t. This is used for both the server and
268  * client probes since these versions of node didn't distinguish between the
269  * types used in these probes.
270  */
272  url = (*(uint32_t *)copyin((uintptr_t)(uint32_t *)nd,
273  sizeof (uint32_t))) >= 4096 ?
274  (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
275  copyinstr(*(uint32_t *)copyin((uintptr_t)
277  sizeof (uint32_t))) :
278  copyinstr(*(uint64_t *)copyin((uintptr_t)
280  sizeof (uint64_t)))) :
281  (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
282  copyinstr(*(uint32_t *)copyin((uintptr_t)
284  sizeof (uint32_t))) :
285  copyinstr(*(uint64_t *)copyin((uintptr_t)
287  sizeof (uint64_t))));
288 
289  method = (*(uint32_t *)copyin((uintptr_t)(uint32_t *)nd,
290  sizeof (uint32_t))) >= 4096 ?
291  (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
292  copyinstr(*(uint32_t *)copyin((uintptr_t)
294  sizeof (uint32_t))) :
295  copyinstr(*(uint64_t *)copyin((uintptr_t)
297  sizeof (uint64_t)))) :
298  (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
299  copyinstr(*(uint32_t *)copyin((uintptr_t)
301  sizeof (uint32_t))) :
302  copyinstr(*(uint64_t *)copyin((uintptr_t)
304  sizeof (uint64_t))));
305 
306  forwardedFor = (*(uint32_t *) copyin((uintptr_t)(uint32_t *)nd,
307  sizeof (uint32_t))) >= 4096 ? "" :
308  (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
309  copyinstr(*(uint32_t *)copyin((uintptr_t)
311  sizeof (uint32_t))) :
312  copyinstr(*(uint64_t *)copyin((uintptr_t)
314  forwardedFor, sizeof (uint64_t))));
315 };
bufferSize
Definition: node.d:61
int bufferSize
Definition: node.d:49
uint32_t buffered
Definition: node.d:35
int remotePort
Definition: node.d:48
forwardedFor
Definition: node.d:212
string remoteAddress
Definition: node.d:47
remotePort
Definition: node.d:54
remoteAddress
Definition: node.d:56
string forwardedFor
Definition: node.d:141
string method
Definition: node.d:140
method
Definition: node.d:195