Henry's Notebook
Many strange things
搜索
菜单
导航
首页
最近更改
随机页面
帮助
Henry's Home
个人资料
个人资料
创建账户
登录
消息
目前您没有通知。请访问您的
讨论页
以查看过去消息。
页面工具
内容页面
讨论
查看源代码
历史
首页
»
页面s
查看“Fwder”的源代码
←
Fwder
页面上次由
HenryHu
编辑于13年前
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:emailconfirmed
您可以查看与复制此页面的源代码。
[[Category:程序]] fwder的作用主要是通过一个HTTP proxy,转发HTTPS的连接。它主要是用在透明代理上的。 <source lang="c"> #include <sys/socket.h> #include <netdb.h> #include <sys/types.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <signal.h> char proxy_addr[] = "127.0.0.1"; char proxy_port[] = "8120"; int main() { sigignore(SIGCHLD); struct addrinfo *ai; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; int ret = getaddrinfo("::", "8443", &hints, &ai); if (ret) { fprintf(stderr, "failed to getaddrinfo: %s\n", gai_strerror(ret)); return 1; } int s = -1; while (ai) { s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (s < 0) { ai = ai->ai_next; continue; } int val = 1; setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); ret = bind(s, ai->ai_addr, ai->ai_addrlen); if (ret < 0) { close(s); s = -1; ai = ai->ai_next; continue; } break; } if (s < 0) { perror("failed to create and bind sock: "); return 1; } ret = listen(s, 10); if (ret < 0) { perror("failed to listen: "); return 1; } while (1) { struct sockaddr_storage cliaddr, myaddr; socklen_t cl = sizeof(cliaddr); socklen_t ml = sizeof(myaddr); int client = accept(s, (struct sockaddr *)&cliaddr, &cl); if (client < 0) { if (errno != ECONNABORTED) break; } char host[256]; char serv[256]; getnameinfo((struct sockaddr *)&cliaddr, cl, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV); char myhost[256], myserv[256]; getsockname(client, (struct sockaddr *)&myaddr, &ml); getnameinfo((struct sockaddr *)&myaddr, ml, myhost, sizeof(myhost), myserv, sizeof(myserv), NI_NUMERICHOST | NI_NUMERICSERV); pid_t pid = fork(); if (pid == 0) { // close(stdout); // close(stderr); struct addrinfo newhint, *res; memset(&newhint, 0, sizeof(newhint)); newhint.ai_family = AF_UNSPEC; newhint.ai_socktype = SOCK_STREAM; newhint.ai_flags = AI_NUMERICHOST; ret = getaddrinfo(proxy_addr, proxy_port, &hints, &res); if (ret) { // fprintf(stderr, "[%d] failed to getaddrinfo: %s\n", getpid(), gai_strerror(ret)); return 1; } if (strncmp(myhost, "::ffff:", 7) != 0) { return 1; } int xs = -1; while (res) { xs = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (xs < 0) { res = res->ai_next; continue; } int val = 1; setsockopt(xs, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); break; } if (s < 0) { // perror("failed to create sock: "); return 1; } ret = connect(xs, res->ai_addr, res->ai_addrlen); if (ret < 0) { // perror("failed to connect: "); return 1; } char *target = myhost + 7; char req[1500]; char reply[1500]; char *ptr = reply; if (strcmp(target, "78.16.49.15") == 0) { target = "199.59.148.87"; } snprintf(req, sizeof(req), "CONNECT %s:%s HTTP/1.1\r\n\r\n", target, myserv); int linelen = 0; write(xs, req, strlen(req)); int status = 0; while (1) { char c; ret = read(xs, &c, 1); if (ret <= 0) break; if (c == '\r') { read(xs, &c, 1); if (c != '\n') { } if (linelen == 0) { // reply end break; } else { if (strncmp(reply, "HTTP/", 5) == 0) { // reply line if (strstr(reply, " 200") != 0) { // OK status = 1; // printf("STATE OK\n"); } else { status = 0; // printf("STATE ERROR\n"); } } else { // other line // printf("OTHER LINE\n"); } } linelen = 0; // printf("NEW LINE\n"); } else { reply[linelen] = c; linelen++; // printf("%c", c); } } if (status > 0) { char buf[1500]; int max = xs; if (client > xs) max = client; max++; int closed = 0; while (1) { fd_set inout; FD_ZERO(&inout); FD_SET(xs, &inout); FD_SET(client, &inout); /*fprintf(stderr, "ok1 : %d\n", FD_ISSET(client, &inout));*/ /*fprintf(stderr, "ok2 : %d\n", FD_ISSET(xs, &inout));*/ /*printf("before select\n");*/ ret = select(max, &inout, NULL, NULL, NULL); /*printf("after select\n");*/ if (ret == -1) { break; } if (FD_ISSET(xs, &inout)) { /*printf("server data ready\n");*/ int len = read(xs, buf, sizeof(buf)); if (len <= 0) { closed++; shutdown(client, SHUT_WR); } else { /*printf("got server data: %d\n", len);*/ ret = write(client, buf, len); if (ret < len) break; } } if (FD_ISSET(client, &inout)) { /*printf("client data ready\n");*/ int len = read(client, buf, sizeof(buf)); if (len <= 0) { closed++; shutdown(xs, SHUT_WR); } else { /*printf("got data: %d bytes\n", len);*/ ret = write(xs, buf, len); if (ret < len) break; } } if (closed >= 2) break; } } /*printf("EXIT\n");*/ shutdown(xs, SHUT_RDWR); close(xs); shutdown(client, SHUT_RDWR); close(client); return 0; } else { /* printf("new child %d serving %s:%s, at %s:%s\n", pid, host, serv, myhost, myserv);*/ close(client); } } return 0; } </source>
返回至
Fwder
。