文档章节

golang tcp 转发

明月惊鹊
 明月惊鹊
发布于 2016/10/01 17:15
字数 302
阅读 84
收藏 2
点赞 0
评论 0
package main

import (
    "os"
    "io"
    "fmt"
    "net"
    "strings"
    "strconv"
    "syscall"
    "encoding/binary"
)

type CSPair struct {
    clientaddr net.Addr
    serveraddr net.Addr
    clientconn *net.TCPConn
    serverconn *net.TCPConn
}

const (
    SO_ORIGINAL_DST = 80
)

var (
    connection_count = 0
)

func main() {
    laddr := &net.TCPAddr{}
    laddr.Port = 8838
    ln, err := net.ListenTCP("tcp4", laddr)
    handle_error(err)
    fmt.Printf("listen on %d\n", laddr.Port)
    defer ln.Close()

    for {
        conn, err := ln.AcceptTCP()
        handle_error(err)
        pair := construct_connection(conn)
        handle_data(pair)
    }
}

func handle_data(pair *CSPair) {
    go handle_cs(pair)
    go handle_sc(pair)
}

func handle_cs(pair *CSPair) {
    defer pair.clientconn.Close()
    if strings.Index(pair.serveraddr.String(), ":843") != -1 {
        fmt.Println(":843 connection.")
        io.Copy(pair.serverconn, pair.clientconn)
        return
    }

    var remain_data []byte
    for {
        bs, err := readPacket(pair.clientconn)
        handle_error(err)
        remain_data = append(remain_data, bs...)
        packet_len := int(binary.LittleEndian.Uint32(remain_data))
        packet_len += 4 //fixed len.
        fmt.Printf("remain_data: 0x%x, packet_len: 0x%x\n", len(remain_data), packet_len)
        if packet_len > len(remain_data) {
            continue
        }
        packet_data := remain_data[:packet_len]
        remain_data = remain_data[packet_len:]
        //packet_data = append(packet_data, 0)
        fmt.Printf("receive 0x%x:%s\n", packet_len, string(packet_data))
        n, err := pair.serverconn.Write(packet_data)
        handle_error(err)
        fmt.Printf("handle_cs write 0x%x bytes\n", n)
    }
}

func handle_sc(pair *CSPair) {
    defer pair.serverconn.Close()
    io.Copy(pair.clientconn, pair.serverconn)
    fmt.Println("handle_sc close pair.serverconn")
    /*
    bs, err := readPacket(pair.serverconn)
    handle_error(err)
    fmt.Printf("handle_sc:%s\n", string(bs))
    pair.clientconn.Write(bs)
    */
}

func construct_connection(c *net.TCPConn) *CSPair {
    var pair = &CSPair{}
    pair.clientconn = c
    pair.clientaddr = (*c).RemoteAddr()
    f, err := c.File()
    handle_error(err)

    addr, err :=  syscall.GetsockoptIPv6Mreq(int(f.Fd()), syscall.IPPROTO_IP, SO_ORIGINAL_DST)
    handle_error(err)

    ipv4 := strconv.Itoa(int(addr.Multiaddr[4])) + "." +
            strconv.Itoa(int(addr.Multiaddr[5])) + "." +
            strconv.Itoa(int(addr.Multiaddr[6])) + "." +
            strconv.Itoa(int(addr.Multiaddr[7]))

    port := uint16(addr.Multiaddr[2]) << 8 + uint16(addr.Multiaddr[3])
    origin_ipv4 := ipv4
    origin_port := port

    sa, err := net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", ipv4, port))
    handle_error(err)
    pair.serveraddr = sa
    pair.serverconn, err = net.DialTCP("tcp4", nil, sa)
    handle_error(err)

    connection_count++
    fmt.Printf("accept %d, %s and create a new connection to server %s(%s:%d)\n",
        connection_count, pair.clientaddr.String(), pair.serveraddr.String(), origin_ipv4, origin_port)
    return pair
}

func handle_error(err error) {
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
}

 

© 著作权归作者所有

共有 人打赏支持
明月惊鹊
粉丝 25
博文 60
码字总数 12982
作品 0
广州
高级程序员
Proxy-Go v4.0 发布,内网穿透使用多路复用重构

Proxy-Go v4.0 发布了。Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5代理服务器,支持正向代理、内网穿透、TCP/UDP端口转发、SSH中转。 更新内容: 内网穿透三端重构了一个...

狂奔的蜗牛.
2017/12/04
1K
25
Proxy-Go v5.0 发布:DNS 污染?不存在的!

Proxy-Go v5.0发布了。Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5代理服务器,支持正向代理、反向代理、透明代理、内网穿透、TCP/UDP端口映射、SSH中转、TLS加密传输、协...

狂奔的蜗牛.
06/19
0
0
高性能代理服务器 - Proxy-Go

Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5代理服务器,支持正向代理、反向代理、透明代理、内网穿透、TCP/UDP端口映射、SSH中转,TLS加密传输,协议转换。 Features 链式...

狂奔的蜗牛.
2017/09/13
0
8
Proxy-Go v4.9 发布:优化了内网穿透,更稳定!

