当前位置: 首页 > article >正文

ngx_connection_local_sockaddr

1 定义ngx_connection_local_sockaddr 函数 定义在 ./nginx-1.24.0/src/core/ngx_connection.cngx_int_tngx_connection_local_sockaddr(ngx_connection_t*c,ngx_str_t*s,ngx_uint_tport){socklen_tlen;ngx_uint_taddr;ngx_sockaddr_tsa;structsockaddr_in*sin;#if(NGX_HAVE_INET6)ngx_uint_ti;structsockaddr_in6*sin6;#endifaddr0;if(c-local_socklen){switch(c-local_sockaddr-sa_family){#if(NGX_HAVE_INET6)caseAF_INET6:sin6(structsockaddr_in6*)c-local_sockaddr;for(i0;addr0i16;i){addr|sin6-sin6_addr.s6_addr[i];}break;#endif#if(NGX_HAVE_UNIX_DOMAIN)caseAF_UNIX:addr1;break;#endifdefault:/* AF_INET */sin(structsockaddr_in*)c-local_sockaddr;addrsin-sin_addr.s_addr;break;}}if(addr0){lensizeof(ngx_sockaddr_t);if(getsockname(c-fd,sa.sockaddr,len)-1){ngx_connection_error(c,ngx_socket_errno,getsockname() failed);returnNGX_ERROR;}c-local_sockaddrngx_palloc(c-pool,len);if(c-local_sockaddrNULL){returnNGX_ERROR;}ngx_memcpy(c-local_sockaddr,sa,len);c-local_socklenlen;}if(sNULL){returnNGX_OK;}s-lenngx_sock_ntop(c-local_sockaddr,c-local_socklen,s-data,s-len,port);returnNGX_OK;}ngx_connection_local_sockaddr 函数 获取并缓存当前连接的本地套接字地址 并可将其转换为文本格式的 IP和端口字符串。 它首先检查连接上是否已缓存有效的非“全零”地址 若没有则调用 getsockname 获取真实本地地址并保存到连接的内存池中 若调用者提供了输出字符串结构 s 则进一步将该地址格式化为可读字符串是否带端口由参数 port 控制。2 详解1 函数签名ngx_int_tngx_connection_local_sockaddr(ngx_connection_t*c,ngx_str_t*s,ngx_uint_tport)返回值 NGX_OK操作成功完成。 NGX_ERROR操作失败 调用者通常通过检查返回值是否为 NGX_OK 来判断是否成功。参数1 ngx_connection_t *c 指向 ngx_connection_t 结构的指针。 代表一个客户端的 TCP 或 Unix 域套接字连接。 c-fd套接字文件描述符用于调用 getsockname 获取本地地址 通过传入此连接对象函数即可获知要对哪个套接字进行操作以及将结果缓存在哪里参数2 ngx_str_t *s 双重用途输入与输出 输入 调用者预先分配好缓冲区s-data 指向缓冲区的起始地址s-len 存放该缓冲区的大小字节数。 输出 函数内部调用 ngx_sock_ntop 将本地套接字地址格式化为可读字符串 并修改 s-len 为实际写入的字符数不包含结尾的 \0。 此时 s 成为一个合法的 Nginx 字符串可被其它 Nginx 模块直接使用。 若为 NULL 表示调用者仅希望确保本地地址已被缓存不需要获取字符串形式。 此时函数在校验/填充完缓存地址后直接返回 NGX_OK。参数3 ngx_uint_t port 作用 控制由 ngx_sock_ntop 生成的字符串是否包含端口号。 值为 1或非零 格式化为 IP:PORT 的形式例如 192.168.1.1:80 或 [::1]:8080。 值为 0 仅返回 IP 地址本身不附加端口。2 逻辑流程1 局部变量 2 已缓存本地地址 3 获取地址 4 无需字符串 5 返回成功1 局部变量{socklen_tlen;ngx_uint_taddr;ngx_sockaddr_tsa;structsockaddr_in*sin;#if(NGX_HAVE_INET6)ngx_uint_ti;structsockaddr_in6*sin6;#endifaddr0;将 addr 初始化为 0 表示“默认认为本地地址是全零未指定”。 后续会通过检查已缓存的地址来修改它。2 已缓存本地地址if(c-local_socklen){switch(c-local_sockaddr-sa_family){#if(NGX_HAVE_INET6)caseAF_INET6:sin6(structsockaddr_in6*)c-local_sockaddr;for(i0;addr0i16;i){addr|sin6-sin6_addr.s6_addr[i];}break;#endif#if(NGX_HAVE_UNIX_DOMAIN)caseAF_UNIX:addr1;break;#endifdefault:/* AF_INET */sin(structsockaddr_in*)c-local_sockaddr;addrsin-sin_addr.s_addr;break;}}#1 判断连接对象 c 中是否已经保存了本地地址的长度local_socklen 非 0。 若已保存说明之前已成功获取过本地地址可以直接利用缓存 若为 0说明尚未获取需要调用 getsockname。#2 根据已缓存地址的协议族sa_family进入不同的分支提取有效地址判断标志 addr。#2-1 如果支持 IPv6 并且协议族是 AF_INET6 则将已缓存地址强制转换成 sockaddr_in6 指针以便访问 16 字节的 IPv6 地址部分。 遍历 IPv6 地址的 16 个字节。 循环条件是 addr 0 i 16 即只要 addr 仍为 0说明前面检查的字节全为 0且未遍历完 16 个字节就继续。 每次循环将当前字节 sin6-sin6_addr.s6_addr[i] 按位或到 addr 上。 如果 16 个字节全部为 0则循环结束后 addr 仍为 0 只要任何一字节非零addr 就变为非零后续循环会因为 addr 0 为假而提前结束节省 CPU。#2-2 对于 Unix 域套接字地址AF_UNIX 不存在“全零未指定”的概念直接设置 addr 1 表示地址有效无需再次获取。#2-3 其他情形默认即 IPv4。 将缓存地址转为 sockaddr_in然后将其 32 位网络字节序的地址值赋给 addr。 如果该地址是 INADDR_ANY即 0.0.0.0则 s_addr 为 0addr 为 0表示未指定。3 获取地址if(addr0){lensizeof(ngx_sockaddr_t);if(getsockname(c-fd,sa.sockaddr,len)-1){ngx_connection_error(c,ngx_socket_errno,getsockname() failed);returnNGX_ERROR;}c-local_sockaddrngx_palloc(c-pool,len);if(c-local_sockaddrNULL){returnNGX_ERROR;}ngx_memcpy(c-local_sockaddr,sa,len);c-local_socklenlen;}#1 如果经过上述检查后 addr 仍为 0意味着两种情况 1 从未获取过本地地址local_socklen 0 2 已缓存的地址是通配地址全零需要获取真正的本地地址。此时通过 getsockname 获取。#2 设置 len 为 ngx_sockaddr_t 联合体的大小 作为传递给 getsockname 的缓冲区最大长度。#3 调用系统 API getsockname获取文件描述符 c-fd 关联的本地套接字地址。 地址被写入 sa.sockaddr 所在的内存区域len 被设置为实际地址长度。 如果调用失败返回 -1 用 ngx_connection_error 记录错误日志 并返回 NGX_ERROR 表示失败。#4 从当前连接的内存池 c-pool 中分配 len 字节内存用于持久保存该地址。 这样后续对同一连接的调用可直接复用缓存 若内存分配失败返回 NULL则返回 NGX_ERROR。#5 将栈上临时变量 sa 中刚获取的地址数据复制到新分配的内存 c-local_sockaddr 中完成缓存。#6 将地址长度记录下来标记缓存有效。 下次调用此函数时if (c-local_socklen) 将成立并直接使用缓存。4 无需字符串if(sNULL){returnNGX_OK;}s-lenngx_sock_ntop(c-local_sockaddr,c-local_socklen,s-data,s-len,port);#1 如果调用者没有提供输出字符串的结构s NULL 表示它只希望确保本地地址已缓存不需要转换成文本。 此时直接返回 NGX_OK函数的核心任务已完成。#2 调用 ngx_sock_ntop 函数将已缓存的套接字地址转换为可读文本 写入 s-data 指向的预分配缓冲区。 传入的 s-len 是缓冲区大小输入 函数返回实际写入的字符数不含结尾 \0 并将其重新赋值给 s-len使 s 成为一个合法的 ngx_str_t。 参数 port 控制是否在地址后附加 :端口号。5 返回成功returnNGX_OK;}所有操作成功完成返回 NGX_OK。总结逻辑流程 函数通过先检查缓存、再按需调用 getsockname 的方式 确保连接对象中存在一个真实有效的本地地址非全零 并能按要求生成文本表示。 这种“缓存惰性求值”的设计避免了不必要的系统调用 同时保证了地址与端口字符串的易用性。

相关文章:

ngx_connection_local_sockaddr

1 定义 ngx_connection_local_sockaddr 函数 定义在 ./nginx-1.24.0/src/core/ngx_connection.cngx_int_t ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,ngx_uint_t port) {socklen_t len;ngx_uint_t addr;ngx_sockaddr_t …...

如何免费下载Steam创意工坊模组:跨平台玩家的终极解决方案

如何免费下载Steam创意工坊模组:跨平台玩家的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在Epic Games Store或GOG平台购买了心仪的游戏&…...

GRETNA开源工具实战指南:从零掌握MATLAB脑网络分析

GRETNA开源工具实战指南:从零掌握MATLAB脑网络分析 【免费下载链接】GRETNA A Graph-theoretical Network Analysis Toolkit in MATLAB 项目地址: https://gitcode.com/gh_mirrors/gr/GRETNA 在神经科学研究中,如何从复杂的大脑影像数据中提取有意…...

5个实战技巧:高效使用WebAssembly进行浏览器端图像处理

5个实战技巧:高效使用WebAssembly进行浏览器端图像处理 【免费下载链接】opencvjs JavaScript Bindings for OpenCV 项目地址: https://gitcode.com/gh_mirrors/op/opencvjs OpenCV.js是OpenCV计算机视觉库的JavaScript绑定版本,通过Emscripten将…...

3个步骤掌握AI Toolkit:从零到一的完整AI开发指南

3个步骤掌握AI Toolkit:从零到一的完整AI开发指南 【免费下载链接】vscode-ai-toolkit 项目地址: https://gitcode.com/GitHub_Trending/vs/vscode-ai-toolkit AI Toolkit for Visual Studio Code是一款专为开发者设计的AI应用开发扩展,它将Azur…...

小龙虾养成记:小龙虾和爱马仕(OpenClaw vs Hermes)源码对比与选型指南

适用人群:第一次接触 OpenClaw / Hermes,想快速看懂差异、做选型、不踩坑。 OpenClaw:偏本地与可控编排 | Hermes:偏在线与持续运营 小龙虾和爱马仕怎么选?是不是很多朋友都有这个疑惑。其实很多朋友第一次看 OpenClaw 和 Hermes,会有同一个感受: “都能接微信/飞书/…...

如何快速配置Lab Streaming Layer:科研数据同步与流式处理的完整指南

如何快速配置Lab Streaming Layer:科研数据同步与流式处理的完整指南 【免费下载链接】labstreaminglayer LabStreamingLayer super repository comprising submodules for LSL and associated apps. 项目地址: https://gitcode.com/gh_mirrors/la/labstreamingla…...

CSS旋转效果在Edge旧版支持_添加-ms-transform前缀与过渡

本文教你如何将 random.randint(100, 999) 生成的三位整数拆解为各位数字,高效判断是否存在重复数字(如 112、333),并量化重复程度(双重复/三重复),从而为游戏逻辑提供可编程的胜率倍数变量。 …...

5分钟搞定小说离线阅读:Novel-Downloader终极使用指南

5分钟搞定小说离线阅读:Novel-Downloader终极使用指南 【免费下载链接】novel-downloader 一个可扩展的通用型小说下载器。 项目地址: https://gitcode.com/gh_mirrors/no/novel-downloader 你是否经常遇到这样的情况:追更到一半的小说突然网站打…...

星露谷农场规划器:专业级农场布局设计与优化方案

星露谷农场规划器:专业级农场布局设计与优化方案 【免费下载链接】stardewplanner Stardew Valley farm planner 项目地址: https://gitcode.com/gh_mirrors/st/stardewplanner 星露谷农场规划器(Stardew Valley Farm Planner)是一款专…...

终极指南:如何用RPFM快速上手《全面战争》模组制作

终极指南:如何用RPFM快速上手《全面战争》模组制作 【免费下载链接】rpfm Rusted PackFile Manager (RPFM) is a... reimplementation in Rust and Qt6 of PackFile Manager (PFM), one of the best modding tools for Total War Games. 项目地址: https://gitcod…...

构建现代化IT资产管理体系:开源CMDB如何解决企业运维核心痛点

构建现代化IT资产管理体系:开源CMDB如何解决企业运维核心痛点 【免费下载链接】open-cmdb 开源资产管理平台 项目地址: https://gitcode.com/gh_mirrors/op/open-cmdb 在数字化转型的浪潮中,企业IT基础设施日益复杂,资产管理混乱、运维…...

零基础入门kohya_ss:在AMD GPU上轻松训练你的专属AI绘画模型

零基础入门kohya_ss:在AMD GPU上轻松训练你的专属AI绘画模型 【免费下载链接】kohya_ss 项目地址: https://gitcode.com/GitHub_Trending/ko/kohya_ss 你是否曾经想过,用自己的AMD显卡就能训练出专属的AI绘画模型?不用羡慕那些拥有昂…...

我开源了一款本地音乐播放器 —— Yeah Music,欢迎大家体验

我开源了一款本地音乐播放器 —— Yeah Music,欢迎大家体验 🎵 大家好,我是一名普通的开发者,也是个重度本地音乐爱好者。 这些年被各种商业音乐App的广告、会员、联网要求搞得很烦,尤其是想好好听自己收藏的无损音乐时…...

【PostgreSQL从零到精通】第48篇:PL/Proxy数据分片——PostgreSQL的水平扩展利器

上一篇【第47篇】Bucardo多主复制——实现真正的双向数据同步 下一篇【第49篇】pgpool-II完全指南——连接池复制负载均衡的三合一方案 单台 PostgreSQL 服务器的读写能力总有一个上限。当数据量达到 TB 级别、并发请求达到数万 QPS 时,再怎么优化硬件也无济于事——…...

看完100个失败私域直播案例,90%的人死在预热前

前年刚开始搞私域直播的时候,我特别自信,觉得产品也好、主播也专业,开播肯定有人看。结果呢?第一场播下来,场观不到两百,卖了不到一千块。我当时完全懵了,不知道问题出在哪。后来我一个做私域的…...

D3.js:数据可视化的终极利器

什么是 D3.js D3.js(Data-Driven Documents)是一个基于 JavaScript 的数据可视化库,用于创建动态、交互式的数据可视化图表。它通过绑定数据到 DOM(文档对象模型),并利用 HTML、SVG 和 CSS 实现数据驱动的…...

从零搭建一个拼多多CPS返利小程序:我的踩坑记录与避坑指南

从零搭建一个拼多多CPS返利小程序:我的踩坑记录与避坑指南 去年夏天,我决定尝试开发一个拼多多CPS返利小程序。作为一个独立开发者,我本以为凭借多年的编程经验,两周就能搞定这个"小项目"。没想到从API对接、用户绑定到…...

从D435i的深度图反推:如何让OpenCV SGBM的输出更接近工业级传感器效果?

从D435i深度图反推:OpenCV SGBM算法优化实战指南 当你在机器人导航或三维重建项目中对比OpenCV SGBM算法生成的深度图与Intel RealSense D435i输出的结果时,是否发现前者总是显得"平面化"且噪声明显?这背后隐藏着工业级深度传感器在…...

RAG进阶:下一代RAG怎么玩?

基础RAG能解决80%的问题,但剩下20%的难题,需要更进阶的技术。一、基础RAG碰到了什么天花板 基础RAG的套路很简单:文档切块 → Embedding → 向量检索 → 拼接Prompt → 大模型生成答案。 简单场景够用,但往深了用,三个…...

用GD32F470的ADC+DMA实现高精度电流采样,附梁山派开发板实测波形

GD32F470高精度电流采样实战:ADC过采样与DMA传输的工程化实现 在电机控制和电源监测领域,电流采样的精度和实时性直接决定了系统性能的上限。传统12位ADC往往难以兼顾噪声抑制和动态响应,而外置高精度ADC又会增加BOM成本和布线复杂度。本文将…...

【Docker 工程实践】AI 服务容器化部署全流程

文章目录Docker 工程实践:AI 服务容器化部署全流程一、引言二、核心挑战:Mac arm64 → Linux amd64 的跨平台陷阱2.1 为什么会出现 exec format error2.2 一个镜像跑两端:统一构建 amd64三、Dockerfile 工程规范3.1 标准生产模板3.2 多阶段构…...

VMware Workstation 虚拟机创建客户端系统,出现此主机不支持64位客户机操作系统问题解决

安装VMware Workstation 虚拟机(版本15.5),选择windows 11 64位是出现此主机不支持64位客户机操作系统.硬件以及系统支持64位。网上找了几个情况1、hyper-v 功能选项是否开启状态,关闭它2、看CPU技术是否支持虚拟技术,打开任务管…...

如何配置Data Guard环境中的应用连接_客户端TAF与服务漂移Service Trigger

TAF配置不生效主因是TNSNAMES.ORA中未正确定义FAILOVER_MODE参数,需显式设置TYPE(SESSION/SELECT)、METHOD(BASIC)、RETRIES、DELAY及ADDRESS_LIST顺序;srvctl服务需配合DB_ROLE_CHANGE触发器或Broker手动启…...

从Claude Code源码泄露事件看AI CLI工具的五层架构与安全设计

1. 项目概述:一次对Claude Code CLI的深度技术考古最近,AI编程助手领域发生了一件颇有意思的技术事件:Anthropic官方推出的命令行工具Claude Code,其完整的TypeScript源代码意外地在npm包中被公开了。这并非一次主动的开源&#x…...

告别Hackbar解析错误!用Burp Suite搞定复杂GET/POST请求的保姆级教程

告别Hackbar解析错误!用Burp Suite搞定复杂GET/POST请求的保姆级教程 在Web安全测试和CTF比赛中,处理HTTP请求是基本功。许多初学者习惯使用浏览器插件Hackbar快速构造请求,但当遇到复杂参数时,Hackbar的解析能力就显得力不从心。…...

Scratch编程实战:手把手教你实现坦克大战的“穿墙”与“子弹反弹”效果(附完整源码)

Scratch编程实战:从零构建坦克大战的穿墙与子弹反弹机制 引言:为什么选择坦克大战作为Scratch进阶项目? 坦克大战作为经典游戏,其核心机制对编程初学者极具教学价值。不同于简单动画项目,它需要处理角色移动边界检测、…...

不止于Hello World:在IDEA里用Lua写一个自动化运维小工具(环境搭建+实战)

不止于Hello World:在IDEA里用Lua写一个自动化运维小工具(环境搭建实战) 当开发者第一次接触Lua时,往往止步于打印"Hello World"的成就感。但Lua真正的魅力在于其轻量级特性与嵌入式优势,特别适合作为自动化…...

从MII到RGMII:你的嵌入式网卡PCB面积是怎么省下来的?一个硬件老鸟的笔记

从MII到RGMII:硬件工程师的PCB布局优化实战指南 当我在设计第一块千兆以太网卡时,面对密密麻麻的GMII接口走线几乎崩溃——8位数据线、控制信号和时钟线让本已紧张的PCB空间雪上加霜。直到发现RGMII这个"布线救星",才真正体会到接口…...

OpenClaw 工具接入 Taotoken 的配置要点与注意事项

OpenClaw 工具接入 Taotoken 的配置要点与注意事项 对于使用 OpenClaw 构建智能体工作流的开发者而言,统一接入多个大模型并管理其调用是一个常见的需求。Taotoken 作为一个提供 OpenAI 兼容 API 的平台,可以很好地与 OpenClaw 集成。本文将详细说明如何…...