tcp.c
资源名称:socks5.zip [点击查看]
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:19k
源码类别:
代理服务器
开发平台:
Unix_Linux
- /* Copyright (c) 1995,1996,1997 NEC Corporation. All rights reserved. */
- /* */
- /* The redistribution, use and modification in source or binary forms of */
- /* this software is subject to the conditions set forth in the copyright */
- /* document ("Copyright") included with this distribution. */
- /*
- * $Id: tcp.c,v 1.74.2.1.2.5 1998/11/04 00:03:39 steve Exp $
- */
- /* This file has all the function to do tcp proxying itself. The only one */
- /* that is visible to the outside world should be HandleTcpConnection. */
- #include "socks5p.h"
- #include "threads.h"
- #include "daemon.h"
- #include "validate.h"
- #include "protocol.h"
- #include "msgids.h"
- #include "sident.h"
- #include "flow.h"
- #include "info.h"
- #include "null.h"
- #include "log.h"
- #include "tcp.h"
- #include "msg.h"
- #include "s2s.h"
- #ifdef DONT_SUPPORT_RCMD
- #define doRcmd 0 /* I will support rcmd's... */
- #else
- #define doRcmd 1 /* I won't support rcmd's.... */
- #endif
- #ifndef ACCEPT_TIMEOUT
- #define ACCEPT_TIMEOUT 60
- #endif
- struct tcpinfo {
- S5IOInfo iio, oio;
- char idtentry[IDTENTRY_SIZE];
- int ndests, exitval;
- char *packetbuf;
- };
- typedef struct tcpinfo TcpInfo;
- #define ResvPort(x) ((int)ntohs(lsAddr2Port((x))) < IPPORT_RESERVED && (int)ntohs(lsAddr2Port((x))) >= (IPPORT_RESERVED/2))
- #define PortDecr(x) (lsAddrSetPort((x), htons(ntohs(lsAddr2Port((x)))-1)))
- /* Send a status message back to the client with socks_err if the client was */
- /* a socks server or socks5_err if it was a socks5 server...res is the */
- /* result of the current state of connection...connect host for connect, */
- /* bound host for bind, accepted host for accept...Don't send more than the */
- /* client expects though (1 for connect, 2 for bind/accept...) */
- static int SendDest(S5LinkInfo *pri, TcpInfo *tcpinfo, const S5NetAddr *res, u_char s5error, u_char s4error) {
- S5NetAddr tmp;
- if (tcpinfo->ndests++ >= ((pri->peerCommand==SOCKS_CONNECT)?1:2)) return 0;
- if (pri->peerVersion == SOCKS4_VERSION) {
- if (res->sa.sa_family != AF_INET) {
- memset(&tmp, 0, sizeof(S5NetAddr));
- tmp.sin.sin_addr.s_addr = INADDR_ANY;
- tmp.sin.sin_port = 0;
- tmp.sin.sin_family = AF_INET;
- res = &tmp;
- }
- }
- if (!lsSendResponse(tcpinfo->iio.fd, &tcpinfo->iio, res, pri->peerVersion, (pri->peerVersion == SOCKS5_VERSION)?s5error:s4error, pri->nextReserved, NULL)) return 0;
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "TCP Sending Response failed");
- return -1;
- }
- /* Perform the connect command. Basically connect to the client, send any */
- /* protocol necessary (via RRconnect), get our peer's name, and then send */
- /* that info back to the client...(dumb?)... */
- static int TcpConnect(S5LinkInfo *pri, TcpInfo *tcpinfo, u_char *s5ep, u_char *s4ep) {
- int len = sizeof(ssi);
- if (pri->nextVersion) {
- if (S5SExchangeProtocol(&tcpinfo->iio, &tcpinfo->oio, pri, tcpinfo->idtentry, &pri->dstAddr, &pri->intAddr) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "TCP Connect to %s:%d failed: %m", ADDRANDPORT(&pri->dstAddr));
- *s5ep = (ISSOCKETERROR(ETIMEDOUT))?SOCKS5_TTLEXP:SOCKS5_CONNREF;
- return EXIT_ERR;
- }
- } else {
- GetRoute(&pri->dstAddr, pri->dstName, "tcp", &pri->intAddr);
- /* If the client had a reserved port and we support that ability, */
- /* reserve a port... */
- if (doRcmd && ResvPort(&pri->srcAddr)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "TCP Setup: trying to reserve port");
- lsAddrSetPort(&pri->intAddr, htons(IPPORT_RESERVED-1));
- for ( ; ResvPort(&pri->intAddr); PortDecr(&pri->intAddr)) {
- if (!bind(tcpinfo->oio.fd, &pri->intAddr.sa, lsAddrSize(&pri->intAddr))) break;
- if (ISSOCKETERROR(EADDRINUSE)) continue;
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "TCP Setup: Failed to get reserved port: %m");
- return EXIT_ERR;
- }
- if (lsAddr2Port(&pri->intAddr) == htons(IPPORT_RESERVED/2-1)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "TCP Setup: Failed to get reserved port: %m");
- return EXIT_ERR;
- }
- } else if (bind(tcpinfo->oio.fd, &pri->intAddr.sa, lsAddrSize(&pri->intAddr)) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "TCP Setup: Failed to bind to out interface: %m");
- return EXIT_ERR;
- }
- if (connect(tcpinfo->oio.fd, &pri->dstAddr.sa, lsAddrSize(&pri->dstAddr)) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "TCP Connect to %s:%d failed: %m", ADDRANDPORT(&pri->dstAddr));
- return EXIT_ERR;
- }
- MakeIdentEntry(tcpinfo->iio.fd, tcpinfo->oio.fd, pri, tcpinfo->idtentry);
- if (getsockname(tcpinfo->oio.fd, &pri->intAddr.sa, &len) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "TCP Getsockname failed: %m");
- return EXIT_ERR;
- }
- }
- if (SendDest(pri, tcpinfo, &pri->intAddr, SOCKS5_RESULT, SOCKS_RESULT) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "TCP SendDest failed: %m");
- return EXIT_NETERR;
- }
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "TCP out interface %s:%d", ADDRANDPORT(&pri->intAddr));
- return EXIT_OK;
- }
- static int TcpBind(S5LinkInfo *pri, TcpInfo *tcpinfo, u_char *s5ep, u_char *s4ep) {
- int len = sizeof(struct sockaddr_in), rval;
- u_char errbyte = 0;
- S5NetAddr wtdaddr;
- S5IOHandle fd;
- fd_set fds, b;
- if (pri->nextVersion) {
- rval = S5SExchangeProtocol(&tcpinfo->iio, &tcpinfo->oio, pri, tcpinfo->idtentry, &pri->dstAddr, &pri->intAddr);
- } else {
- GetRoute(&pri->dstAddr, pri->dstName, "tcp", &pri->intAddr);
- rval = bind(tcpinfo->oio.fd, &pri->intAddr.sa, lsAddrSize(&pri->intAddr));
- }
- if (rval < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "TCP Binding to address %s:%d failed: %m", ADDRANDPORT(&pri->intAddr));
- return EXIT_ERR;
- }
- if (!pri->nextVersion && getsockname(tcpinfo->oio.fd, &pri->intAddr.sa, &len) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "TCP Getsockname failed: %m");
- return EXIT_ERR;
- }
- if (!pri->nextVersion && listen(tcpinfo->oio.fd, 1) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "TCP Listen failed: %m");
- return EXIT_ERR;
- }
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "TCP out interface %s:%d", ADDRANDPORT(&pri->intAddr));
- if (SendDest(pri, tcpinfo, &pri->intAddr, SOCKS5_RESULT, SOCKS_RESULT) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "TCP SendDest failed: %m");
- return EXIT_NETERR;
- }
- FD_ZERO(&b);
- FD_SET(tcpinfo->iio.fd, &b);
- FD_SET(tcpinfo->oio.fd, &b);
- lsAddrCopy(&wtdaddr, &pri->dstAddr, lsAddrSize(&pri->dstAddr));
- /* Do a select here, so we can have a timeout on how long we wait... */
- /* XXX We should also check to make sure the client doesn't become read */
- /* ready, that would mean it exitted. */
- for (fds = b; ; fds = b) {
- struct timeval to = { ACCEPT_TIMEOUT, 0 };
- switch (select(MAX(tcpinfo->iio.fd, tcpinfo->oio.fd)+1, &fds, NULL, NULL, &to)) {
- case -1:
- if (ISSOCKETERROR(EINTR)) continue;
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "TCP Accept Select failed: %m");
- return EXIT_ERR;
- case 0:
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "TCP Accept Timeout expired");
- *s5ep = SOCKS5_TTLEXP;
- return EXIT_ERR;
- }
- break;
- }
- if (FD_ISSET(tcpinfo->iio.fd, &fds) && S5IOCheck(tcpinfo->iio.fd) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "TCP Client closed connection");
- return EXIT_NETERR;
- }
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "TCP accepting connection");
- switch (pri->nextVersion) {
- case 0:
- /* Accept will not restart on a signal interrupt, so we might */
- /* have to restart it... */
- while ((fd = accept(tcpinfo->oio.fd, &pri->dstAddr.sa, &len)) == S5InvalidIOHandle) {
- if (ISSOCKETERROR(EINTR)) continue;
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "TCP Accept failed: %m");
- return EXIT_ERR;
- }
- CLOSESOCKET(tcpinfo->oio.fd);
- tcpinfo->oio.fd = fd;
- break;
- case SOCKS4_VERSION:
- case SOCKS5_VERSION:
- if (lsReadResponse(tcpinfo->oio.fd, &tcpinfo->oio, &pri->dstAddr, pri->nextVersion, &errbyte, &pri->nextReserved) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "TCP Recieved bad reply from proxy at %s:%d", ADDRANDPORT(&pri->sckAddr));
- lsAddrCopy(&pri->dstAddr, &wtdaddr, lsAddrSize(&wtdaddr));
- return EXIT_ERR;
- }
- break;
- default:
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "TCP Unknown next version number: %d", pri->nextVersion);
- return EXIT_ERR;
- }
- GetName(pri->dstName, &pri->dstAddr);
- GetServ(pri->dstServ, pri->dstAddr.sin.sin_port, "tcp");
- /* We need to check first that the accepted address (pri->dstAddr) */
- /* matches the requested address (wtdaddr). */
- if (lsAddrAddrComp(&pri->dstAddr, &wtdaddr) != 0) {
- /* People are not happy with this checking because it breaks */
- /* round robin DNS entries... */
- if (pri->dstAddr.sa.sa_family == AF_INET &&
- (pri->retName[0] != ' ' && inet_addr(pri->retName) == INVALIDADDR)) {
- struct hostent *hp;
- int i;
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "TCP Accepted: Checking round robin DNS entries");
- MUTEX_LOCK(gh_mutex);
- if (!(hp = gethostbyname(pri->retName))) {
- MUTEX_UNLOCK(gh_mutex);
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), MSGID_SERVER_TCP_ACCEPT_AUTH, "TCP Accepted authorization failed for host: %s:%d", pri->dstName, (int)ntohs(lsAddr2Port(&pri->dstAddr)));
- *s5ep = SOCKS5_AUTHORIZE;
- return EXIT_AUTH;
- }
- for (i = 0; hp->h_addr_list[i]; i++) {
- if (!memcmp((char *)&pri->dstAddr.sin.sin_addr, hp->h_addr_list[i], sizeof(struct in_addr))) break;
- }
- if (!hp->h_addr_list[i]) {
- MUTEX_UNLOCK(gh_mutex);
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), MSGID_SERVER_TCP_ACCEPT_AUTH, "TCP Accepted authorization failed for host: %s:%d", pri->dstName, (int)ntohs(lsAddr2Port(&pri->dstAddr)));
- *s5ep = SOCKS5_AUTHORIZE;
- return EXIT_AUTH;
- }
- MUTEX_UNLOCK(gh_mutex);
- } else {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), MSGID_SERVER_TCP_ACCEPT_AUTH, "TCP Accepted authorization failed for host: %s:%d", pri->dstName, (int)ntohs(lsAddr2Port(&pri->dstAddr)));
- *s5ep = SOCKS5_AUTHORIZE;
- return EXIT_AUTH;
- }
- }
- /* Note that the requested address can be type of S5NAME while the */
- /* accepted address can be type of INET. If this is the case and */
- /* we can't resolve the name, we have accept as is... */
- if (pri->dstAddr.sa.sa_family == AF_INET &&
- (pri->retAddr.sin.sin_addr.s_addr == INVALIDADDR && pri->retName[0] != ' ')) {
- lsAddrCopy(&wtdaddr, &pri->dstAddr, lsAddrSize(&pri->dstAddr));
- memset((char *)&pri->dstAddr, 0, sizeof(S5NetAddr));
- pri->dstAddr.sn.sn_family = AF_S5NAME;
- strcpy(pri->dstAddr.sn.sn_name, pri->retName);
- lsAddrSetPort(&pri->dstAddr, lsAddr2Port(&wtdaddr));
- }
- if (Authorize(pri, 0) != AUTH_OK) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), MSGID_SERVER_TCP_ACCEPT_AUTH, "TCP Accepted authorization failed for host: %s:%d", pri->dstName, (int)ntohs(lsAddr2Port(&pri->dstAddr)));
- *s5ep = SOCKS5_AUTHORIZE;
- return EXIT_AUTH;
- }
- if (SendDest(pri, tcpinfo, &pri->dstAddr, SOCKS5_RESULT, SOCKS_RESULT) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "TCP SendDest failed: %m");
- return EXIT_NETERR;
- }
- /* If this isn't through another socks server, we didn't have the right */
- /* info before, but we do now. If it is through another socks server, */
- /* it is our peer, and hasn't changed since the entry was added before. */
- if (!pri->nextVersion) {
- MakeIdentEntry(tcpinfo->iio.fd, tcpinfo->oio.fd, pri, tcpinfo->idtentry);
- }
- return EXIT_OK;
- }
- int TcpFlowRecvPkt(S5Packet *packet, S5LinkInfo *pri, TcpInfo *coption, int *dir) {
- int rv;
- if (!coption) return -1;
- rv = S5TcpFlowRecv(&coption->iio, &coption->oio, packet, dir);
- if (rv < 0) coption->exitval = EXIT_ERR;
- else coption->exitval = EXIT_OK;
- if (packet->data != NULL) coption->packetbuf = packet->data;
- return rv;
- }
- int TcpFlowSendPkt(S5Packet *packet, S5LinkInfo *pri, TcpInfo *coption, int *dir) {
- int rv;
- if (!coption) return -1;
- rv = S5TcpFlowSend(&coption->iio, &coption->oio, packet, dir);
- if (rv < 0) coption->exitval = EXIT_ERR;
- else coption->exitval = EXIT_OK;
- return rv;
- }
- int TcpCloseConnection(S5LinkInfo *linkinfo, TcpInfo *coption) {
- if (!coption) return -1;
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_INFO, 0, "TCP Connection Terminated: %s (%s:%d to %s:%s) for user %s: %d bytes out, %d bytes in",
- (coption->exitval == EXIT_ERR)?"Abnormal":"Normal",
- linkinfo->srcName, ntohs(lsAddr2Port(&linkinfo->srcAddr)),
- linkinfo->dstName, linkinfo->dstServ, linkinfo->srcUser,
- linkinfo->outbc, linkinfo->inbc);
- RemoveIdentEntry(coption->idtentry);
- S5BufCleanContext(&coption->oio);
- S5BufCleanContext(&coption->iio);
- if (coption->packetbuf) free(coption->packetbuf);
- free(coption);
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(15), 0, "TCP Close: Cleanup done");
- return 0;
- }
- int TcpSetup(S5IOInfo *ioinfo, S5LinkInfo *linkinfo, S5CommandInfo *cmdinfo) {
- int turnon = 1, rval = EXIT_ERR;
- u_char s5error = SOCKS5_FAIL, s4error = SOCKS_FAIL;
- TcpInfo *tcpinfo = NULL;
- if (ResolveNames(linkinfo) < 0) {
- s5error = SOCKS5_BADADDR;
- goto cleanup;
- }
- /* Allocate space for the tcp specific options we'll be using... */
- if (!(cmdinfo->option = (void *)(tcpinfo = (TcpInfo *)malloc(sizeof(TcpInfo))))) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "TCP Setup: Malloc() failed: %m");
- goto cleanup;
- }
- tcpinfo->packetbuf = NULL;
- tcpinfo->ndests = 0;
- tcpinfo->iio = *ioinfo;
- InitIdentEntry(tcpinfo->idtentry);
- S5BufSetupContext(&tcpinfo->oio);
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_INFO, MSGID_SERVER_TCP_START, "TCP Connection Request: %s (%s:%d to %s:%s) for user %s",
- (linkinfo->peerCommand == SOCKS_CONNECT)?"Connect":"Bind",
- linkinfo->srcName, ntohs(lsAddr2Port(&linkinfo->srcAddr)),
- linkinfo->dstName, linkinfo->dstServ, linkinfo->srcUser);
- /* Make sure we're allowed to do this before we start any work on it... */
- if (Authorize(linkinfo, (linkinfo->peerCommand == SOCKS_BIND)?1:0) != AUTH_OK) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, MSGID_SERVER_TCP_AUTH, "TCP Setup: Authorization failed");
- s5error = SOCKS5_AUTHORIZE;
- rval = EXIT_AUTH;
- goto cleanup;
- }
- /* Make the socket we'll use for the server side... */
- if ((tcpinfo->oio.fd = socket(AF_INET, SOCK_STREAM,0)) == S5InvalidIOHandle) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "TCP Setup: Socket() failed: %m");
- goto cleanup;
- }
- switch (linkinfo->peerCommand) {
- case SOCKS_BIND:
- if ((rval = TcpBind(linkinfo, tcpinfo, &s5error, &s4error)) != 0) goto cleanup;
- rval = EXIT_ERR;
- break;
- case SOCKS_CONNECT:
- if ((rval = TcpConnect(linkinfo, tcpinfo, &s5error, &s4error)) != 0) goto cleanup;
- rval = EXIT_ERR;
- break;
- default:
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "TCP Setup: Invalid command: %d", (int)linkinfo->peerCommand);
- s5error = SOCKS5_BADCMND;
- goto cleanup;
- }
- /* Set out of band data inline, since we won't be dealing with it.... */
- if (setsockopt(tcpinfo->iio.fd, SOL_SOCKET, SO_OOBINLINE, (char *)&turnon, sizeof(int)) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(15), 0, "TCP Setup: Failed to inline out-of-band data: %m");
- rval = EXIT_NETERR;
- goto cleanup;
- }
- if (setsockopt(tcpinfo->oio.fd, SOL_SOCKET, SO_OOBINLINE, (char *)&turnon, sizeof(int)) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(15), 0, "TCP Setup: Failed to inline out-of-band data: %m");
- goto cleanup;
- }
- #ifdef USE_LINGERING
- /* ATM: use SO_LINGER so it won't hang up on client */
- /* submitted by Andy McFadden fadden@uts.amdahl.com */
- /* snarfed from Socks V4 cstc version, not clear when its necessary. */
- if (setsockopt(tcpinfo->iio.fd, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(struct linger)) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(15), 0, "TCP Setup: Failed to turn off lingering: %m");
- rval = EXIT_NETERR;
- goto cleanup;
- }
- if (setsockopt(tcpinfo->oio.fd, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(struct linger)) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(15), 0, "TCP Setup: Failed to turn off lingering: %m");
- goto cleanup;
- }
- #endif
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_INFO, MSGID_SERVER_TCP_ESTAB, "TCP Connection Established: %s (%s:%d to %s:%s) for user %s",
- (linkinfo->peerCommand == SOCKS_CONNECT)?"Connect":"Bind",
- linkinfo->srcName, ntohs(lsAddr2Port(&linkinfo->srcAddr)),
- linkinfo->dstName, linkinfo->dstServ, linkinfo->srcUser);
- cmdinfo->recvpkt = (int (*)(S5Packet *, S5LinkInfo *, void *, int *))TcpFlowRecvPkt;
- cmdinfo->sendpkt = (int (*)(S5Packet *, S5LinkInfo *, void *, int *))TcpFlowSendPkt;
- cmdinfo->clean = (int (*)(S5LinkInfo *, void *))TcpCloseConnection;
- return EXIT_OK;
- cleanup:
- if (rval != EXIT_NETERR) lsSendResponse(ioinfo->fd, ioinfo, &linkinfo->dstAddr, linkinfo->peerVersion, (linkinfo->peerVersion == SOCKS5_VERSION)?s5error:s4error, 0, NULL);
- if (tcpinfo != NULL) {
- tcpinfo->exitval = EXIT_ERR;
- TcpCloseConnection(linkinfo, tcpinfo);
- } else {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_INFO, 0, "TCP Connection Terminated: %s (%s:%d to %s:%s) for user %s: %d bytes out, %d bytes in",
- "Abnormal", linkinfo->srcName, ntohs(lsAddr2Port(&linkinfo->srcAddr)),
- linkinfo->dstName, linkinfo->dstServ, linkinfo->srcUser,
- linkinfo->outbc, linkinfo->inbc);
- S5BufCleanContext(ioinfo);
- }
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(15), 0, "TCP Setup failed");
- /* Prevent any further problems from being seg faults. */
- cmdinfo->option = NULL;
- if (rval == EXIT_OK) rval = EXIT_ERR;
- return rval;
- }