introduction to ats plugins

57
Introduction to ATS plugins

Upload: psudaemon

Post on 11-May-2015

1.526 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Introduction to ATS plugins

Introduction to ATS plugins

Page 2: Introduction to ATS plugins

About Me● Phil Sorber● ATS Committer● Work for OmniTI

Page 3: Introduction to ATS plugins

About This Tutorial● Introductory Overview● Example Walkthrough● Assuming you haven't written a plugin for

ATS before but that you have some programming knowledge

● C API (we also have C++11 and Lua)

Page 4: Introduction to ATS plugins

Brief History● Inktomi 1996● Yahoo! 2002● ASF 2009● ASF TLP 2010● INK -> TS

Page 5: Introduction to ATS plugins

Architecturethreaded + async state machine model

● Event Processors● State Machines● Continuations

Page 6: Introduction to ATS plugins

Architecture

Page 7: Introduction to ATS plugins

What's in a plugin?1. Initialization2. Hook Registration3. Handle Events in continuations (do work)

Page 8: Introduction to ATS plugins

Initialization#include <ts/ts.h>

voidTSPluginInit (int argc, const char *argv[])

Page 9: Introduction to ATS plugins

InitializationvoidTSPluginInit (int argc, const char *argv[]){ TSPluginRegistrationInfo info; MyStateInfo state;

info.plugin_name = "foobar"; info.vendor_name = "foobar inc"; info.support_email = "[email protected]";

Page 10: Introduction to ATS plugins

InitializationvoidTSPluginInit (int argc, const char *argv[]){... if (TSPluginRegister(TS_SDK_VERSION_3_0, &info) != TS_SUCCESS) { TSError("Plugin registration failed.\n"); return; } else { TSDebug(LOG_PREFIX, "Plugin registration succeeded.\n"); }

Page 11: Introduction to ATS plugins

InitializationvoidTSPluginInit (int argc, const char *argv[]){... state = TSmalloc(sizeof(MyStateInfo)); TSHttpArgIndexReserve("plugin_txn_state", "txn state info for plugin", &state->txn_slot); state->my_mutex = TSMutexCreate(); my_cont = TSContCreate(my_cont_func, NULL); TSContDataSet(my_cont, (void *) state);

Page 12: Introduction to ATS plugins

Global Hook Reg.voidTSPluginInit (int argc, const char *argv[]){... TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, main_cont);}

Page 13: Introduction to ATS plugins

Global Hook Reg.TSHttpHookAdd: adds a global hook. You can globally add any hook except for TS_HTTP_REQUEST_TRANSFORM_HOOK and TS_HTTP_RESPONSE_TRANSFORM_HOOK.

The following hooks can ONLY be added globally:● TS_HTTP_SELECT_ALT_HOOK● TS_HTTP_SSN_START_HOOK● TS_HTTP_SSN_CLOSE_HOOK

Page 14: Introduction to ATS plugins

Hook RegistrationTSHttpSsnHookAdd: adds a transaction hook to each transaction within a session.TSHttpTxnHookAdd: adds a callback at a specific point within an HTTP transaction.

Page 15: Introduction to ATS plugins

Hooks● TS_HTTP_READ_REQUEST_HDR_HOOK● TS_HTTP_OS_DNS_HOOK● TS_HTTP_SEND_REQUEST_HDR_HOOK● TS_HTTP_READ_CACHE_HDR_HOOK● TS_HTTP_READ_RESPONSE_HDR_HOOK● TS_HTTP_SEND_RESPONSE_HDR_HOOK● TS_HTTP_REQUEST_TRANSFORM_HOOK● TS_HTTP_RESPONSE_TRANSFORM_HOOK● TS_HTTP_SELECT_ALT_HOOK● TS_HTTP_TXN_START_HOOK● TS_HTTP_TXN_CLOSE_HOOK● TS_HTTP_SSN_START_HOOK● TS_HTTP_SSN_CLOSE_HOOK● TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK● TS_HTTP_PRE_REMAP_HOOK● TS_HTTP_POST_REMAP_HOOK

Page 16: Introduction to ATS plugins

Hooks

Page 17: Introduction to ATS plugins

Hooks

Page 18: Introduction to ATS plugins

Hooks

Page 19: Introduction to ATS plugins

Doing the work

Page 20: Introduction to ATS plugins

The Continuationstatic int

my_cont_func(TSCont cont, TSEvent event, void *edata){ TSHttpTxn txn = (TSHttpTxn) edata; MyStateInfo state; MyTxnInfo tinfo;

switch (event) {

Page 21: Introduction to ATS plugins

The Continuationstatic int

my_cont_func(TSCont cont, TSEvent event, void *edata){ ... case TS_EVENT_HTTP_READ_REQUEST_HDR: if (TSHttpIsInternalRequest(txn) != TS_SUCCESS) { tinfo = TSmalloc(sizeof(MyTxnInfo)); time(&tinfo->txn_start); tinfo->req_info = my_get_req_info(txn); state = (MyStateInfo *) TSContDataGet(cont); TSHttpTxnArgSet(txn, state->txn_slot, (void *) tinfo); TSHttpTxnHookAdd(txn, TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK, cont); } TSHttpTxnReenable(txn, TS_EVENT_HTTP_CONTINUE); break;

Page 22: Introduction to ATS plugins

The Continuationstatic int

my_cont_func(TSCont cont, TSEvent event, void *edata){ ... case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE: state = (MyStateInfo *) TSContDataGet(cont); tinfo = (MyStateInfo *) TSHttpTxnArgGet(txn, state->txn_slot); if (TSHttpTxnCacheLookupStatusGet(txn, &status) == TS_SUCCESS) { if (status == TS_CACHE_LOOKUP_HIT_STALE) {

Page 23: Introduction to ATS plugins

ContinuationsTSCont TSContCreate(TSEventFunc funcp, TSMutex mutexp);

void TSContDestroy(TSCont contp);

void TSContDataSet(TSCont contp, void* data);

void* TSContDataGet(TSCont contp);

TSAction TSContSchedule(TSCont contp, TSHRTime timeout, TSThreadPool tp);

TSAction TSContScheduleEvery(TSCont contp, TSHRTime every, TSThreadPool tp);

TSAction TSHttpSchedule(TSCont contp, TSHttpTxn txnp, TSHRTime timeout);

int TSContCall(TSCont contp, TSEvent event, void* edata);

TSMutex TSContMutexGet(TSCont contp);

Page 24: Introduction to ATS plugins

TransactionsA Request and the associated

response

void TSHttpTxnHookAdd(TSHttpTxn txnp, TSHttpHookID id, TSCont contp);

void TSHttpTxnReenable(TSHttpTxn txnp, TSEvent event);

Page 25: Introduction to ATS plugins

TransactionsGets the client request header for a specified HTTP

transaction:TSReturnCode TSHttpTxnClientReqGet(TSHttpTxn txnp, TSMBuffer*

bufp, TSMLoc* offset);

Gets the client response header for a specified HTTP transaction:

TSReturnCode TSHttpTxnClientRespGet(TSHttpTxn txnp, TSMBuffer* bufp, TSMLoc* offset);

Gets the server request header from a specified HTTP transaction:

TSReturnCode TSHttpTxnServerReqGet(TSHttpTxn txnp, TSMBuffer* bufp, TSMLoc* offset);

Page 26: Introduction to ATS plugins

TransactionsGets the server response header from a specified HTTP

transaction:TSReturnCode TSHttpTxnServerRespGet(TSHttpTxn txnp,

TSMBuffer* bufp, TSMLoc* offset);

Gets the cached request header for a specified HTTP transaction:

TSReturnCode TSHttpTxnCachedReqGet(TSHttpTxn txnp, TSMBuffer* bufp, TSMLoc* offset);

Gets the cached response header for a specified HTTP transaction:

TSReturnCode TSHttpTxnCachedRespGet(TSHttpTxn txnp, TSMBuffer* bufp, TSMLoc* offset);

Page 27: Introduction to ATS plugins

Transaction DataTSReturnCode TSHttpArgIndexReserve(const char* name, const char* description, int* arg_idx);

TSReturnCode TSHttpArgIndexNameLookup(const char* name, int* arg_idx, const char** description);

TSReturnCode TSHttpArgIndexLookup(int arg_idx, const char** name, const char** description);

void TSHttpTxnArgSet(TSHttpTxn txnp, int arg_idx, void* arg);

void* TSHttpTxnArgGet(TSHttpTxn txnp, int arg_idx);

void TSHttpSsnArgSet(TSHttpSsn ssnp, int arg_idx, void* arg);

void* TSHttpSsnArgGet(TSHttpSsn ssnp, int arg_idx);

Page 28: Introduction to ATS plugins

Sessionsvoid TSHttpSsnHookAdd(TSHttpSsn ssnp, TSHttpHookID id, TSCont contp);

void TSHttpSsnReenable(TSHttpSsn ssnp, TSEvent event);

int TSHttpSsnTransactionCount(TSHttpSsn ssnp);

TSHttpSsn TSHttpTxnSsnGet(TSHttpTxn txnp);

Page 29: Introduction to ATS plugins

Remapping#include <ts/remap.h>

int TSRemapInit(TSRemapInterface *api_info, char *errbuf, int errbuf_size);

int TSRemapNewInstance(int argc, char *argv[], void **ih, char *errbuf, int errbuf_size);

TSRemapStatus TSRemapDoRemap(void* ih, TSHttpTxn rh, TSRemapRequestInfo *rri);

void TSRemapDeleteInstance(void* ih);

void TSRemapOSResponse(void* ih, TSHttpTxn rh, int os_response_type);

Page 30: Introduction to ATS plugins

Remappingremap.config:

map http://www.example.com/search http://srch1.example.com/search @plugin=query_remap.so@pparam=q@pparam=srch1.example.com @pparam=srch2.example.com @pparam=srch3.example.com

map http://www.example.com/profiles http://prof1.example.com/profiles @plugin=query_remap.so@pparam=user_id@pparam=prof1.example.com @pparam=prof2.example.com

Page 31: Introduction to ATS plugins

Marshal BuffersTSMBuffer is a heap data structure that

stores parsed:● URLs● HTTP Headers● MIME HeadersTo manipulate these you need a handle to the object (TSMLoc)

Page 32: Introduction to ATS plugins

Marshal BuffersTSMBuffer TSMBufferCreate(void);

TSReturnCode TSMBufferDestroy(TSMBuffer bufp);

TSReturnCode TSHandleMLocRelease(TSMBuffer bufp, TSMLoc parent, TSMLoc mloc);

Page 33: Introduction to ATS plugins

URLsTSReturnCode TSUrlCreate(TSMBuffer bufp, TSMLoc* locp);

TSParseResult TSUrlParse(TSMBuffer bufp, TSMLoc offset, const char** start, const char* end);

char* TSUrlStringGet(TSMBuffer bufp, TSMLoc offset, int* length);

int TSUrlPortGet(TSMBuffer bufp, TSMLoc offset);

const char* TSUrlHttpQueryGet(TSMBuffer bufp, TSMLoc offset, int* length);

const char* TSUrlHttpFragmentGet(TSMBuffer bufp, TSMLoc offset, int* length);

Page 34: Introduction to ATS plugins

HTTP HeadersGET http://www.tiggerwigger.com/ HTTP/1.0Proxy-Connection: Keep-AliveUser-Agent: Mozilla/5.0 [en] (X11; I; Linux 2.2.3 i686)Host: www.tiggerwigger.comAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*Accept-Encoding: gzipAccept-Language: enAccept-Charset: iso-8859-1, *, utf-8

HTTP/1.0 200 OKDate: Fri, 13 Nov 2009 06:57:43 GMTContent-Location: http://locutus.tiggerwigger.com/index.htmlEtag: "07db14afa76be1:1074"Last-Modified: Thu, 05 Nov 2009 20:01:38 GMTContent-Length: 7931Content-Type: text/htmlServer: Microsoft-IIS/4.0Age: 922Proxy-Connection: close

Page 35: Introduction to ATS plugins

HTTP HeadersTSMLoc TSHttpHdrCreate(TSMBuffer bufp);

void TSHttpHdrDestroy(TSMBuffer bufp, TSMLoc offset);

TSHttpType TSHttpHdrTypeGet(TSMBuffer bufp, TSMLoc offset);

int TSHttpHdrVersionGet(TSMBuffer bufp, TSMLoc offset);

const char* TSHttpHdrMethodGet(TSMBuffer bufp, TSMLoc offset, int* length);

TSReturnCode TSHttpHdrUrlGet(TSMBuffer bufp, TSMLoc offset, TSMLoc* locp);

TSHttpStatus TSHttpHdrStatusGet(TSMBuffer bufp, TSMLoc offset);

const char* TSHttpHdrReasonGet(TSMBuffer bufp, TSMLoc offset, int* length);

Page 36: Introduction to ATS plugins

MIME HeadersTSReturnCode TSMimeHdrCreate(TSMBuffer bufp, TSMLoc* locp);

TSReturnCode TSMimeHdrDestroy(TSMBuffer bufp, TSMLoc offset);

TSParseResult TSMimeHdrParse(TSMimeParser parser, TSMBuffer bufp, TSMLoc offset, const char** start, const char* end);

Page 37: Introduction to ATS plugins

MIME Header FieldsTSReturnCode TSMimeHdrFieldCreate(TSMBuffer bufp, TSMLoc hdr, TSMLoc* locp);

TSReturnCode TSMimeHdrFieldCreateNamed(TSMBuffer bufp, TSMLoc mh_mloc, const char* name, int name_len, TSMLoc* locp);

TSReturnCode TSMimeHdrFieldDestroy(TSMBuffer bufp, TSMLoc hdr, TSMLoc field);

int TSMimeHdrFieldsCount(TSMBuffer bufp, TSMLoc offset);

TSMLoc TSMimeHdrFieldGet(TSMBuffer bufp, TSMLoc hdr, int idx);

TSMLoc TSMimeHdrFieldFind(TSMBuffer bufp, TSMLoc hdr, const char* name, int length);

TSMLoc TSMimeHdrFieldNext(TSMBuffer bufp, TSMLoc hdr, TSMLoc field);

Page 38: Introduction to ATS plugins

MIME Hdr Fld Valsint TSMimeHdrFieldValuesCount(TSMBuffer bufp, TSMLoc hdr, TSMLoc field);

const char* TSMimeHdrFieldValueStringGet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx, int* value_len_ptr);

time_t TSMimeHdrFieldValueDateGet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field);

TSReturnCode TSMimeHdrFieldValueDelete(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx);

Page 39: Introduction to ATS plugins

VConnections● Specialized Continuation● Abstraction for async IO● You read from or write to a VConn

Page 40: Introduction to ATS plugins

VConnectionsint TSVConnClosedGet(TSVConn connp);

TSVIO TSVConnRead(TSVConn connp, TSCont contp, TSIOBuffer bufp, int64_t nbytes);

TSVIO TSVConnWrite(TSVConn connp, TSCont contp, TSIOBufferReader readerp, int64_t nbytes);

void TSVConnClose(TSVConn connp);

void TSVConnAbort(TSVConn connp, int error);

void TSVConnShutdown(TSVConn connp, int read, int write);

Page 41: Introduction to ATS plugins

IOBuffers● TSIOBuffer transfers data to/from a

VConn● A TSIOBuffer has TSIOBufferBlock's● A TSIOBufferBlock has TSIOBufferData's● One writer but can be multiple readers● Readers need no knowledge of each

other and coordinate through a TSIOBufferReader

Page 42: Introduction to ATS plugins

IOBuffersTSIOBuffer TSIOBufferCreate(void);

TSIOBuffer TSIOBufferSizedCreate(TSIOBufferSizeIndex index);

void TSIOBufferWaterMarkSet(TSIOBuffer bufp, int64_t water_mark);

void TSIOBufferDestroy(TSIOBuffer bufp);

int64_t TSIOBufferCopy(TSIOBuffer bufp, TSIOBufferReader readerp, int64_t length, int64_t offset);

int64_t TSIOBufferWrite(TSIOBuffer bufp, const void* buf, int64_t length);

Page 43: Introduction to ATS plugins

IOBuffer ReadersTSIOBufferReader TSIOBufferReaderAlloc(TSIOBuffer bufp);

void TSIOBufferReaderFree(TSIOBufferReader readerp);

Page 44: Introduction to ATS plugins

VIOs● State of the IO transaction● Every VConn has an input and output

VIO

Page 45: Introduction to ATS plugins

VIOsvoid TSVIOReenable(TSVIO viop);

TSIOBuffer TSVIOBufferGet(TSVIO viop);

TSIOBufferReader TSVIOReaderGet(TSVIO viop);

int64_t TSVIONBytesGet(TSVIO viop);

void TSVIONBytesSet(TSVIO viop, int64_t nbytes);

int64_t TSVIONDoneGet(TSVIO viop);

void TSVIONDoneSet(TSVIO viop, int64_t ndone);

int64_t TSVIONTodoGet(TSVIO viop);

TSVConn TSVIOVConnGet(TSVIO viop);

Page 46: Introduction to ATS plugins

TransformsTSVConn TSTransformCreate(TSEventFunc event_funcp, TSHttpTxn txnp);

TSVConn TSTransformOutputVConnGet(TSVConn connp);

Page 47: Introduction to ATS plugins

Transformsstatic inttransform_plugin(TSCont contp, TSEvent event, void *edata){ TSHttpTxn txnp = (TSHttpTxn) edata; TSVConn connp;

switch (event) { case TS_EVENT_HTTP_READ_RESPONSE_HDR: connp = TSTransformCreate(bnull_transform, txnp); TSHttpTxnHookAdd(txnp, TS_HTTP_RESPONSE_TRANSFORM_HOOK, connp);

Page 48: Introduction to ATS plugins

Actionsvoid TSActionCancel(TSAction actionp);

int TSActionDone(TSAction actionp);

Page 49: Introduction to ATS plugins

Alternate SelectionTSReturnCode TSHttpAltInfoClientReqGet(TSHttpAltInfo infop, TSMBuffer* bufp, TSMLoc* offset);

TSReturnCode TSHttpAltInfoCachedReqGet(TSHttpAltInfo infop, TSMBuffer* bufp, TSMLoc* offset);

TSReturnCode TSHttpAltInfoCachedRespGet(TSHttpAltInfo infop, TSMBuffer* bufp, TSMLoc* offset);

void TSHttpAltInfoQualitySet(TSHttpAltInfo infop, float quality);

Page 50: Introduction to ATS plugins

Statisticsint TSStatCreate(const char* the_name, TSRecordDataType the_type, TSStatPersistence persist, TSStatSync sync);

void TSStatIntIncrement(int the_stat, TSMgmtInt amount);

void TSStatIntDecrement(int the_stat, TSMgmtInt amount);

TSMgmtInt TSStatIntGet(int the_stat);

void TSStatIntSet(int the_stat, TSMgmtInt value);

Page 51: Introduction to ATS plugins

Threadstypedef void *(*TSThreadFunc) (void* data);

TSThread TSThreadCreate(TSThreadFunc func, void* data);

TSThread TSThreadInit(void);

void TSThreadDestroy(TSThread thread);

TSThread TSThreadSelf(void);

Page 52: Introduction to ATS plugins

MutexesTSMutex my_mutex;

my_mutex = TSMutexCreate();

TSMutexLock(my_mutex);

...

TSMutexUnlock(my_mutex);

TSReturnCode rc;

rc = TSMutexLockTry(my_mutex);

Page 53: Introduction to ATS plugins

Memory Mgmtvoid* TSmalloc(size_t size, const char* path);

void* TSrealloc(void* ptr, size_t size, const char* path);

char* TSstrdup(const char* str, int64_t length, const char* path);

size_t TSstrlcpy(char *dst, const char *str, size_t siz);

size_t TSstrlcat(char *dst, const char *str, size_t siz);

void TSfree(void* ptr);

Page 54: Introduction to ATS plugins

Loggingvoid TSDebug(const char* tag, const char* format_str, ...);

void TSError(const char* fmt, ...);

TSTextLogObject

TSReturnCode TSTextLogObjectCreate(const char* filename, int mode, TSTextLogObject* new_log_obj);

TSReturnCode TSTextLogObjectWrite(TSTextLogObject the_object, const char* format, ...);

Page 55: Introduction to ATS plugins

Cache APITSCacheKey TSCacheKeyCreate(void);

TSReturnCode TSCacheKeyDigestSet(TSCacheKey key, const char* input, int length);

TSReturnCode TSCacheKeyDestroy(TSCacheKey key);

TSAction TSCacheRead(TSCont contp, TSCacheKey key);

TSAction TSCacheWrite(TSCont contp, TSCacheKey key);

TSAction TSCacheRemove(TSCont contp, TSCacheKey key);

Page 56: Introduction to ATS plugins

Compiling

tsxs -I/usr/lib/include -lfoo -c plugin.c -o plugin.so

tsxs -i -o plugin.so

Page 57: Introduction to ATS plugins

Questions?

Email: [email protected]: @PhilSorberIRC: PSUdaemon in freenode/#traffic-

server

Come find me with your questions!