@@ -64,96 +64,252 @@ translator node_connection_t <node_dtrace_connection_t *nc> {
64
64
& ((node_dtrace_connection64_t * )nc )-> buffered , sizeof (int32_t ));
65
65
};
66
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
+ */
67
93
typedef struct {
68
94
uint32_t version ;
95
+ uint64_t dummy1 ;
69
96
} node_dtrace_http_request_t ;
70
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
+ */
71
108
typedef struct {
72
109
uint32_t url ;
73
110
uint32_t method ;
74
- } node_dtrace_http_request_v0_t ;
111
+ } node_dtrace_http_server_request_v0_t ;
75
112
76
113
typedef struct {
77
114
uint32_t version ;
78
115
uint32_t url ;
79
116
uint32_t method ;
80
117
uint32_t forwardedFor ;
81
- } node_dtrace_http_request_v1_t ;
118
+ } node_dtrace_http_server_request_v1_t ;
82
119
83
120
typedef struct {
84
121
uint64_t url ;
85
122
uint64_t method ;
86
- } node_dtrace_http_request64_v0_t ;
123
+ } node_dtrace_http_server_request64_v0_t ;
87
124
88
125
typedef struct {
89
126
uint32_t version ;
90
127
uint32_t pad ;
91
128
uint64_t url ;
92
129
uint64_t method ;
93
130
uint64_t forwardedFor ;
94
- } node_dtrace_http_request64_v1_t ;
131
+ } node_dtrace_http_server_request64_v1_t ;
95
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
+ */
96
138
typedef struct {
97
139
string url ;
98
140
string method ;
99
141
string forwardedFor ;
100
142
} node_http_request_t ;
101
143
102
144
/*
103
- * This translator is even filthier than usual owing to our attempts to
104
- * maintain backwards compatibility. Previous versions of node used an
105
- * http_request struct that had fields for "url" and "method". The current
106
- * version also provides a "forwardedFor" field. To distinguish the binary
107
- * representations of these structs, the new version also prepends a "version"
108
- * member (where the old one has a "url" pointer). So each field that we're
109
- * translating below first switches on the value of this "version" field: if
110
- * it's larger than 4096, we know we must be looking at the "url" pointer of
111
- * the older structure version. Otherwise, we must be looking at the new
112
- * version. Besides this, we have the usual switch based on the userland
113
- * process data model. This would all be simpler with macros, but those aren't
114
- * available in delivered D library files since that would make DTrace
115
- * dependent on cpp, which isn't always available.
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.
116
171
*/
117
- translator node_http_request_t < node_dtrace_http_request_t * nd > {
118
- url = (* (uint32_t * )copyin ((uintptr_t )& nd -> version , sizeof (uint32_t ))) >= 4096 ?
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 )))) :
119
204
(curpsinfo -> pr_dmodel == PR_MODEL_ILP32 ?
120
205
copyinstr (* (uint32_t * )copyin ((uintptr_t )
121
- & ((node_dtrace_http_request_v0_t * )nd )-> url ,
206
+ & ((node_dtrace_http_server_request_v1_t * )nd )-> method ,
122
207
sizeof (uint32_t ))) :
123
208
copyinstr (* (uint64_t * )copyin ((uintptr_t )
124
- & ((node_dtrace_http_request64_v0_t * )nd )-> url ,
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 ,
125
236
sizeof (uint64_t )))) :
126
237
(curpsinfo -> pr_dmodel == PR_MODEL_ILP32 ?
127
238
copyinstr (* (uint32_t * )copyin ((uintptr_t )
128
- & ((node_dtrace_http_request_v1_t * )nd )-> url ,
239
+ & ((node_dtrace_http_server_request_v1_t * )nd )-> url ,
129
240
sizeof (uint32_t ))) :
130
241
copyinstr (* (uint64_t * )copyin ((uintptr_t )
131
- & ((node_dtrace_http_request64_v1_t * )nd )-> url ,
242
+ & ((node_dtrace_http_server_request64_v1_t * )nd )-> url ,
132
243
sizeof (uint64_t )))) ;
133
244
134
- method = (* (uint32_t * )copyin ((uintptr_t )& nd -> version , sizeof (uint32_t ))) >= 4096 ?
245
+ method = (* (uint32_t * )copyin ((uintptr_t )(uint32_t * )nd ,
246
+ sizeof (uint32_t ))) >= 4096 ?
135
247
(curpsinfo -> pr_dmodel == PR_MODEL_ILP32 ?
136
248
copyinstr (* (uint32_t * )copyin ((uintptr_t )
137
- & ((node_dtrace_http_request_v0_t * )nd )-> method ,
249
+ & ((node_dtrace_http_server_request_v0_t * )nd )-> method ,
138
250
sizeof (uint32_t ))) :
139
251
copyinstr (* (uint64_t * )copyin ((uintptr_t )
140
- & ((node_dtrace_http_request64_v0_t * )nd )-> method ,
252
+ & ((node_dtrace_http_server_request64_v0_t * )nd )-> method ,
141
253
sizeof (uint64_t )))) :
142
254
(curpsinfo -> pr_dmodel == PR_MODEL_ILP32 ?
143
255
copyinstr (* (uint32_t * )copyin ((uintptr_t )
144
- & ((node_dtrace_http_request_v1_t * )nd )-> method ,
256
+ & ((node_dtrace_http_server_request_v1_t * )nd )-> method ,
145
257
sizeof (uint32_t ))) :
146
258
copyinstr (* (uint64_t * )copyin ((uintptr_t )
147
- & ((node_dtrace_http_request64_v1_t * )nd )-> method ,
259
+ & ((node_dtrace_http_server_request64_v1_t * )nd )-> method ,
148
260
sizeof (uint64_t ))));
149
-
150
- forwardedFor = (* (uint32_t * )
151
- copyin ((uintptr_t )& nd -> version , sizeof (uint32_t ))) >= 4096 ? "" :
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 ?
152
274
(curpsinfo -> pr_dmodel == PR_MODEL_ILP32 ?
153
275
copyinstr (* (uint32_t * )copyin ((uintptr_t )
154
- & ((node_dtrace_http_request_v1_t * )nd )-> forwardedFor ,
276
+ & ((node_dtrace_http_server_request_v0_t * )nd )-> url ,
155
277
sizeof (uint32_t ))) :
156
278
copyinstr (* (uint64_t * )copyin ((uintptr_t )
157
- & ((node_dtrace_http_request64_v1_t * )nd )-> forwardedFor ,
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 ,
158
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 ))));
159
315
};
0 commit comments