TSCLIENTPROTOCOLSTACK(3ts)

πŸ“¦
version 9.2.5 Β· 5 versions
, in ubuntu questing

πŸ’– TSCLIENTPROTOCOLSTACK πŸ’–

okay bestie, gather round, because we're doing the TSClientProtocolStack API function from Apache Traffic Server and it's actually iconic. this is TSCLIENTPROTOCOLSTACK(3ts), section 3ts, and yes we're about to get intimately acquainted with protocol stacks. no cap. πŸ¦‹


✨ NAME ✨

TSClientProtocolStack β€” the TSClientProtocolStack API function, aka the thing that lets you peek at the actual stack of protocols running under a connection. it's giving detective energy πŸ”


🌸 SYNOPSIS 🌸

#include <ts/ts.h>

TSReturnCode TSHttpTxnClientProtocolStackGet(TSHttpTxn txnp, int count,
char const **result, int *actual)

TSReturnCode TSHttpTxnServerProtocolStackGet(TSHttpTxn txnp, int count,
const char **result, int *actual)

TSReturnCode TSHttpSsnClientProtocolStackGet(TSHttpSsn ssnp, int count,
char const **result, int *actual)

char const *TSHttpTxnClientProtocolStackContains(TSHttpTxn txnp)

const char *TSHttpTxnServerProtocolStackContains(TSHttpTxn txnp, char
const *tag)

char const *TSHttpSsnClientProtocolStackContains(TSHttpSsn ssnp)

char const *TSNormalizedProtocolTag(char const *tag)

char const *TSRegisterProtocolTag(char const *tag)

like, eight whole functions. we ate. πŸ’…


πŸ‘‘ DESCRIPTION πŸ‘‘

so these functions are how you go snooping through the protocol stack of either the client (user agent) connection or the origin server connection to Traffic Server. two directions, both juicy.

  • TSHttpTxnClientProtocolStackGet() and TSHttpSsnClientProtocolStackGet() β€” grab the entire protocol stack for the user agent connection. the whole thing, front to back.
  • TSHttpTxnServerProtocolStackGet() β€” same deal but for the origin server connection. server side representation ✨
  • TSHttpTxnClientProtocolStackContains(), TSHttpSsnClientProtocolStackContains(), and TSHttpTxnServerProtocolStackContains() β€” these ones don't want the whole list, they just want to know is this specific protocol tag in the stack or not. yes/no vibes only.

every protocol is represented by a tag, which is a null terminated string. and here's the cute part: a particular tag will always come back as the same character pointer, so you can reliably check protocols with pointer comparisons. like, literally just compare the pointers. slay. πŸ”₯

TSNormalizedProtocolTag() hands you that character pointer for a specific tag. if it returns NULL, that means the tag you handed it is not registered as a known protocol tag. sorry bestie. 😭

TSRegisterProtocolTag() registers the tag and then returns its normalized value β€” which is exactly what you want if you're a plugin providing custom protocols for user agents. custom protocol? go off, register your tag. πŸŽ€

🧚 the ordering thing (important, don't skip)

the protocols are ordered from higher level protocols to the lower level ones on which the higher operate. so for example, a stack might look like:

"http/1.1,tls/1.2,tcp,ipv4"

see how it descends? high level β†’ low level. beautiful. 🌈

πŸ’œ how the Get functions actually fill stuff in

for TSHttpTxnClientProtocolStackGet(), TSHttpSsnClientProtocolStackGet(), and TSHttpTxnServerProtocolStackGet(), these values get placed in the array result.

  • count is the maximum number of elements of result that the function call is allowed to modify.
  • if actual is not NULL, then the actual number of elements in the protocol stack gets returned there.

and now the math:

  • if actual is equal to or less than count β†’ all the elements were returned. you got the whole stack, congrats. πŸ’–
  • if actual is larger β†’ some layers were omitted from result. you got a partial stack, rip.

if you need the full stack, you can use actual to resize result so it's big enough to hold all the elements, then call the function again with the updated count and result. that's the two-pass move, iykyk. in practice the maximum number of elements is almost certain to be less than 10, which therefore should suffice.

these functions return TS_SUCCESS on success and TS_ERROR on failure, and that failure should only occur if txnp or ssnp are invalid. invalid handle = error, that's it, no other drama. ⭐

πŸ” the Contains functions

TSHttpTxnClientProtocolStackContains(), TSHttpSsnClientProtocolStackContains(), and TSHttpTxnServerProtocolStackContains() exist for convenience β€” for when you only care about the presence of a protocol, not its location and not whether other protocols are there. low maintenance, high value.

  • returns NULL if the protocol tag is not present.
  • returns a pointer to the normalized tag if it is present.

the strings are matched with an anchor prefix search, exactly like debug tags. so for instance, if tag is "tls", it'll match "tls/1.2" or "tls/1.3". that makes checking for TLS or IP way more convenient. if you need more precision than that, you can always retrieve the entire protocol stack and process it more thoroughly. main character thoroughness. πŸ‘‘

🌟 The protocol tags defined by Traffic Server

  • http/1.1 β€” HTTP/1.1
  • http/1.0 β€” HTTP/1.0
  • h2 β€” HTTP/2
  • ws β€” WebSocket
  • tls/1.3 β€” TLS 1.3
  • tls/1.2 β€” TLS 1.2
  • tls/1.1 β€” TLS 1.1
  • tls/1.0 β€” TLS 1.0
  • tcp β€” TCP
  • udp β€” UDP
  • ipv4 β€” IPv4
  • ipv6 β€” IPv6
  • quic β€” QUIC

that's the whole roster, all thirteen of them, no edits, no cuts. 🫢


πŸ“ Examples

the example below is excerpted from example/plugins/c-api/protocol_stack/protocol_stack.cc in the Traffic Server source distribution. it demonstrates how to use TSHttpTxnClientProtocolStackGet() and TSHttpTxnClientProtocolStackContains(). so cute that it's a real file you can go read.

static int
proto_stack_cb(TSCont contp ATS_UNUSED, TSEvent event, void *edata)
{
  TSHttpTxn txnp = static_cast<TSHttpTxn>(edata);
  const char *results[10];
  int count = 0;
  TSDebug(PLUGIN_NAME, "Protocols:");
  TSHttpTxnClientProtocolStackGet(txnp, 10, results, &count);
  for (int i = 0; i < count; i++) {
    TSDebug(PLUGIN_NAME, "\t%d: %s", i, results[i]);
  }
  const char *ret_tag = TSHttpTxnClientProtocolStackContains(txnp, "h2");
  TSDebug(PLUGIN_NAME, "Stack %s HTTP/2", ret_tag != nullptr ? "contains" : "does not contain");
  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
  return 0;
}

look at that. ten-element array, count starts at zero, loop prints every protocol, then it asks the stack if it's got h2 in it. the whole flow is a vibe. 🌸


2026, dev@trafficserver.apache.org


and that's the whole page, bestie!! πŸŽ€ this was Apache Traffic Server, TSCLIENTPROTOCOLSTACK(3ts), version 9.2, dated Feb 12, 2026. go forth and interrogate some protocol stacks, you absolute icon. periodt. πŸ’…βœ¨πŸ¦‹

πŸ“¦ where this page comes from