TSVConnFdCreate¶
Create a TSVConn from a socket.
Synopsis¶
#include <ts/ts.h>
Description¶
TSVConnFdCreate()
accepts a network socket fd and returns a new
TSVConn
constructed from the socket. The socket descriptor must be an
already connected socket. It will be placed into non-blocking mode.
Return Values¶
On success, the returned TSVConn
object owns the socket and the
caller must not close it. If TSVConnFdCreate()
fails, nullptr
is returned, the socket is unchanged and the caller must close it.
Examples¶
The example below is excerpted from example/plugins/c-api/intercept/intercept.cc
in the Traffic Server source distribution. It demonstrates how to
use TSVConnFdCreate()
to construct a TSVConn
from a
connected socket.
char buf[INET_ADDRSTRLEN];
socket_type addr;
argument_type cdata(TSContDataGet(contp));
InterceptState *istate = new InterceptState();
int fd = -1;
// This event is delivered by the continuation that we
// attached in InterceptTxnHook, so the continuation data is
// the TSHttpTxn pointer.
VDEBUG("allocated server intercept state istate=%p for txn=%p", istate, cdata.txn);
// Set up a connection to our real origin, which will be
// 127.0.0.1:$PORT.
memset(&addr, 0, sizeof(addr));
addr.sin.sin_family = AF_INET;
addr.sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); // XXX config option
addr.sin.sin_port = htons(PORT); // XXX config option
// Normally, we would use TSNetConnect to connect to a secondary service, but to demonstrate
// the use of TSVConnFdCreate, we do a blocking connect inline. This it not recommended for
// production plugins, since it might block an event thread for an arbitrary time.
fd = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
TSReleaseAssert(fd != -1);
if (::connect(fd, &addr.sa, sizeof(addr.sin)) == -1) {
// We failed to connect to the intercepted origin. Abort the
// server intercept since we cannot handle it.
VDEBUG("connect failed with %s (%d)", strerror(errno), errno);
TSVConnAbort(arg.vc, TS_VC_CLOSE_ABORT);
delete istate;
TSContDestroy(contp);
::close(fd);
return TS_EVENT_NONE;
}
if ((istate->server.vc = TSVConnFdCreate(fd)) == nullptr) {
VDEBUG("TSVconnFdCreate() failed");
TSVConnAbort(arg.vc, TS_VC_CLOSE_ABORT);
delete istate;
TSContDestroy(contp);
::close(fd);
return TS_EVENT_NONE;
}
VDEBUG("binding client vc=%p to %s:%u", istate->client.vc, inet_ntop(AF_INET, &addr.sin.sin_addr, buf, sizeof(buf)),
See Also¶
TSAPI(3ts)