3
A brief file description
5
@section license License
7
Licensed to the Apache Software Foundation (ASF) under one
8
or more contributor license agreements. See the NOTICE file
9
distributed with this work for additional information
10
regarding copyright ownership. The ASF licenses this file
11
to you under the Apache License, Version 2.0 (the
12
"License"); you may not use this file except in compliance
13
with the License. You may obtain a copy of the License at
15
http://www.apache.org/licenses/LICENSE-2.0
17
Unless required by applicable law or agreed to in writing, software
18
distributed under the License is distributed on an "AS IS" BASIS,
19
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
See the License for the specific language governing permissions and
21
limitations under the License.
26
#include "ink_assert.h"
28
#include <netinet/in.h>
29
#include <sys/socket.h>
35
/* cvrt unsigned int address to dotted decimal address
36
* delete on the otherside, otherwise: don't care
39
uint2ddip(unsigned int addr)
41
char *ptr = (char *) TSmalloc(64);
45
unsigned int address = addr;
46
unsigned char *ip = (unsigned char *) &address;
48
sprintf(ptr, "%d.%d.%d.%d", (unsigned int) ip[0], (unsigned int) ip[1], (unsigned int) ip[2], (unsigned int) ip[3]);
54
/* Set in TSPluginInit */
55
typedef struct parentProxyInfo
57
char parentProxyp[BUFSIZ];
62
handle_SEND_REQUEST(TSCont contp, TSEvent event, void *eData)
64
TSHttpTxn txnp = (TSHttpTxn *) eData;
65
unsigned int nextHopIP = 0;
69
/* Origin Server (destination) or Parent IP
70
* TODO use return addr with an actual network library routine (gethostbyaddr) to validate addr
71
* TODO tests with an actual parent proxy
73
nextHopIP = TSHttpTxnNextHopIPGet(txnp);
75
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnNextHopIPGet failed");
78
ipAddrp = uint2ddip(nextHopIP);
79
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnNextHopIPGet passed for %s", ipAddrp ? ipAddrp : "NULL ptr!");
81
/* TODO validate this IP address, not just an integer value
89
* TSHttpTxnClientReqGet
90
* TSHttpTxnServerIPGet (specific)
93
* Test is to use the address returend by TSHttpTxnServerIPGet
94
* with a standard network interface api and compare that
95
* host with the hostname found in the request URL.
98
handle_OS_DNS(TSCont contp, TSEvent event, void *eData)
101
TSHttpTxn txnp = (TSHttpTxn *) eData;
102
struct in_addr inAddr;
103
struct hostent *hostEntp = NULL;
105
const char *reqURLHost = NULL;
107
char strTokenp = '.'; /* URLs separated by this token */
108
char *domain_os_ip = NULL, *domain_url = NULL;
110
unsigned int nextHopIP;
114
/* See: handle_SEND_REQUEST(): nextHopIP = TSHttpTxnNextHopIPGet(txnp);
116
os_ip = TSHttpTxnServerIPGet(txnp);
118
inAddr.s_addr = os_ip;
119
hostEntp = gethostbyaddr((const char *) &inAddr, sizeof(struct in_addr), AF_INET);
121
ptr = uint2ddip(os_ip);
123
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnServerIPGet: gethostbyaddr failed for %s", ptr ? ptr : "NULL ptr!");
129
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnServerIPGet: gethostbyaddr no hostname");
132
if (!TSHttpTxnClientReqGet(txnp, &buf, &loc)) {
134
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnServerIPGet: TSHttpTxnClientReqGet failed");
135
return ++err; /* ret here, else TSMHandleRelease */
138
if ((hdrLoc = TSHttpHdrUrlGet(buf, loc)) == NULL) {
140
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnServerIPGet: TSHttpHdrURLGet failed");
141
TSHandleMLocRelease(buf, TS_NULL_MLOC, loc);
142
return ++err; /* ret here, else TSMHandleRelease */
145
/* no memory del on reqURLHost */
146
reqURLHost = TSUrlHostGet(buf, hdrLoc, &hostLen);
147
if (!reqURLHost || !hostLen) {
149
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnServerIPGet: gethostbyaddr no hostname");
150
TSHandleMLocRelease(buf, TS_NULL_MLOC, loc);
153
/* compare the domains of the hostname
154
* from gethostbyaddr and TSURLHostGet: e.g.:
155
* w1.someGiantSite.com with a request of: www.someGiantSite.com
158
/* compare with domain (!host) from os_ip
161
domain_url = strchr((char *) reqURLHost, (int) strTokenp);
162
domain_os_ip = strchr(hostEntp->h_name, (int) strTokenp);
164
if (!domain_os_ip || !domain_url) {
165
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnServerIPGet: fail: strtok");
168
if (strncmp(++domain_os_ip, ++domain_url, BUFSIZ)) {
169
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnServerIPGet: fail: domain names %s != %s", domain_os_ip, domain_url);
173
TSHandleMLocRelease(buf, TS_NULL_MLOC, loc);
177
/* Currently not used. Interfaces like TSHttpTxnNextHopIPGet
178
* should only be called from SEND_REQUEST, inclusive, forward
181
handle_TXN_START(TSCont contp, TSEvent event, void *eData)
187
handle_TXN_CLOSE(TSCont contp, TSEvent event, void *eData)
191
TSHttpTxn txnp = (TSHttpTxn) eData;
192
char *hostNamep = NULL;
193
void *dataPtr = NULL;
195
char **hostname = NULL;
197
unsigned int os_addr = 0;
198
unsigned int clientIP, nextHopIP;
200
char *ipAddrp = NULL;
202
incomingPort = TSHttpTxnClientIncomingPortGet(txnp);
204
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnClientIncomingPortGet failed");
207
/* TODO validate this port, not just an integer value
211
/* Client IP for a transaction (not incoming) */
212
clientIP = TSHttpTxnClientIPGet(txnp);
214
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnClientIPGet failed");
217
/* TODO validate this IP address, not just an integer value
221
/* See: handle_SEND_REQUEST(): nextHopIP = TSHttpTxnNextHopIPGet(txnp);
223
* If origin server was contacted, its adress
224
* will be returned. Need a cach hit true/false interface ?
226
* Origin Server (destination) or Parent IP
227
* TODO tests with an actual parent proxy
229
nextHopIP = TSHttpTxnNextHopIPGet(txnp);
231
/* It is the responsibility of the plug-in to store hit/miss
232
* details and resolve this as TSHttpTxnNextHopIPGet failure
233
* or cache miss (no o.s. contected).
235
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnNextHopIPGet failed for or cache miss");
238
/* TODO validate this IP address, not just an integer value
242
/***********************************************************
243
* Failure in the following tests will cause remaining tests
246
os_addr = TSHttpTxnServerIPGet(txnp);
248
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnServerIPGet failed");
249
return ++err; /* failure */
252
hostname = (char **) TSmalloc(BUFSIZ);
253
/* if parent proxy is not set: re is -1
255
TSHttpTxnParentProxyGet(txnp, hostname, &hostPort);
256
/* TODO value of hostname when parent not set? */
257
if (hostPort == (-1) || *hostname == NULL) {
258
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnParentProxyGet failed");
259
/* return ++err; failure */
260
/* Allow other test to continue */
264
* Get the parent/port that were set at plug-in init
266
dataPtr = TSContDataGet(contp);
268
TSDebug("TSHttpTxnIPAddress", "TSContDataGet returned NULL pointer, cannot test TSHttpTxnParentProxySet");
272
TSDebug("TSHttpTxnIPAddress",
273
"Setting parent proxy to %s:%d",
274
((parentProxyInfo_t *) dataPtr)->parentProxyp, ((parentProxyInfo_t *) dataPtr)->parentPort);
276
/* TODO how do we check return value? */
277
TSHttpTxnParentProxySet(txnp,
278
((parentProxyInfo_t *) dataPtr)->parentProxyp, ((parentProxyInfo_t *) dataPtr)->parentPort);
280
/* parent proxy was set
282
TSHttpTxnParentProxyGet(txnp, hostname, &hostPort);
283
if (hostPort == (-1) || *hostname == NULL) {
284
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnParentProxyGet failed");
285
/* return ++err; failure */
286
/* Allow other test to continue */
290
if ((strncmp(*hostname,
291
((parentProxyInfo_t *) dataPtr)->parentProxyp, BUFSIZ)) ||
292
((parentProxyInfo_t *) dataPtr)->parentPort != hostPort) {
293
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnParentProxySet/Get failed");
303
TSHttpTransaction(TSCont contp, TSEvent event, void *eData)
305
TSHttpSsn ssnp = (TSHttpSsn) eData;
306
TSHttpTxn txnp = (TSHttpTxn) eData;
308
unsigned int nextHopIP = 0;
312
case TS_EVENT_HTTP_SSN_START:
313
TSHttpSsnHookAdd(ssnp, TS_HTTP_TXN_START_HOOK, contp);
314
TSHttpSsnHookAdd(ssnp, TS_HTTP_TXN_CLOSE_HOOK, contp);
315
TSHttpSsnHookAdd(ssnp, TS_HTTP_SEND_REQUEST_HDR_HOOK, contp);
316
TSHttpSsnHookAdd(ssnp, TS_HTTP_OS_DNS_HOOK, contp);
318
TSHttpSsnReenable(ssnp, TS_EVENT_HTTP_CONTINUE);
321
case TS_EVENT_HTTP_OS_DNS:
322
handle_OS_DNS(contp, event, eData);
323
TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
326
case TS_EVENT_HTTP_TXN_START:
327
handle_TXN_START(contp, event, eData);
328
TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
331
case TS_EVENT_HTTP_TXN_CLOSE:
332
handle_TXN_CLOSE(contp, event, eData);
333
TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
336
case TS_EVENT_HTTP_SEND_REQUEST_HDR:
337
handle_SEND_REQUEST(contp, event, eData);
338
TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
348
TSPluginInit(int argc, const char *argv[])
351
int length = 0, argCnt = 0;
352
ink_assert(argc == 3);
354
/* Passed in as args to the plug-in and does not get deleted
356
parentProxyInfo_t *parentInfop = (parentProxyInfo_t *) TSmalloc(sizeof(parentProxyInfo_t));
359
TSDebug("TSHttpTxnIPAddress", "TSmalloc(parentProxyInfo_t = [%d]) failed", sizeof(parentProxyInfo_t));
360
TSDebug("TSHttpTxnIPAddress", "TSHttpTxnIPAddress failed and did not run");
363
strncpy(parentInfop->parentProxyp, argv[++argCnt], strlen(argv[argCnt]));
364
parentInfop->parentPort = atoi(argv[++argCnt]);
366
TSCont contp = TSContCreate(TSHttpTransaction, NULL);
367
TSContDataSet(contp, (void *) parentInfop); /* Used in txn */
369
/* Never: TSfree(parentInfop);
370
* if you expect to use TSContDataGet
371
* not a leak since TS keeps a reference to this heap
373
* Here's a leak (bad stuff man!):
377
* TSConDataSet(contp, ptr);
379
* at some other event at a later time
381
* retreivePtr = TSContDataGet(contp);
382
* newPtr = Modify(retrievePtr);
383
* TSConDataSet(contp, newPtr);
384
* TSfree(retrievedPtr); if not freed, leak
387
TSHttpHookAdd(TS_HTTP_SSN_START_HOOK, contp);