Proxy-Go v4.9发布了。Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5代理服务器,支持正向代理、反向代理、透明代理、内网穿透、TCP/UDP端口映射、SSH中转,TLS加密传输,协...

狂奔的蜗牛.
06/06
0
0
Proxy-Go v5.2 发布,重构 SOCKS5/SPS 的 UDP 功能

Proxy-Go v5.2发布了。Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5代理服务器,支持正向代理、反向代理、透明代理、内网穿透、TCP/UDP端口映射、SSH中转、TLS加密传输、协...

狂奔的蜗牛.
07/09
0
0
Proxy-Go v5.1 发布,可以全平台生成证书

Proxy-Go v5.1发布了。Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5代理服务器,支持正向代理、反向代理、透明代理、内网穿透、TCP/UDP端口映射、SSH中转、TLS加密传输、协...

狂奔的蜗牛.
06/28
0
0
Proxy-Go v4.8 发布:内存等多项优化,看 4K 无鸭梨!

Proxy-Go v4.8发布了。Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5代理服务器,支持正向代理、反向代理、透明代理、内网穿透、TCP/UDP端口映射、SSH中转,TLS加密传输,协...

狂奔的蜗牛.
05/22
0
0
Ngrok内网穿透服务搭建

> 第一次发个博客好激动啊,总之(@¥%#¥%¥#@……#¥……%@#%¥&%……&¥%……!#¥#%%¥@……%¥&%……*@#%@!#¥@!¥#!¥#!……此处省略99999字)对你们深深的思念。好了,废话不多说...

chen松灿
2017/12/25
0
0
go 的 ssh 开发包--gosshtool

gosshtool provide some useful functions for ssh client in golang.implemented using golang.org/x/crypto/ssh. go语言中提供ssh相关操作,支持ssh本地端口转发服务。...

卧雪Sirk
2016/03/09
392
0
go语言import时为什么都从github导入?网络不稳就用不了?

我对go语言了解很少,近两天安装go-cve-dictionary时遇到了问题 正常使用的命令 go get github.com/kotakanbe/go-cve-dictionary package golang.org/x/net/context: unrecognized import pa......

LionelShen
2016/08/12
2.9K
10

没有更多内容

加载失败,请刷新页面

加载更多

下一页

【JVM】JSTATD结合Java VisualVM进行远程监控JVM运行情况(二)

内存泄露指的是程序中动态分配内存给一些临时对象,但是对象不会被GC(java垃圾回收机制gabage collection)所回收,它始终占用内存。即被分配的对象很大但已无用; 内存溢出指的是程序运行过...

大白来袭
8分钟前
0
0
聊聊ribbon的超时时间设置

序 本文主要研究一下ribbon的超时时间设置 配置 实例 ribbon: ReadTimeout: 10000 ConnectTimeout: 10000 MaxAutoRetries: 0 MaxAutoRetriesNextServer: 1 eureka: enabled: ......

go4it
16分钟前
0
0
一行代码结果叹为观止,能做到这么极致的也只有python了

Python 这门语言非常的有趣,不仅可以做高大上的人工智能、大数据、机器学习。还可以用来做 Web、爬虫。还有其它很多的应用。今天我就给大家展示下一行 Python 代码都可以做些什么。 一行打印...

猫咪编程
20分钟前
1
0
KingShard使用

对于kingshard的功能,在git中可以看到明确的功能说明 主要功能: 1. 基础功能 支持SQL读写分离。 支持透明的MySQL连接池,不必每次新建连接。 支持平滑上线DB或下线DB,前端应用无感知。 支...

mickelfeng
22分钟前
0
0
Linux 下 查找某个字符串

如果你想在当前项目下 查找 "test" 这个字符串,可以这样: grep -rn "test" * * : 表示当前目录所有文件,也可以是某个文件名-r 是递归查找-n 是显示行号-R ...

nsns
22分钟前
0
0
数据结构 之 B树与红黑树

https://blog.csdn.net/v_july_v/article/details/6530142 http://www.cnblogs.com/CarpenterLee/p/5503882.html...

晨猫
22分钟前
0
0
Linux查看服务器总内存和总硬盘大小

一、linux CPU大小; 其实应该通过Physical Processor ID来区分单核和双核。而Physical Processor ID可以从cpuinfo或者dmesg中找到. flags 如果有 ht 说明支持超线程技术 判断物理CPU的个数可...

浮躁的码农
22分钟前
0
0
Postfix命令行说明

Postfix tips and Troubleshooting Commands Here's a list of stuff I user everyday and other email admins will also be using, Let me know if I missed anything List/Print current m......

mingle
28分钟前
0
0
是时候使用Helm了:Helm, Kubernetes的包管理工具

目前我们的一个产品共有4套环境:dev环境、test环境、staging环境、production环境。 其中dev, test, staging环境在一个Kubernetes集群上以不同namespace部署,production环境部署在另一个Kub...

xiaomin0322
36分钟前
0
0
常见的redis的序列化方式

概括 一般redis的序列化方式主要有:字符串序列化、json序列化、xml序列化、jdk序列化,具体可查阅org.springframework.data.redis.serializer.RedisSerializer 的实现类,其中对于json序列化...

菜蚜
50分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部