📄 forward.cpp
字号:
// forward.cpp// program to forward data between two sockets// copyright SafeTP Development Group, Inc., 2000 Terms of use are as specified in license.txt#include <iostream.h> // cout#include <stdio.h> // printf#include <stdlib.h> // atoi#include <syslog.h> // syslog#include "sockutil.h" // socket funcs#include "datablok.h" // DataBlock#include "str.h" // stringb// reporting macro#define report(verbLevel, formatting) \ reportString(verbLevel, stringb(formatting)) /* user ; */// global user optionsint verbosity = 30; // we print/log things up to this level of verbosity // level severity // ----- -------- // 0 nothing is at this level; verbosity=0 means print/log nothing // 5 errors // 8 accept // 10 listen/accept/connect/close // 15 preparing to block on connect // 20 summary info for each chunk forwarded // 30 every forwarded byte is printed// global control variablesbool useSyslog = false; // when true, reports are sent to syslogbool logOpened = false; // set to true once we call 'openlog'char const *progName; // name under which we were invoked// verbLevel - threshold verbosity level; indicates severityvoid reportString(int verbLevel, char const *str){ if (verbosity < verbLevel) { // suppress this message return; } if (useSyslog) { if (!logOpened) { openlog(progName, LOG_PID, LOG_USER); } syslog(verbLevel <= 5? LOG_ERR : /* otherwise */ LOG_INFO, "%s\n", str); } else { if (verbLevel <= 5) { cout << "error: "; } cout << str << endl; }}void forwardTo(DataBlock buffer, SOCKET dest, SOCKET src, char const *prompt){ // get some data int len = recv(src, buffer.getData(), buffer.getAllocated(), 0); if (len < 0) { xsocket(src, "recv"); } buffer.setDataLen(len); // print what we got if (verbosity >= 30) { buffer.print(prompt); } else { report(20, prompt << ": forwarding " << buffer.getDataLen() << " bytes"); } // forward it sendAll(dest, (char const*)buffer.getDataC(), len);}void printUsage(){ cout << "usage: " << progName << " [options] listen-port connect-server connect-port\n" " listen-port: will listen for client to connect here;\n" " use port 0 if spawned by inetd (& print=syslog)\n" " connect-server: server to connect to (name or IP)\n" " connect-port: will connect to server at this port\n" " options:\n" " -vN verbosity level:\n" " 0 don't print anything, ever\n" " 5 print errors only\n" " 8 print connection-establishment (accept) only\n" " 10 print listen/accept/connect/close activity only\n" " 15 print when blocking on connect\n" " 20 print a summary for each chunk forwarded\n" " 30 (default) print every byte forwarded\n" ;}int doit(int argc, char *argv[]){ progName = argv[0]; // named arguments bool argumentError = false; int i; for (i=1; i<argc; i++) { if (argv[i][0] == '-') { char const *argptr = argv[i] + 2; // pointer to any text following the argument character switch (argv[i][1]) { case 'v': verbosity = atoi(argptr); if (verbosity < 5) { } break; default: report(5, "illegal argument: " << argv[i]); argumentError = true; } } else { // done with named arguments break; } } // positional arguments int listenPort; int connectPort; IPAddress serverAddr; if (argc - i < 3) { report(5, "too few arguments"); argumentError = true; } else { listenPort = atoi(argv[i]); if (listenPort == 0) { useSyslog = true; } serverAddr = resolveHostName(argv[i+1]); connectPort = atoi(argv[i+2]); } // check for argument errors, and bail if there were any if (argumentError) { printUsage(); return 2; } // wait for an incoming connection SOCKET client; if (listenPort != 0) { report(10, "listening for client to connect on port " << listenPort); SOCKET listener = listen_socket(listenPort); // accept it client = accept_socket(listener); close_socket(listener); } else { client = (SOCKET)0; // file descriptor 0 is stdin -- used with inetd } report(8, "accepted client: " << sockInfo(client)); // connect to server report(15, "connecting to server at port " << connectPort); SOCKET server = connect_socket(serverAddr, connectPort); report(10, "connected to server: " << sockInfo(server)); // create a forwarding buffer DataBlock buffer(1024); // enter forwarding loop SOCKET active; try { for(;;) { active = INVALID_SOCKET; SocketSet sockset; sockset.add(client); sockset.add(server); sockset.blockUntilReadable(); if (sockset.contains(client)) { active = client; checkClosed(client); forwardTo(buffer, server /*dest*/, client, "C->S"); } else if (sockset.contains(server)) { active = server; checkClosed(server); forwardTo(buffer, client /*dest*/, server, "S->C"); } else { report(5, "select() screwed up!\n"); } } } catch (xSocket &x) { if (active == client) { report(10, "client closed the connection; closing both"); } else if (active == server) { report(10, "server closed the connection; closing both"); } else { report(5, "unknown peer (?!?!) closed the connection; closing both"); } close_socket(client); close_socket(server); return 0; }}int main(int argc, char *argv[]){ xBase::logExceptions = false; // generally I'm handling them myself socket_lib_init(); try { return doit(argc, argv); } catch (xBase &x) { report(5, "unhandled exception: " << x.why()); return 4; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -