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.rhkb.cn/news/447023.html

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

相关文章

九寨沟,智慧旅游新名片

九寨沟属于自然类景区&#xff0c;以优美的自然风光取胜&#xff0c;景区文化内涵相对缺失。智慧化和文旅融合是智慧文旅景区的两个必备条件&#xff0c;九寨沟在智慧文旅景区建设过程中&#xff0c;经历了两个阶段&#xff0c;先是从传统景区迈向智慧景区&#xff0c;然后是充…

SpringBoot项目打成jar包,在其他项目中引用

1、首先新建一个SpringBoot工程 记得要将Gradle换成Maven 2、新建一个要引用的方法 3、打包的时候要注意&#xff1a; ① 不能使用springboot项目自带的打包插件进行打包&#xff0c;下面是自带的&#xff1a; ②要换成传统项目的maven打包&#xff0c;如下图&#xff1a; 依…

SQL 干货 | 使用 Having 子句筛选聚合字段

如果你编写 SQL 查询已有一段时间&#xff0c;那么你可能对 WHERE 子句非常熟悉。虽然它对聚合字段没有影响&#xff0c;但有一种方法可以根据聚合值过滤记录&#xff0c;那就是使用 HAVING 子句。本博客将介绍它的工作原理&#xff0c;并提供几个在 SELECT 查询中使用它的示例…

ssm基于java的网上手机销售系统

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码请私聊我 需要定制请私聊 目 录 目 录 III 1 绪论 1 1.1 研究背景 1 1.2 目的和意义 1 1.3 论文结构安排 2 2 相关技术 3 2.1 SSM框…

特定风格素材的网站推荐

在创作短视频或视觉内容时&#xff0c;找到符合主题和风格的素材至关重要。以下推荐的素材网站覆盖了丰富的创意资源库&#xff0c;从情感表达到时代背景、从悬疑到冒险等多种风格&#xff0c;帮助创作者轻松找到心仪的素材。无论你是抖音短视频创作者&#xff0c;还是从事广告…

git gui基本使用

一、图形化界面 二、创建新项目 创建文件&#xff0c;加入暂存区&#xff0c;提交到版本库 三、创建分支 四、合并分支 1.切换至master 五、更新分支 六、解决冲突 修改冲突&#xff0c;加入暂存区&#xff0c;提交到版本库 七、远程创建库 Gitee - 基于 Git 的代码托管和研…

自动化运维:提升效率、降低风险的利器

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

【读书笔记·VLSI电路设计方法解密】问题12:制造MOSFET晶体管的主要工艺步骤是什么

VLSI芯片是在半导体材料上制造的,这种材料的导电性介于绝缘体和导体之间。通过一种称为掺杂的工艺引入杂质,可以改变半导体的电气特性。能够在半导体材料的细小且定义明确的区域内控制导电性,促使了半导体器件的发展。结合更简单的无源元件(电阻、电容和电感),这些器件被…

Open WebUI | 自托管的类 ChatGPT 网站

Open WebUI 是一个扩展性强、功能丰富且用户友好的自托管 WebUI&#xff0c;支持 ChatGPT 网页端的大部分功能&#xff0c;支持各类模型服务&#xff0c;包括 Ollama 和 OpenAI 的 API。该项目在 GitHub 上已有 38k 星&#xff0c;非常受欢迎。 功能介绍 本篇介绍该项目的功能…

001 Qt_从零开始创建项目

文章目录 前言什么是QtQt的优点Qt的应用场景创建项目小结 前言 本文是Qt专栏的第一篇文章&#xff0c;该文将会向你介绍如何创建一个Qt项目 什么是Qt Qt 是⼀个 跨平台的 C 图形⽤⼾界⾯应⽤程序框架 。它为应⽤程序开发者提供了建⽴艺术级图形界⾯所需的所有功能。它是完全…

【华为】基于华为交换机的VLAN配置与不同VLAN间通信实现

