quic-go源码一---server启动

前言:

走马观花地看了RFC 9000:QUIC: A UDP-Based Multiplexed and Secure Transport,
感受不是那么直观,所以再来看看这个协议的golang语言实现:quic-go,加强学习。

https://quic-go.net/docs/quic/quic-go文档
在这里插入图片描述

本篇准备的代码片断如下:

const addr = "127.0.0.1:9000"func main() {quicConf := &quic.Config{InitialStreamReceiveWindow:     1 << 20,  // 1 MBMaxStreamReceiveWindow:         6 << 20,  // 6 MBInitialConnectionReceiveWindow: 2 << 20,  // 2 MBMaxConnectionReceiveWindow:     12 << 20, // 12 MB}// 学习点1listener, err := quic.ListenAddr(addr, generateTLSConfig(), quicConf)if err != nil {log.Fatalf("Error listening on address: %v", err)}defer listener.Close()for {// 学习点2conn, err := listener.Accept(context.Background())if err != nil {log.Printf("Error accepting connection: %v", err)continue}go handleConnection(conn)fmt.Println("New client connected")}
}func handleConnection(conn quic.Connection) {for {// 接收数据流stream, err := conn.AcceptStream(context.Background())// 。。。。。。}
}func generateTLSConfig() *tls.Config {key, err := rsa.GenerateKey(rand.Reader, 1024)if err != nil {panic(err)}template := x509.Certificate{SerialNumber: big.NewInt(1)}certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)if err != nil {panic(err)}keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})tlsCert, err := tls.X509KeyPair(certPEM, keyPEM)if err != nil {panic(err)}return &tls.Config{Certificates: []tls.Certificate{tlsCert},NextProtos:   []string{"TEST"},}
}

看点1

listener, err := quic.ListenAddr(addr, generateTLSConfig(), quicConf)

先记住参数

createdConn: true,
isSingleUse: true,

在这里插入图片描述
其中conn, err := listenUDP(addr)是net udp常规操作,略过不提。
所以核心是调用了Transport.Listener(tlsConf, quicConf)方法。但是注意其中的参数,呃,我们先看官网文档:
在这里插入图片描述
使用简写方式:我们demo正是如此:
在这里插入图片描述
看看官方的实现:正好印证了文档的准确性:
在这里插入图片描述

接着看 Transport.Listen(…)

在这里插入图片描述
在这里插入图片描述
上述allow0RTT为true/false的区别在于,所以当使用ListenEarly(。。。)allow0RTT为true)时,服务端会开辟一个map:
在这里插入图片描述

官网文档如下:To allow clients to use 0-RTT resumption, the Allow0RTT flag needs to be set on the quic.Config.(为了能够使用0-RTT, 需要在 quic.Config设置Allow0RTT标识
当然也得用ListenEarly() 而不是Listen()
在这里插入图片描述
allow0RTT在本篇只是带过,知道有个概念,后续有机会学习分析。。。

接着看 Transport.createServer(…)

在这里插入图片描述

validateConfig(…):

在这里插入图片描述

populateConfig(config *Config)

在这里插入图片描述

t.init(false)

在这里插入图片描述
wrapConn(..)核心如下:

setReceiveBuffer(pc net.PacketConn)
setSendBuffer(pc)supportsDF, err = setDF(rawConn)// 优化点在这里!
c, ok := pc.(OOBCapablePacketConn)
if !ok {return &basicConn{PacketConn: pc, supportsDF: supportsDF}, nil
}
return newConn(c, supportsDF)

其中前2项性质都一样:

_ = conn.SetReadBuffer(protocol.DesiredReceiveBufferSize) // 7 MBerr := fd.pfd.SetsockoptInt(syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes)
size, serr = unix.GetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_SNDBUF)

在这里插入图片描述
其中setDF(rawConn syscall.RawConn)实现主要逻辑如下:

errDFIPv4 = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_DONTFRAG, 1)
errDFIPv6 = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_DONTFRAG, 1)

在这里插入图片描述
再看看newConn(...)
在这里插入图片描述
只激活了读取ipv4的ECN:
在这里插入图片描述
在这里插入图片描述
最后返回的conn如下:
在这里插入图片描述
说完了wrapConn(...)后再回到init(...)
在这里插入图片描述
在这里插入图片描述

// is closed when listen returns
t.listening = make(chan struct{})

在这里插入图片描述
DefaultConnectionIDGenerator初始化:
在这里插入图片描述
getMultiplexer().AddConn(t.Conn)

