一、扩展报头粘性选项介绍

根据RFC 3542中的说明,存在两种机制可以用于发送携带HBH扩展报头的IPv6数据包,分别为:

  1. 使用ancillary data,可以为单个数据包指定扩展报头的选项内容;
  2. 使用setsockopt函数,可以为一个socket指定扩展报头的选项内容。设置完毕后,可以使该socket发出的所有数据包都携带指定的选项内容,所以也被称为粘性选项("sticky" options)。再次调用setsockopt函数后,可以对扩展报头的选项内容进行更新。

二、设置函数

设置HBH扩展报头的粘性选项需要依次使用4种函数,分别为inet6_opt_init(),inet6_opt_append(),inet6_opt_set_val(),inet6_opt_finish(),且其中3种需要被调用2次。

2.1变量定义

#define OPT_X 0x3c // 定义TLV选项类型,此处自定义为0x3c

void* extbuf; // extension buffer,扩展报头缓存指针

socklen_t extlen; // extension length,扩展报头长度

int currentlen; // 当前长度

void* databuf; // data buffer,扩展报头数据部分缓存指针

int offset; // 偏移

uint32_t value4; // 4字节数据变量

uint64_t value8; // 8字节数据变量

int datalen; // TLV选项数据长度

2.2 第一次调用设置函数

第一次调用函数,用于获得扩展报头长度,为扩展报头分配内存空间,以便第二次调用时存放数据。

2.2.1 inet6_opt_init ()

int inet6_opt_init(void *extension_buffer,

socklen_t extension_length)

该函数返回扩展报头所需的字节数。

currentlen = inet6_opt_init(NULL, 0);

第一次调用该函数,用于开始计算扩展报头大小。

2.2.2 inet6_opt_append()

int inet6_opt_append(void *extension_buffer,

socklen_t extension_length,

int offset,

uint8_t option_type,

socklen_t option_length,

uint32_t alignment,

void **data_bufferp)

该函数返回添加了新TLV选项和对齐后的扩展报头新长度。

currentlen = inet6_opt_append(NULL, 0, currentlen, OPT_X, datalen, 8, NULL);

第一次调用该函数,根据准备设置的TLV选项的类型、数据长度等信息,更新扩展报头长度。OPT_X表示需要设置的TLV选项类型,datalen表示设置该选项的数据部分长度为12字节,8表示该TLV选项是8字节对齐。

2.2.3 inet6_opt_finish()

int inet6_opt_finish(void *extension_buffer,
                 socklen_t extension_length,
                 int offset)

该函数返回IPv6扩展报头增加填充字节后的长度,使扩展报头满足字节对齐要求。

currentlen = inet6_opt_finish(NULL, 0, currentlen);

第一次调用该函数,计算增加了填充选项(Pad1、PadN)后的长度,使扩展报头长度满足字节对齐要求。

2.3第二次调用设置函数

首先,应根据第一次调用3种函数后计算得到的扩展报头长度对变量进行更新:

extlen = currentlen; // 更新扩展报头长度

extbuf = malloc(extlen); // 为扩展报头分配内存空间

2.3.1 inet6_opt_init()

currentlen = inet6_opt_init(extbuf, extlen);

第二次调用该函数,基于extlen初始化extbuf。

此时extbuf指向的扩展报头内存空间中,前2字节为HBH头部,第一字节表示下一头部类型,函数暂不设置;第二字节表示扩展报头长度,函数通过extlen设置。

2.3.2 inet6_opt_append()

currentlen = inet6_opt_append(extbuf, extlen, currentlen, OPT_X, datalen, 8, &databuf);

第二次调用该函数,为扩展报头添加TLV选项,并使databuf指向扩展报头内存空间中的数据部分的起始字节处。

此时extbuf指向的扩展报头内存空间中,第三字节被函数填充为TLV选项类型OPT_X,第四字节为TLV选项数据长度,函数通过datalen设置,故databuf实际指向第5字节处。(注意,此处简化分析,实际情况可能并非从第三字节开始填充TLV选项,因为系统会先根据扩展报头长度和对齐要求填充Pad1或PanN选项)。

重复使用该函数,可以为同一个扩展报头添加多个TLV选项。

2.3.3 inet6_opt_set_val()

offset = 0;

value4 = 0x12345678; // 为4字节变量赋值

offset = inet6_opt_set_val(databuf, offset,&value4, sizeof(value4));

value8 = 0x0102030405060708; // 为8字节变量赋值

offset = inet6_opt_set_val(databuf, offset,&value8, sizeof(value8));

两次调用该函数,分别将value4和value8的数据填入databuf指向的扩展报头内存空间的数据部分。

2.3.4 inet6_opt_finish()

currentlen = inet6_opt_finish(extbuf, extlen, currentlen);

第二次调用该函数,系统根据扩展报头长度和对齐要求在扩展报头内存空间中填充Pad1或PanN选项,使满足对齐要求。

2.4 setsockopt()

int setsockopt(int socket_descriptor,

int level,

int option_name,

char *option_value,

int option_length)

该函数用于设置socket。

setsockopt(m_sock, IPPROTO_IPV6,IPV6_HOPOPTS,extbuf, currentlen);

在上述函数调用完毕后,为socket设置HBH扩展头,设置level为IPPROTO_IPV6;option_name为IPV6_HOPOPTS;extbuf指向扩展报头内存空间,使socket能访问HBH扩展头数据。

