The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / src / node.d @ 31c510ca

History | View | Annotate | Download (12 KB)

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;
36
} node_dtrace_connection_t;
37

    
38
typedef struct {
39
	int32_t fd;
40
	int32_t port;
41
	uint64_t remote;
42
	uint32_t buffered;
43
} node_dtrace_connection64_t;
44

    
45
typedef struct {
46
	int fd;
47
	string remoteAddress;
48
	int remotePort;
49
	int bufferSize;
50
} node_connection_t;
51

    
52
translator node_connection_t <node_dtrace_connection_t *nc> {
53
	fd = *(int32_t *)copyin((uintptr_t)&nc->fd, sizeof (int32_t));
54
	remotePort =
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;
74
} node_dtrace_http_client_request_t;
75

    
76
typedef struct {
77
	uint64_t url;
78
	uint64_t method;
79
} node_dtrace_http_client_request64_t;
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;
96
} node_dtrace_http_request_t;
97

    
98
typedef struct {
99
	uint32_t version;
100
	uint64_t dummy2;
101
	uint64_t dummy3;
102
} node_dtrace_http_server_request_t;
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;
111
} node_dtrace_http_server_request_v0_t;
112

    
113
typedef struct {
114
	uint32_t version;
115
	uint32_t url;
116
	uint32_t method;
117
	uint32_t forwardedFor;
118
} node_dtrace_http_server_request_v1_t;
119

    
120
typedef struct {
121
	uint64_t url;
122
	uint64_t method;
123
} node_dtrace_http_server_request64_v0_t;
124

    
125
typedef struct {
126
	uint32_t version;
127
	uint32_t pad;
128
	uint64_t url;
129
	uint64_t method;
130
	uint64_t forwardedFor;
131
} node_dtrace_http_server_request64_v1_t;
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;
142
} node_http_request_t;
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
 */
177
translator node_http_request_t <node_dtrace_http_server_request_t *nd> {
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)
182
		    &((node_dtrace_http_server_request_v0_t *)nd)->url,
183
		    sizeof (uint32_t))) :
184
		copyinstr(*(uint64_t *)copyin((uintptr_t)
185
		    &((node_dtrace_http_server_request64_v0_t *)nd)->url,
186
		    sizeof (uint64_t)))) :
187
	    (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
188
		copyinstr(*(uint32_t *)copyin((uintptr_t)
189
		    &((node_dtrace_http_server_request_v1_t *)nd)->url,
190
		    sizeof (uint32_t))) :
191
		copyinstr(*(uint64_t *)copyin((uintptr_t)
192
		    &((node_dtrace_http_server_request64_v1_t *)nd)->url,
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)
199
		    &((node_dtrace_http_server_request_v0_t *)nd)->method,
200
		    sizeof (uint32_t))) :
201
		copyinstr(*(uint64_t *)copyin((uintptr_t)
202
		    &((node_dtrace_http_server_request64_v0_t *)nd)->method,
203
		    sizeof (uint64_t)))) :
204
	    (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
205
		copyinstr(*(uint32_t *)copyin((uintptr_t)
206
		    &((node_dtrace_http_server_request_v1_t *)nd)->method,
207
		    sizeof (uint32_t))) :
208
		copyinstr(*(uint64_t *)copyin((uintptr_t)
209
		    &((node_dtrace_http_server_request64_v1_t *)nd)->method,
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)
216
		    &((node_dtrace_http_server_request_v1_t *)nd)->forwardedFor,
217
		    sizeof (uint32_t))) :
218
		copyinstr(*(uint64_t *)copyin((uintptr_t)
219
		    &((node_dtrace_http_server_request64_v1_t *)nd)->
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
 */
227
translator node_http_request_t <node_dtrace_http_client_request_t *nd> {
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)
232
		    &((node_dtrace_http_server_request_v0_t *)nd)->url,
233
		    sizeof (uint32_t))) :
234
		copyinstr(*(uint64_t *)copyin((uintptr_t)
235
		    &((node_dtrace_http_server_request64_v0_t *)nd)->url,
236
		    sizeof (uint64_t)))) :
237
	    (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
238
		copyinstr(*(uint32_t *)copyin((uintptr_t)
239
		    &((node_dtrace_http_server_request_v1_t *)nd)->url,
240
		    sizeof (uint32_t))) :
241
		copyinstr(*(uint64_t *)copyin((uintptr_t)
242
		    &((node_dtrace_http_server_request64_v1_t *)nd)->url,
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)
249
		    &((node_dtrace_http_server_request_v0_t *)nd)->method,
250
		    sizeof (uint32_t))) :
251
		copyinstr(*(uint64_t *)copyin((uintptr_t)
252
		    &((node_dtrace_http_server_request64_v0_t *)nd)->method,
253
		    sizeof (uint64_t)))) :
254
	    (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
255
		copyinstr(*(uint32_t *)copyin((uintptr_t)
256
		    &((node_dtrace_http_server_request_v1_t *)nd)->method,
257
		    sizeof (uint32_t))) :
258
		copyinstr(*(uint64_t *)copyin((uintptr_t)
259
		    &((node_dtrace_http_server_request64_v1_t *)nd)->method,
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
 */
271
translator node_http_request_t <node_dtrace_http_request_t *nd> {
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)
276
		    &((node_dtrace_http_server_request_v0_t *)nd)->url,
277
		    sizeof (uint32_t))) :
278
		copyinstr(*(uint64_t *)copyin((uintptr_t)
279
		    &((node_dtrace_http_server_request64_v0_t *)nd)->url,
280
		    sizeof (uint64_t)))) :
281
	    (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
282
		copyinstr(*(uint32_t *)copyin((uintptr_t)
283
		    &((node_dtrace_http_server_request_v1_t *)nd)->url,
284
		    sizeof (uint32_t))) :
285
		copyinstr(*(uint64_t *)copyin((uintptr_t)
286
		    &((node_dtrace_http_server_request64_v1_t *)nd)->url,
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)
293
		    &((node_dtrace_http_server_request_v0_t *)nd)->method,
294
		    sizeof (uint32_t))) :
295
		copyinstr(*(uint64_t *)copyin((uintptr_t)
296
		    &((node_dtrace_http_server_request64_v0_t *)nd)->method,
297
		    sizeof (uint64_t)))) :
298
	    (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
299
		copyinstr(*(uint32_t *)copyin((uintptr_t)
300
		    &((node_dtrace_http_server_request_v1_t *)nd)->method,
301
		    sizeof (uint32_t))) :
302
		copyinstr(*(uint64_t *)copyin((uintptr_t)
303
		    &((node_dtrace_http_server_request64_v1_t *)nd)->method,
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)
310
		    &((node_dtrace_http_server_request_v1_t *)nd)->forwardedFor,
311
		    sizeof (uint32_t))) :
312
		copyinstr(*(uint64_t *)copyin((uintptr_t)
313
		    &((node_dtrace_http_server_request64_v1_t *)nd)->
314
		    forwardedFor, sizeof (uint64_t))));
315
};