tcproxy 使用介绍
来源:互联网 发布:华林证券软件 编辑:程序博客网 时间:2024/06/07 15:04
最近看到一个基于c语言开发的tcp代理开源项目 地址:https://github.com/dccmx/tcproxy
因为在现有的项目引用到 做下简单的记录
这里面主要是应用到了epoll 处理监听网络客户端,代理端口转发到本地服务,可以实现过滤黑名单,很小巧的程序
</pre><pre name="code" class="cpp">int main(int argc, char **argv) { int i, listen_fd;
</pre><pre name="code" class="cpp">
struct sigaction sig_action; ParseArgs(argc, argv); if (run_daemonize) Daemonize(); sig_action.sa_handler = SignalHandler; sig_action.sa_flags = SA_RESTART; sigemptyset(&sig_action.sa_mask); sigaction(SIGINT, &sig_action, NULL); sigaction(SIGTERM, &sig_action, NULL); sigaction(SIGPIPE, &sig_action, NULL); if ((policy->listen.addr == NULL) || !strcmp(policy->listen.addr, "any")) { free(policy->listen.addr); policy->listen.addr = strdup("0.0.0.0"); } else if (!strcmp(policy->listen.addr, "localhost")) { free(policy->listen.addr); policy->listen.addr = strdup("127.0.0.1"); } listen_fd = anetTcpServer(error_, policy->listen.port, policy->listen.addr); el = aeCreateEventLoop(65536); if (listen_fd < 0 || aeCreateFileEvent(el, listen_fd, AE_READABLE, AcceptTcpHandler, NULL) == AE_ERR) { LogFatal("listen failed: %s", strerror(errno)); } LogInfo("listenning on %s:%d", (policy->listen.addr? policy->listen.addr : "any"), policy->listen.port); for (i = 0; i < policy->nhost; i++) { if (policy->hosts[i].addr == NULL) policy->hosts[i].addr = strdup("127.0.0.1"); LogInfo("proxy to %s:%d", policy->hosts[i].addr, policy->hosts[i].port); } aeMain(el); aeDeleteEventLoop(el); FreePolicy(policy); return 0;}ParseArgs 判断命令行参数
policy = ParsePolicy(argv[i]); 这个函数用了加密算法 把端口地址体会成代理地址端口映射
接下来整个程序围绕
policy这个结构体来操作 listen_fd = anetTcpServer(error_, policy->listen.port, policy->listen.addr); 创建一个socket连接bind 地址 listen 开始监听
el = aeCreateEventLoop(65536); 创建el 事件循环
接下来这步比较重要了
if (listen_fd < 0 || aeCreateFileEvent(el, listen_fd, AE_READABLE, AcceptTcpHandler, NULL) == AE_ERR) {
LogFatal("listen failed: %s", strerror(errno));
}
回调函数 AcceptTcpHandler 里面accept 接受客户端连接
aeCreateFileEvent(el, cfd, AE_READABLE, ReadIncome, c)
读写数据 在readincome里面 接受客户端信息
void ReadIncome(aeEventLoop *el, int fd, void *privdata, int mask) { LogDebug("read in come"); Client *c = (Client*)privdata; Client *r = c->remote; char *buf; int len, nread = 0; while (1) { buf = BufferListGetSpace(r->blist, &len); if (buf == NULL) break; nread = recv(fd, buf, len, 0); if (nread == -1) { if (errno == EAGAIN) { // no data nread = 0; } else { // connection error goto ERROR; } } else if (nread == 0) { // connection closed LogInfo("connection closed"); goto ERROR; } if (nread) { BufferListPush(r->blist, nread); SetWriteEvent(r); LogDebug("set write"); } else { break; } } return;ERROR: c->OnError(c);}循环接受客户端数据的同时 触发SetWriteEvent 写事件
前面说的是原理:
一、要增加黑名单 可以在ReadIncome 这个函数加限制判断 读取的buf 内容 判断是否是给它通过
二、在ParseArgs函数可以做一些改动 包括加密密码等内容
0 0
- tcproxy 使用介绍
- tiles使用介绍
- VSI使用介绍
- RPM使用介绍
- openCV使用介绍
- Log4j使用介绍
- Log4j使用介绍
- Log4j使用介绍
- Log4j使用介绍
- Log4j使用介绍
- Filter使用介绍
- dbunit介绍及使用
- winCVS使用介绍
- LCC使用介绍
- sp_executesql介绍和使用
- dotnetopenmail使用介绍
- AutoSave介绍与使用
- Samba介绍和使用
- iOS linker错误之Undefined symbols for architecture arm64
- 魔法顶层复原
- Android环境下使用net.sf.JSONObject问题出现BUG
- LinkedHashMap剖析
- centos7下快速安装mysql
- tcproxy 使用介绍
- ionic后退按钮 有时候出现 有时隐藏
- Introduction to C++ Programming in UE4——UE4官方文档翻译与理解(二)
- android 记住用户名关键代码
- Android 开发技巧 - Android 6.0 以上权限大坑和权限检查基类封装
- 安卓 OKHTTP 简单示例
- 疑问:
- Setting 的首页加载过程
- 用堆实现优先级队列--Java