三、扩展报头内容修改

在依次调用inet6_opt_init(),inet6_opt_append(),inet6_opt_set_val(),inet6_opt_finish()和setsockopt函数后,socket发出的数据包都将带有设置好的HBH扩展报头。

如果需要修改扩展报头内容,而不改变数据长度,再次调用inet6_opt_set_val()和setsockopt即可;如果需要修改数据长度,则需要全部重新设置。在重新设置完成后,socket发出的数据包的HBH扩展报头都会被更新。

参考文献:

IBM Documentation

RFC 3542 - Advanced Sockets Application Program Interface (API) for IPv6

IPv6 tcp socket HBH扩展报头设置相关推荐

  1. 《IPv6技术精要》一2.4 扩展报头

    本节书摘来自异步社区<IPv6技术精要>一书中的第2章,第2.4节,作者[美]Rick Graziani,更多章节内容可以访问云栖社区"异步社区"公众号查看 2.4 扩 ...

  2. C# 的tcp Socket设置自定义超时时间

    简单的c# TCP通讯(TcpListener) C# 的TCP Socket (同步方式) C# 的TCP Socket (异步方式) C# 的tcp Socket设置自定义超时时间 C# TCP ...

  3. linux网络编程IPv6socket,简单的IPv6 UDP/TCP socket编程 -- 两台Linux实现简单的ipv6通信...

    配置: 1.两台linux用网线直接相连 2.手动配置两台linux的ipv6地址为: ifconfig eth0 add 2001:da8:e000::1:1:1 ifconfig eth0 add ...

  4. IPv6之初使用,及IPv4与IPv6的socket通信

    1.IPv6概念 IPv6是InternetProtocol Version 6的缩写.IPv6是IETF(互联网工程任务组,InternetEngineering Task Force)设计的用于替 ...

  5. python 实现TCP socket通信和 HTTP服务器、服务器和客户端通信python实例

    python 实现TCP socket通信和 HTTP服务器.服务器和客户端通信实例 socket是什么? 服务器和客户端通信的流程 python 实现TCP socket通信例子 关于Host和PO ...

  6. pdu报头内容_发送具有分段和打包扩展报头的macpdu的装置及其方法

    专利名称:发送具有分段和打包扩展报头的mac pdu的装置及其方法 技术领域: 本发明涉及一种移动通信系统,并且更具体的,涉及ー种用于传送具有分段&打包扩展报头的MAC PDU (媒体访问控制 ...

  7. 转Go语言TCP Socket编程

    授权转载: Tony Bai 原文连接: https://tonybai.com/2015/11/17/tcp-programming-in-golang/ Golang的主要 设计目标之一就是面向大 ...

  8. golang TCP Socket编程

    Golang的主要 设计目标之一就是面向大规模后端服务程序,网络通信这块是服务端 程序必不可少也是至关重要的一部分.在日常应用中,我们也可以看到Go中的net以及其subdirectories下的包均 ...

  9. 【Java 网络编程】TCP 数据传输示例 ( 客户端参数设置 | 服务器端参数设置 | ByteBuffer 存放读取数据类型 )

    文章目录 I 客户端代码示例 II 服务器端代码示例 III 运行结果 I 客户端代码示例 import java.io.IOException; import java.io.InputStream ...

最新文章

  1. R语言ggplot2可视化:jupyter中设置全局图像大小、jupyter中自定义单个ggplot2图像结果的大小
  2. 索引中丢失 IN 或 OUT 参数:: 103,解决办法
  3. GPU端吊打RegNet、EfficientNet的强悍担当:GENet
  4. JVM参数调优,无停滞实践
  5. 百度回应“出售他人隐私”报道:从未开展此类业务
  6. [.net]c#登陆实现验证码-图形编程
  7. 微信团队分享:微信支付代码重构以及软件架构上的思考
  8. Linux之flash流媒体服务器red5安装
  9. 变更日志 批准的变更请求 收尾流程 原型法 名义小组 习题
  10. linux 查找py文件命令_Linux常用命令(一)
  11. WOX配置常用搜索引擎
  12. 解决windows电脑蓝屏的方法
  13. Android强行进阶:为何大厂APP如微信、支付宝、淘宝、手Q等只适配了armeabi-v7a/armeabi?
  14. 我们无法创建新分区。【错误:0x80042468】
  15. 学习OpenCV 函数方法结构总结
  16. 基于Redis实现查找附近的人
  17. 2019校招宜信JAVA研发面经
  18. Android APP连接电脑数据库(以SQL Server为例)
  19. SAP BASIS ADM100 中文版 Unit 5(4)
  20. 第八课——细述QQ与TIM的不同之处

热门文章

  1. vue 拖拽组件github网址
  2. 概率密度函数、分布函数区别
  3. 单分支结构与双分支结构与多分支结构
  4. 批处理获取本机IP(局域网)及MAC地址
  5. 佰马科技亮相中国通信展,参加智慧杆最受欢迎企业联展
  6. 利用Scrapy框架爬取前途无忧招聘信息
  7. 剑桥计算机通用英语优学院,优学院《剑桥计算机通用英语》答案2020中国大学《光学(王海艳)》查询答案...
  8. python口号_1947年10月10日,中国人民解放军总部发表宣言,提出的口号是( )
  9. 2020武汉大学计算机学院夏令营面经
  10. 人工智能:到底是天使还是恶魔?