划分VLAN&#xff08;虚拟局域网&#xff09;主要作用&#xff1a; 一、提高网络安全性 广播域隔离访问控制增强 二、优化网络性能 减少网络拥塞提高网络可管理性 sysytem-view #进入系统视图配置参数 vlan batch 10 20 #批量创建vlanLSW3: int g0/0/1 port …

Linux 进程概念

一.进程的基本概念 课本概念: 进程是程序的一个执行实例, 指的是正在执行的程序。内核视角: 进程是担当分配系统资源的实体。 1.1 什么是进程PCB? 进程PCB(Process control block)是一个存储进程属性的集合。 1.1.1 Linux系统中的进程PCB 进程PCB在Linux操作系统中为task_…

【STM32CubeMX开发】-2.1-TIM_生成一个定时器中断

目录 1 Tim定时器的时钟源 2 Tim定时器的配置 2.1 中断配置 3 生成代码 4 测试结果 结尾 1 Tim定时器的时钟源 TIM1的时钟来源自APB1 Timer clocks&#xff0c;时钟树上所有总线频率均设置为了STM32F0能达到的最高频率&#xff0c;此时APB1 Timer clocks 48MHz。 2 Tim…

SparkSQL介绍及使用

文章目录 1. SparkSQL介绍及使用1.1 SparkSQL介绍1.2 数据结构的形式1.3 Spark SQL 特点1.4 Spark SQL 和 Hive SQL关系 1. SparkSQL介绍及使用 1.1 SparkSQL介绍 Spark SQL是Apache Spark 用于处理结构化数据&#xff08;DataFrame和Datasets&#xff09;的模块。 在Spark1.0…

【C++】map和set使用

前言 有了前面搜索二叉树的基础&#xff0c;那么这篇博客对于map和set两个容器就很好理解使用&#xff0c;让我们来看看map和set到底有什么特性吧 &#x1f493; 个人主页&#xff1a;小张同学zkf ⏩ 文章专栏&#xff1a;C 若有问题 评论区见&#x1f4dd; &#x1f389;欢迎…

图文深入理解java对象从创建到回收都经历了什么

1. 前言&#xff1a; 每个java对象都是有生命周期的&#xff0c;就像一个人的生命一样&#xff0c;从孕育到出生到成长变老最后由归于自然。笔者认为&#xff0c;Java对象的整个生命周期可以分为两个大的阶段&#xff1a;即创建阶段和运行阶段&#xff08;包含对象的回收和消亡…

LSTM时序预测 | Python实现LSTM长短期记忆神经网络时间序列预测

本文内容&#xff1a;Python实现LSTM长短期记忆神经网络时间序列预测&#xff0c;使用的数据集为AirPassengers 目录 数据集简介 1.步骤一 2.步骤二 3.步骤三 4.步骤四 数据集简介 AirPassengers 数据集的来源可以追溯到经典的统计和时间序列分析文献。原始数据集由 Box,…

一个好的维权小程序应该是什么样的?

小程序如今为大家提供了很多的便利服务&#xff0c;且小程序的种类、功能是很多样的&#xff0c;那么对于一个好的维权小程序来说&#xff0c;其功能和设计应该紧紧围绕着用户的需求。 设计页面应该直观简单&#xff0c;功能布局让人一目了然&#xff1b;操作简单&#xff0c;…

外包干了30天,技术明显退步:一段自我觉醒与转变的旅程

在人生的长河中&#xff0c;每个人都会遇到属于自己的转折点。我也不例外。作为一个本科生&#xff0c;我于2019年通过校招踏入了南京某软件公司的大门&#xff0c;成为了一名功能测试工程师。在那个相对安逸的环境中&#xff0c;我度过了将近两年的时光。然而&#xff0c;随着…

当下的时代?

我这两天刚接触一个人,错误之皇,每做一件小事的时候他都像救命稻草一样抓着,有一天我一看,嚯,好家伙,他抱着的是已经让我仰望的参天大树了! 这个时代需要我们从无限思维的视角和做法去努力&#xff1b;它不取决于我们现在有多少&#xff0c;而取决于我们未来的成长幅度是多少&a…