flow.c
资源名称:socks5.zip [点击查看]
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:6k
源码类别:
代理服务器
开发平台:
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: flow.c,v 1.31.4.3 1998/03/04 16:13:39 jyou 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 "daemon.h"
- #include "proxy.h"
- #include "flow.h"
- #include "log.h"
- #include "msg.h"
- #ifndef INACTIVITY_TIMEOUT
- #define INACTIVITY_TIMEOUT 15*60 /* How much inactivity will I tolerate??? */
- #endif
- static int proxyinturn() {
- static int turn = 0;
- return turn = turn?0:1;
- }
- static int FlowSetup(S5Packet *buf) {
- char *olddata = buf->data;
- if (buf->data == NULL) {
- buf->data = malloc(GENERICBUFSIZE);
- if (buf->data) S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Flow Setup: Allocated Buffer");
- buf->len = GENERICBUFSIZE;
- buf->off = 0;
- }
- if (buf->len == buf->off) {
- buf->data = realloc(olddata = buf->data, buf->len += GENERICBUFSIZE);
- if (buf->data) S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Flow Setup: Grew Buffer");
- }
- if (buf->data == NULL) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Setup: Couldn't allocate buffer space");
- if (!olddata) free(olddata);
- return -1;
- }
- return 0;
- }
- int S5TcpFlowRecv(S5IOInfo *iio, S5IOInfo *oio, S5Packet *packet, int *dir) {
- S5IOHandle fdsbits = ((iio->fd > oio->fd)?iio->fd:oio->fd)+1;
- fd_set fds, xfds, bu;
- S5IOInfo *io;
- char *string;
- int n;
- int turn = 1;
- FD_ZERO(&bu);
- if (*dir & S5_DIRECTION_OUT) FD_SET(iio->fd, &bu);
- if (*dir & S5_DIRECTION_IN) FD_SET(oio->fd, &bu);
- if (FlowSetup(packet) < 0) {
- return -1;
- }
- for (fds = bu ; ; fds = bu) {
- struct timeval tout;
- tout.tv_sec = idletimeout*60;
- tout.tv_usec = 0;
- if (!FD_ISSET(iio->fd, &fds) && !FD_ISSET(oio->fd, &fds)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Recv: Neither file descriptor is set");
- return -1;
- }
- xfds = fds;
- switch (select(fdsbits, &fds, NULL, &xfds, &tout)) {
- case -1:
- if (ISSOCKETERROR(EINTR)) continue;
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Recv: Select failed: %m");
- return -1;
- case 0:
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Recv: Select failed: Inactivity timeout");
- return -1;
- }
- if (FD_ISSET(iio->fd, &xfds) && FD_ISSET(oio->fd, &xfds))
- turn = proxyinturn();
- else if (FD_ISSET(iio->fd, &xfds))
- turn = 1;
- else if (FD_ISSET(oio->fd, &xfds))
- turn = 0;
- else if (FD_ISSET(iio->fd, &fds) && FD_ISSET(oio->fd, &fds))
- turn = proxyinturn();
- else if (FD_ISSET(iio->fd, &fds))
- turn = 1;
- else if (FD_ISSET(oio->fd, &fds))
- turn = 0;
- else {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Recv: Invalid file descriptor set");
- return -1;
- }
- if (turn) {
- *dir = S5_DIRECTION_OUT;
- string = "client";
- io = iio;
- } else {
- *dir = S5_DIRECTION_IN;
- string = "server";
- io = oio;
- }
- packet->oob = 0;
- if (FD_ISSET(io->fd, &xfds))
- (void) ioctl(io->fd, SIOCATMARK, (char *)&packet->oob);
- #define RECV_IOFLAGS S5_IOFLAGS_TIMED|S5_IOFLAGS_RESTART
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Flow Recv: Reading from %s socket", string);
- switch ((n = S5BufReadPacket(io->fd, io, packet->data + packet->off, packet->oob?1:packet->len - packet->off, 0))) {
- case -1:
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Recv: %s Read failed: %m", string);
- return -1;
- case 0:
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Flow Recv: %s closed connection", string);
- return 0;
- default:
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Flow Recv: Read %d bytes from %s socket", n, string);
- packet->off += n;
- return n;
- }
- }
- }
- int S5TcpFlowSend(S5IOInfo *iio, S5IOInfo *oio, S5Packet *packet, int *dir) {
- double timerm = (double)idletimeout*60;
- S5IOInfo *io;
- char *string;
- int n;
- switch (*dir) {
- case S5_DIRECTION_OUT:
- string = "server";
- io = oio;
- break;
- case S5_DIRECTION_IN:
- string = "client";
- io = iio;
- break;
- default:
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Send: Invalid direction: %d", *dir);
- return -1;
- }
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Flow Send: Writing %d bytes to %s socket", packet->off, string);
- #define SEND_IOFLAGS S5_IOFLAGS_TIMED|S5_IOFLAGS_RESTART|S5_IOFLAGS_NBYTES
- switch ((n = S5IOSend(io->fd, io, packet->data, packet->off, packet->oob?MSG_OOB:0, SEND_IOFLAGS, &timerm))) {
- case -1:
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Send: %s Write failed: %m", string);
- return -1;
- case 0:
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Flow Send: %s closed connection", string);
- return 0;
- default:
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Flow Send: Wrote %d bytes to %s", n, string);
- packet->off -= n;
- return n;
- }
- }