chisel 分析4 面向对象
其核心初始化 clientconn server conn如下(serverconn和clientconn逻辑差不多)
// NewClientConn establishes an authenticated SSH connection using c
// as the underlying transport. The Request and NewChannel channels
// must be serviced or the connection will hang.
func NewClientConn(c net.Conn, addr string, config *ClientConfig) (Conn, <-chan NewChannel, <-chan *Request, error) {
fullConf := *config
fullConf.SetDefaults()
if fullConf.HostKeyCallback == nil {
c.Close()
return nil, nil, nil, errors.New("ssh: must specify HostKeyCallback")
}
conn := &connection{
sshConn: sshConn{conn: c, user: fullConf.User},
}
if err := conn.clientHandshake(addr, &fullConf); err != nil {
c.Close()
return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %v", err)
}
conn.mux = newMux(conn.transport)
return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil
}
// clientHandshake performs the client side key exchange. See RFC 4253 Section
// 7.
func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) error {
if config.ClientVersion != "" {
c.clientVersion = []byte(config.ClientVersion)
} else {
c.clientVersion = []byte(packageVersion)
}
fmt.Printf("client version:%s\n", c.clientVersion)
var err error
c.serverVersion, err = exchangeVersions(c.sshConn.conn, c.clientVersion)
if err != nil {
return err
}
fmt.Printf("serverVersion :%s dialAddress:%s remote:%+v\n", c.serverVersion, dialAddress, c.sshConn.RemoteAddr())
tr := newTransport(c.sshConn.conn, config.Rand, true /* is client */)
c.transport = newClientTransport( tr, c.clientVersion, c.serverVersion, config, dialAddress, c.sshConn.RemoteAddr())
if err := c.transport.waitSession(); err != nil {
return err
}
c.sessionID = c.transport.getSessionID()
return c.clientAuthenticate(config)
}
其主要是依赖connection将mux、 sshconn、handshakeTransport相互组织在一起
// A connection represents an incoming connection.
type connection struct {
transport *handshakeTransport
sshConn
// The connection protocol.
*mux
}
如何组织:
1、初始化conn,然后将net.Con赋值给conn的sshCon
2、conn.clientHandshake 的时候将 net.Conn 封装成newTransport,让后将Transport封装成 newClientTransport,然后执行ssh handshake逻辑。
3、使用newmux 将conn.transport 封装成mux 并填充conn的mux
3.1 初始化mux的时候,会生成channel list,每次创建channel会挂在此channel list上
这其中开启mux的loop协程读取transport的报文,然后解析送到各个channel。然后调用channel的读写函数,channel读取数据解析根据type进一步处理。
如果是要转发的数据,channel也有自己的buf pending 缓存。channel会将数据write 到pending里面,然后channel 在读取数据时,直接从pending里面读取
时间上handshakeTransport里面也有一层 chan buf 缓存,每个handshakeTransport 也会有自己的readloop协程读取Tr流里面的内容,然后将数据放入incoming chan;
每次mux调用handshakeTransport的readpacket的时候实际上就是从incoming的chan里面读取数据。
对于handshakeTransport以及Transport开启的协程读取数据则涉及到ssh加解密过程。涉及到cipher等逻辑。不看了
http代理服务器(3-4-7层代理)-网络事件库公共组件、内核kernel驱动 摄像头驱动 tcpip网络协议栈、netfilter、bridge 好像看过!!!!
但行好事 莫问前程
--身高体重180的胖子
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
2022-01-08 文件系统使用的数据结构
2021-01-08 国产化硬件设备性能追踪
2020-01-08 Socket 连接错误及原因