func getMultiplexer() multiplexer {connMuxerOnce.Do(func() {connMuxer = &connMultiplexer{conns:  make(map[string]indexableConn),logger: utils.DefaultLogger.WithPrefix("muxer"),}})return connMuxer
}func (m *connMultiplexer) AddConn(c indexableConn) {m.mutex.Lock()defer m.mutex.Unlock()connIndex := m.index(c.LocalAddr())p, ok := m.conns[connIndex]if ok {// 后续会去掉panic(...)panic("connection already exists") // TODO: write a nice message}m.conns[connIndex] = p
}

还有最后2行代码:协程启动的:
在这里插入图片描述

go t.listen(conn)
go t.runSendQueue()

在这里插入图片描述
这里先不展开如何处理数据包的逻辑,先把整体流程熟悉起来。
在这里插入图片描述
init方法终于结束了!还差最后一个newServer(...):
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

go s.run()
go s.runSendQueue()

在这里插入图片描述
正是transport.handlePacket(p receivedPacket)调用server.handlePacket(p receivedPacket)

func (s *baseServer) handlePacket(p receivedPacket) {select {case s.receivedPackets <- p: // 【看这里看这里看这里看这里】default:s.logger.Debugf("Dropping packet from %s (%d bytes). Server receive queue full.", p.remoteAddr, p.Size())if s.tracer != nil && s.tracer.DroppedPacket != nil {s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention)}}
}

但是上面第299行的s.handlePacketImpl(p)很重要,后续篇再分析。
在这里插入图片描述

func (s *baseServer) sendRetry(p rejectedPacket) {if err := s.sendRetryPacket(p); err != nil {s.logger.Debugf("Error sending Retry packet: %s", err)}
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/56166.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于R语言机器学习方法在生态经济学领域中技术应用

近年来&#xff0c;人工智能领域已经取得突破性进展&#xff0c;对经济社会各个领域都产生了重大影响&#xff0c;结合了统计学、数据科学和计算机科学的机器学习是人工智能的主流方向之一&#xff0c;目前也在飞快的融入计量经济学研究。表面上机器学习通常使用大数据&#xf…

证件照小程序源码,前后端稳定运行

演示&#xff1a;证寸照制作 运行环境: Linux Nginx PHP >5.6 MySQL>5.6 安装步骤: 1.下载源码上传至你的服务器宝塔面板 2.直接添加站点选择源码目录&#xff0c;新建数据库 3.设置代码执行目录为/web 4.在浏览器中输入你的域名&#xff0c;会提示安装&#xff0c;填写…

SpringBoot02:第一个springboot程序

3、第一个springboot程序 3.1、准备工作 我们将学习如何快速的创建一个Spring Boot应用&#xff0c;并且实现一个简单的Http请求处理。通过这个例子对Spring Boot有一个初步的了解&#xff0c;并体验其结构简单、开发快速的特性。 我的环境准备&#xff1a; java version "…

智能优化算法-禁忌搜索算法(TS)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1.内容介绍 禁忌搜索优化算法 (Tabu Search, TS) 是一种基于局部搜索的元启发式优化算法&#xff0c;由Fred Glover于1986年提出。TS通过引入“禁忌表”来避免重复搜索已经访问过的解&#xff0c;从而跳出局部最优解&#…

十四、MySQL事务日志

文章目录 1. redo日志1.1 为什么需要REDO日志1.2 REDO日志的好处、特点1.2.1 好处1.2.2 特点1.3 redo的组成1.4 redo的整体流程1.5 redo log 的刷盘策略1.6 不同刷盘策略演示1.7 写入redo log buffer 过程1.7.1 补充概念:Mini-Transaction1.7.2 redo 日志写入log buffer1.7.3 …

[DB] NSM

Database Workloads&#xff08;数据库工作负载&#xff09; 数据库工作负载指的是数据库在执行不同类型任务时所需的资源和计算方式&#xff0c;主要包括以下几种类型&#xff1a; 1. On-Line Transaction Processing (OLTP) 中文&#xff1a;联机事务处理解释&#xff1a;…

如何使用DockerSpy检测你的Docker镜像是否安全

关于DockerSpy DockerSpy是一款针对Docker镜像的敏感信息检测与安全审计工具&#xff0c;该工具可以帮助广大研究人员在Docker Hub上检测和搜索自己镜像的安全问题&#xff0c;并识别潜在的泄漏内容&#xff0c;例如身份验证密钥等敏感信息。 功能介绍 1、安全审计&#xff1a…

基于yolov10的驾驶员抽烟打电话安全带检测系统python源码+pytorch模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv10的驾驶员抽烟、打电话、安全带检测系统是一种先进的驾驶行为监测系统。该系统利用YOLOv10算法的高效性和准确性&#xff0c;实现对驾驶员行为的实时检测与识别。 YOLOv10是一种最新的实时物体检测模型&#xff0c;其通过深度学习技术&#xff0c;如卷…

【网络原理】HTTP协议

目录 前言 一.什么是HTTP HTTP报文格式 HTTP的请求格式 1.首行 2.请求头&#xff08;header&#xff09; 3.空行 4.正文&#xff08;body&#xff09; HTTP的响应格式 1.首行 2.响应头 3.空行 4.正文&#xff08;body&#xff09; 首行中的方法 GET和POST的区别 …

使用Radzen Blazor组件库开发的基于ABP框架炫酷UI主题

一、项目简介 使用过ABP框架的童鞋应该知道它也自带了一款免费的Blazor UI主题&#xff0c;它的页面是长这样的&#xff1a; 个人感觉不太美观&#xff0c;于是网上搜了很多Blazor开源组件库&#xff0c;发现有一款样式非常不错的组件库&#xff0c;名叫&#xff1a;Radzen&am…

[渗透]前端源码Chrome浏览器修改并运行

文章目录 简述本项目所使用的代码[Fir](https://so.csdn.net/so/search?qFir&spm1001.2101.3001.7020) Cloud 完整项目 原始页面修改源码本地运行前端源码修改页面布局修改请求接口 本项目请求方式 简述 好久之前&#xff0c;就已经看到&#xff0c;_无论什么样的加密&am…

【p2p、分布式,区块链笔记 Blockchain】truffle004 测试网络项目部署

编写合约 一个简单的Solidity智能合约 Usermap 用于在以太坊区块链上管理用户的ID和名称&#xff1a; 数据存储: 使用了 mapping 和 array 两种方式存储用户信息。addUser: 添加用户&#xff08;id和对应的用户名name&#xff09;到区块链。getid: 根据用户 id 获取用户名。该函…

计算机组成原理一句话

文章目录 计算机系统概述存储系统 计算机系统概述 指令和数据以同等地位存储在存储器中&#xff0c;形式上没有差别&#xff0c;但计算机应能区分他们。通过指令周期的不同阶段。 完整的计算机系统包括&#xff0c;1&#xff09;软件系统&#xff1a;程序、文档和数据&#xff…

【牛客刷题】笔记2

目录 1、单词搜索 2、岛屿数量 2.1 DFS 2.2 BFS 3、腐烂的橘子 1、单词搜索 单词搜索_牛客题霸_牛客网 (nowcoder.com) 这道题我们就是先遍历数组board&#xff0c;若遇到了与word[0]相等的字符&#xff0c;则以这个字符为起点进行搜索&#xff0c;搜索可以是dfs&#x…

PHP露营地管理小程序系统源码

&#x1f3d5;️露营新风尚&#xff01;露营地管理小程序系统&#xff0c;打造完美露营体验✨ &#x1f4cd;营地预订&#xff0c;轻松搞定&#x1f4c5; 想要逃离城市的喧嚣&#xff0c;享受大自然的宁静&#xff1f;露营地管理小程序系统让你的露营计划轻松实现&#xff01…

判断网站需不需要改版的几个要点

判断一个网站是否需要改版&#xff0c;可以从多个维度进行分析。以下是一些关键要点&#xff1a; 用户体验&#xff1a; 访问速度&#xff1a;如果网站加载缓慢&#xff0c;用户可能会感到沮丧并离开。导航性&#xff1a;网站结构是否清晰&#xff0c;用户是否能够轻松找到所需…

WebGL编程指南 - 绘制和变换三角形

三角形在三维图形学中的重要地位&#xff0c;以及WebGL如何绘制三角形。使用多个三角形绘制其它类型的基本图形。利用简单的方程对三角形做基本的变换&#xff0c;如移动、旋转和缩放。利用矩阵简化变换。 绘制多个点与缓冲区对象 相关内容&#xff1a;缓冲区对象&#xff1a;创…

第J6周:ResNeXt-50实战解析(pytorch版)

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊]** 任务&#xff1a; ●阅读ResNeXt论文&#xff0c;了解作者的构建思路 ●对比我们之前介绍的ResNet50V2、DenseNet算法 ●使用ResNeX…

LabVIEW离心泵振动监控与诊断系统

利用LabVIEW结合数据采集与处理技术&#xff0c;构建了一套高效、低成本的振动监测与诊断系统&#xff0c;有效提升了测试精度与设备可靠性。 项目背景 在化工生产中&#xff0c;离心泵作为关键设备&#xff0c;其稳定运行对保障生产安全与效率至关重要。由于传统振动测试系统…

C++ —— set系列的使用

目录 1. 序列式容器和关联式容器 2. set和multiset参考⽂档 3. set类的介绍 4. set的构造和迭代器 4.1 set的增删查 4.1.1 插入 4.1.2 查找 4.1.3 删除 5. multiset和set的差异 1. 序列式容器和关联式容器 前⾯我们已经接触过STL中的部分容器如&#xff1a;str…