setsocketopt转
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
setsocketopt 转
setsocketopt(转)2010-09-11 16:23NAME(
ip-Linux IPv4幸槭迪
SYNOPSIS(
#include sys/socket.h
#include net/netinet.h tcp_socket=socket(PF_INET,SOCK_STREAM,0);
raw_socket=socket(PF_INET,SOCK_RAW,protocol);
udp_socket=socket(PF_INET,SOCK_DGRAM,protocol);
DESCRIPTION(
Linux实现描述于RFC791和RFC1122中的Internet幸,版本4.ip包括遵
RFC1112的第二层的多信道广播技术的实现.它也包括含包过滤器的IP路
由器.
程序员的接口与BSD的套接字(socket)兼容.
要获得关于套接字的更多信息,参见(7)
创建一个IP套接字是通过以socket(PF_INET,socket_type,protocol)
方式调用(2)函数来实现的.有效的套接字类型(socket_type)有:
SOCK_STREAM用来打开一个(7)套接字,SOCK_DGRAM用来打开一个(7)
套接字,或者是SOCK_RAW用来打开一个(7)套接字用来直接访问IP幸椋protocol指的是要接收或者发送出去的包含在IP头标识(header)中的IP-
议.对于TCP套接字而言,唯一的有效protocol值是0和IPPROTO_TCP
对于UDP套接字而言,唯一的有效protocol值是0和IPPROTO_UDP.而对于
SOCK_RAW你可以指定一个在RFC1700中定义的有效IANA IP幸榇肜锤持.
当一个进程希望接受新的来访包或者连接时,它应该使用(2)
绑定一个套接字到一个本地接口地址.
任意给定的本地(地址,端口)对只能绑定一个IP套接字.当调用bind
时中声明了INADDR_ANY时,套接字将会绑定到觃
本地接口.当在未绑定的套接字上调用(2)或者(2)
时,套接字会自动绑定到一个本地地址设置为INADDR_ANY的随机的空闲端口上.
除非你设置了S0_REUSEADDR标识,否则一个已绑定的TCP
本地套接字地址在关闭后的一段时间内不可用.
使用该标识的时候要小心,因为它会使TCP变得不可靠.
ADDRESS FORMAT(
一个IP套接字地址定义为一个IP接口地址和一个端口号的组合.基本IP-
议不会提供端口号,它们通过更高层次的幸槿(7)和(7)来实现.
对于raw套接字,sin_port设置为IP幸椋
struct sockaddr_in{
sa_family_t sin_family;/*地址族:AF_INET*/
u_int16_t sin_port;/*按网络字节次序的端口*/
struct in_addr sin_addr;/*internet地址*/
};
/*Internet地址.*/
struct in_addr{
u_int32_t s_addr;/*按网络字节次序的地址*/
};
sin_family总是设置为AF_INET.这是必需的;在Linux 2.2
中,如果该设置缺失,大多数联网函数会返回EINVAL sin_port
包含按网络字节排序的端口号.端口号在1024以下的称为冢
只有那些有效用户标识为0或者CAP_NET_BIND_SERVICE有功能的进程才可以
(2)到这些套接字.注意允嫉模╮ aw)IPv4-
议没有这样的端口概念,它们只通过更高的幸槿(7)和(7)来实现.
sin_addr指的是IP主机地址.在struct in_addr中的addr
部分包含按网络字节序的主机接口地址.in_addr应该只能通过使用
(3),(3),(3)
库函数或者直接通过名字解析器(参见(3))来访问.IPv4
地址分成单点广播,广播传送和多点广播地址.
单点广播地址指定了一台主机的单一接口,广播地址指
定了在一个网段上的所有主机,
而多点广播地址则在一个多点传送组中寻址所有主机.只有当设置了套接字标识
SO_BROADCAST时,才能收发数据报到广播地址.
在当前的实现中,面向连接的套接字只允许使用单点传送地址.
注意地址和端口总是按照网络字节序存储的.
这意味着你需要对分配给端口的号码调用htons(3.
所有在标准库中的地址/端口处理函数都是按网络字节序运行的.
有几个特殊的地址:INADDR_LOOPBACK(127.0.0.1)总是代表-
由回环设备的本地主机;INADDR_ANY(0.0.0.0)表示任何可绑定的地址;
INADDR_BROADCAST(255.255.255.255)表示任何主机,由于历史的-
因,这与绑定为INADDR_ANY有同样的效果.
SOCKET OPTIONS(
IP支持一些与幸橄喙氐奶捉幼盅∠睿庑┭∠羁梢酝ü(2)
设置,并可以通过(2)读取.IP的套接字选项级别为SOL_IP IP_OPTIONS
设置或者获取将由该套接字发送的每个包的IP选项.
该参数是一个指向包含选项和选项长度的存储缓冲区的指针.
(2)系统调用设置与一个套接字相关联的IP选项.IPv4
的最大选项长度为40字节.参阅RFC791获取可用的选项.如果一个
SOCK_STREAM套接字收到的初始连接请求包包含IP选项时,IP
选项自动设置为来自初始包的选项,同时反转路由头.
在连接建立以后将不允许来访的包修改选项.
缺省情况下是关闭对所有来访包的源路由选项的,你可以用accept_source_route sysctl
来激活.仍然处理其它选项如时间戳(timestamp).
对于数据报套接字而言,IP选项只能由本地用户设置.调用带
IP_OPTIONS的(2)会把当前用于发送的IP
选项放到你提供的缓冲区中.
IP_PKTINFO
传递一条包含pktinfo结构(该结构提供一些来访包的相关信息)的IP_PKTINFO辅助信息.这个选项只对数据报类的套接字有效. struct in_pktinfo
{
unsigned int ipi_ifindex;/*接口索引*/
struct in_addr ipi_spec_dst;/*路由目的地址*/
struct in_addr ipi_addr;/*头标识目的地址*/
};
ipi_ifindex指的是接收包的接口的唯一索引.ipi_spec_dst
指的是路由表记录中的目的地址,而ipi_addr
指的是包头中的目的地址.如果给sendmsg(2)传递了IP_PKTINFO
那么外发的包会通过在ipi_ifindex中指定的接口发送出去,同时把
ipi_spec_dst设置为目的地址.
IP_RECVTOS
如果打开了这个选项,则IP_TOS,辅助信息会与来访包一起传递.
它包含一个字节用来指定包头中的服务/优先级字段的类型.
该字节为一个布尔整型标识.
IP_RECVTTL
当设置了该标识时,
传送一条带有用一个字节表示的接收包生存时间(time to live)字段的IP_RECVTTL控制信息.此选项还不支持SOCK_STREAM套接字.
IP_RECVOPTS
用一条IP_OPTIONS控制信息传递所有来访的IP选项给用户.
路由头标识和其它选项已疚镜刂骰詈茫此选项还不支持
SOCK_STREAM套接字.
IP_RETOPTS
等同于IP_RECVOPTS但是返回的是带有时间戳的未处理的-
始选项和在这段路由中未填入的路由记录项目.
IP_TOS设置或者接收源于该套接字的每个IP包的Type-Of-Service(TOS 服务类型)字段.它被用来在网络上区分包的优先级.TOS
是单字节的字段.定义了一些的标准TOS标识:IPTOS_LOWDELAY
用来为交互式通信最小化延迟时间,IPTOS_THROUGHPUT
用来优化吞吐量,IPTOS_RELIABILITY用来作可靠性优化,
IPTOS_MINCOST
应该被用作"填充数据",对于这些数据,低速传输是无关紧要的.
至多只能声明这些TOS值中的一个.其它的都是无效的,应当被清除. 缺省时,Linux首先发送IPTOS_LOWDELAY数据报,
但是确切的做法要看配置的排队规则而定.
一些高优先级的层次可能会要求一个有效的用户标识0或者
CAP_NET_ADMIN能力.优先级也可以以于幸槲熏氐姆绞酵ü(
SOL_SOCKET,SO_PRIORITY)套接字选项(参看(7))来设置.
IP_TTL设置或者检索从此套接字发出的包的当前生存时间字段.
IP_HDRINCL
如果打开的话,那么用户可在用户数据前面提供一个ip头.这只对SOCK_RAW有效.参看(7)
以获得更多信息.当激活了该标识之后,其值由IP_OPTIONS设定,并且IP_TOS被忽略.
IP_RECVERR
允许传递扩展的可靠的错误信息.如果在数据报上激活了该标识,
那么所有产生的错误会在每套接字一个的错误队列中排队等待.
当用户从套接字操作中收到错误时,就可以通过调用设置了MSG_ERRQUEUE
标识的(2)来接收.描述错误的sock_extended_err
结构将通过一条类型为IP_RECVERR,级别为
SOL_IP.
这个选项对在未连接的套接字上可靠地处理错误很有用.
错误队列的已收到的数据部分包含错误包.
IP按照下面的方法使用sock_extended_err结构:ICMP包接收的错误
ee_origin设为SO_EE_ORIGIN_ICMP,对于本地产生的错误则设为
SO_EE_ORIGIN_LOCAL.ee_type和ee_code设置为ICMP
头标识的类型和代码字段.ee_info包含用于EMSGSIZE时找到的MTU.
ee_data目前没有使用.
当错误来自于网络时,该套接字上所有IP选项都被激活(IP_OPTIONS,
IP_TTL,
等.)并且当做控制信息包含错误包中传递.引发错误的包的有效载荷会以正常数据返回.
在SOCK_STREAM套接字上,IP_RECVERR
会有细微的语义不同.它并不保存下次超时的错误,而是立即传递所有进来的错误给用户.
这对TCP连接时间很短的情况很有用,因为它要求快速的错误处理.
使用该选项要小心:因为不允许从路由转移和其它正
常条件下正确地进行恢复,它使得TCP变得不可靠,并且破坏幸榈墓娣.
注意TCP没有错误队列;MSG_ERRQUEUE对于SOCK_STREAM
套接字是非法的.因此所有错误都会由套接字函数返回,或者只返回
SO_ERROR.
对于允(raw)套接字而言,IP_RECVERR
允许传递所有接收到的ICMP错误给应用程序,否则错误只在连接的套接字上报告出来.
它设置或者检索一个整型布尔标识.IP_RECVERR缺省设置为off(关闭).
IP_PMTU_DISCOVER
为套接字设置或接收Path MTU Discovery setting(路径MTU发现设置).
当允许时,Linux会在该套接字上执行定义于RFC1191中的Path MTU Discovery(路径MTU发现).don't段标识会设置在所有外发的数据报上.
系统级别的缺省值是这样的:SOCK_STREAM套接字由ip_no_pmtu_disc sysctl控制,而对其它所有的套接字都被都屏蔽掉了,对于非
SOCK_STREAM套接字而言,
用户有责任按照MTU的大小对数据分块并在必要的情况下进行中继重发.如果设置了该标识
(用EMSGSIZE),内核会拒绝比已知路径MTU更大的包.
Path MTU discovery(路径MTU发现)标识含义
IP_PMTUDISC_WANT对每条路径进行设置.
IP_PMTUDISC_DONT从不作Path MTU Discovery(路径MTU发现).
IP_PMTUDISC_DO总作Path MTU Discovery(路径MTU发现).
当允许PMTU(路径MTU)搜索时,内核会自动记录每个目的主机的path
MTU(路径MTU).当它使用(2)
连接到一个指定的对端机器时,可以方便地使用IP_MTU
套接字选项检索当前已知的path MTU(路径MTU)(比如,在发生了一个
EMSGSIZE错误后).它可能随着时间的推移而改变.
对于带有许多目的端的非连接的套接字,一个特定目的端的新到来的MTU
也可以使用错误队列(参看IP_RECVERR)来存取访问.
新的错误会为每次到来的MTU的更新排队等待.
当进行MTU搜索时,来自数据报套接字的初始包可能会被丢弃.使用
UDP的应用程序应该知道这个并且考虑其包的中继传送策略.
为了在未连接的套接字上引导路径MTU发现进程,
我们可以用一个大的数据报(头尺寸超过64K字节)启动,
并令其通过更新路径MTU逐步收缩.
为了获得路径MTU连接的初始估计,可通过使用(2)
把一个数据报套接字连接到目的地址,并通过调用带IP_MTU(2)检索该MTU.
IP_MTU检索当前套接字的当前已知路径MTU.只有在套接字被连接时才是有效的.返回一个整数.只有作为一个
(2)才有效.
IP_ROUTER_ALERT
给该套接字所有将要转发的包设置IP路由器警告(IP RouterAlert option)选项.只对允继捉幼郑╮ aw socket)有效,这对用户空间的
RSVP后台守护程序之类很有用.
分解的包不能被内核转发,用户有责任转发它们.套接字绑定被忽略,
这些包只按幸楣.要求获得一个整型标识.
IP_MULTICAST_TTL
设置或者读取该套接字的外发多点广播包的生存时间值.
这对于多点广播包设置可能的最小TTL很重要.
缺省值为1,这意味着多点广播包不会超出本地网段,
除非用户程序明确地要求这么做.参数是一个整数.
IP_MULTICAST_LOOP
设置或读取一个布尔整型参数以决定发送的多点广播包是否应该被回送到本地套接字.
IP_ADD_MEMBERSHIP
加入一个多点广播组.参数为struct ip_mreqn结构.
struct ip_mreqn
{
struct in_addr imr_multiaddr;/*IP多点传送组地址*/
struct in_addr imr_address;/*本地接口的IP地址*/
int imr_ifindex;/*接口索引*/
};
imr_multiaddr包含应用程序希望加入或者退出的多点广播组的地址.
它必须是一个有效的多点广播地址.imr_address
指的是系统用来加入多点广播组的本地接口地址;如果它与INADDR_ANY 一致,那么由系统选择一个合适的接口.imr_ifindex
指的是要加入/脱离imr_multiaddr
组的接口索引,或者设为0表示任何接口.
由于兼容性的缘故,老的ip_mreq接口仍然被支持.它与ip_mreqn
只有一个地方不同,就是没有包括imr_ifindex字段.这只在作为一个
(2)时才有效.
IP_DROP_MEMBERSHIP
脱离一个多点广播组.参数为ip_mreqn或者ip_mreq结构,这与
IP_ADD_MEMBERSHIP类似.
IP_MULTICAST_IF
为多点广播套接字设置本地设备.参数为ip_mreqn或者ip_mreq
结构,它与IP_ADD_MEMBERSHIP类似.
当传递一个无效的套接字选项时,返回ENOPROTOOPT.
SYSCTLS IP幸橹Сsysctl接口配置一些全局选项.sysctl可通过读取或者写入
文件或使用(2)接口来存取访问.
ip_default_ttl
设置外发包的缺省生存时间值.此值可以对每个套接字通过IP_TTL
选项来修改.
ip_forward
以一个布尔标识来激活IP转发功能.IP转发也可以按接口来设置
ip_dynaddr
打开接口地址改变时动态套接字地址和伪装记录的重写.
这对具有变化的IP地址的拨号接口很有
用.0表示不重写,1打开其功能,而2则激活冗余模式.
ip_autoconfig
无文档
ip_local_port_range
包含两个整数,定义了缺省分配给套接字的本地端口范围.
分配起始于第一个数而终止于第二个数.
注意这些端口不能与伪装所使用的端口相冲突(尽管这种情况也可以处理).
同时,随意的选择可能会导致一些防火墙包过滤器的问题,它们会误认为本地端口在使用.
第一个数必须至少1024,最好是4096以避免与众所周知的端口发生冲突,
从而最大可能的减少防火墙问题.
ip_no_pmtu_disc
如果打开了,缺省情况下不对TCP套接字执行路径MTU发现.
如果在路径上误配置了防火墙(用来丢弃所有ICMP包)或者误配置了接口(例如,设置了一个两端MTU不同的端对端连接),路径MTU发现可能会失败. 宁愿修复路径上的损坏的路由器,也好过整个地关闭路径MTU发现,
因为这样做会导致网络上的高开销.
ipfrag_high_thresh,ipfrag_low_thresh
如果排队等待的IP碎片的数目达到ipfrag_high_thresh,队列被排空为ipfrag_low_thresh.这包含一个表示字节数的整数.
ip_always_defrag
[kernel 2.2.13中的新功能;在早期内核版本中,该功能在编译时通过CONFIG_IP_ALWAYS_DEFRAG选项来控制]
当该布尔标识被激活(不等于0)时,
来访的碎片(IP包的一部分,这生成于当一些在源端和目的端之间的主机认
定包太大而分割成许多碎片的情况下)将在处理之前重新组合(碎片整理), 即使它们马上要被转发也如此.
只在运行着一台与网络单一连接的防火墙或者透明代理服务器时才这么干;对于正常的路由器或者主机,永远不要打开它.
否则当碎片在不同连接中通过时碎片的通信可能会被扰乱.
而且碎片重组也需要花费大量的内存和CPU时间.
这在配置了伪装或者透明代理的情况下自动打开.
neigh/*
参看(7)
IOCTLS
所有在(7)中有描述的ioctl都可应用于ip.
用于配置防火墙应用的ioctl记载在ipchains包的(7)的文档中.
用来配置普通设备参数的ioctl在(7)中有描述.
NOTES(
使用SO_BROADCAST选项要小心-它在Linux中没有权限要求.
不小心的广播很容易导致网络过载.对于新的应用幸槎,最
好是使用多点广播组来替代广播.我们不鼓励使用广播.
有些其它的BSD套接字实现提供了IP_RCVDSTADDR和IP_RECVIF
套接字选项来获得目的地址以及接收数据报的接口.Linux有更通用的IP_PKTINFO
来完成相同任务.
ERRORS(
ENOBUFS,EPERM对EACCES等.)
ENOTCONN
操作只定义于连接的套接字,而该套接字却没有连接.
EINVAL传递无效的参数.对于发送操作,这可以因发送到一个blackhole()
路由而引发.
EMSGSIZE
数据报大于该路径上的MTU,并且它不能被分成碎片.
EACCES没有必要权限的用户试图执行一项需要某些权限的操作.这包括:
在没有SO_BROADCAST标识设置的情况下发送一个包到广播地址.
通过一条路由发送包.在没有CAP_NET_ADMIN
或者有效用户标识不为0的情况下修改防火墙设置.在没有
CAP_NET_BIND_SERVICE
能力或者有效用户标识不为零0的情况下绑定一个保留端口.
EADDRINUSE
试图绑定到一个已在使用的地址.
ENOMEM和ENOBUFS
没有足够的内存可用.
ENOPROTOOPT和EOPNOTSUPP
传递无效的套接字选项.
EPERM用户没有权限设置高优先级,修改配置或者发送信号到请求的进程或组.
EADDRNOTAVAIL
请求一个不存在的接口或者请求的源端地址不是本地的.
EAGAIN在一个非阻塞的套接字上进行操作会阻塞. ESOCKTNOSUPPORT
套接字未配置或者请求了一个未知类型的套接字.
EISCONN
在一个已玖拥奶捉幼稚系饔(2).
EALREADY
在一个非阻塞的套接字上的连接操作已驹诮兄. ECONNABORTED
在一次(2)执行中连接被关闭.
EPIPE连接意外关闭或者被对端关闭.
ENOENT在没有报到达的套接字上调用SIOCGSTAMP. EHOSTUNREACH
没有有效路由表记录匹配目的地址.该错误可以被来自远程路由器的ICMP消息或者因为本地路由表的缘故而引发.
ENODEV网络设备不可用或者不适于发送IP.
ENOPKG内核子系统没有配置.
ENOBUFS,ENOMEM
没有足够的空闲内存.
这常常意味着内存分配因套接字缓冲区的限制而受限,
而不是因为系统内存的缘故,但是这也不是100%正确.
其它错误可能由重叠幸樽迳;参看(7),(7),(7)和(7).
VERSIONS(
IP_PKTINFO,IP_MTU,IP_PMTU_DISCOVER,IP_PKTINFO,IP_RECVERR和
IP_ROUTER_ALERT是Linux 2.2中的新选项.
struct ip_mreqn也是新出现在Linux 2.2中的.Linux 2.0只支持
ip_mreq.
sysctl是在Linux 2.2中引入的.
COMPATIBILITY(
为了与Linux 2.0相容,仍然支持用过时的socket(PF_INET,SOCK_RAW,
protocol语法打开一个(7)套接字.我们不赞成这么用,而且应该被
socket(PF_PACKET,SOCK_RAW,protocol所代替.主要的区别就是
新的针对一般链接层信息的sockaddr_ll地址结构替换了旧的sockaddr_pkt
地址结构.
BUGS
有许多不连贯的错误码.
没有描述用来配置特定IP接口选项和ARP表的ioctl.
AUTHORS(
该man页作者是Andi Kleen.
SEE ALSO(
(2),(2),(7),(7),(7),(7),(7),
(7).
RFC791:允糏 P规范.
RFC1122:IPv4主机需求.
RFC1812:IPv4路由器需求.
[riser
[2001/07/19 l
特别声明:
1:资料来源于互联网,版权归属原作者
2:资料内容属于网络意见,与本账号立场无关3:如有侵权,请告知,立即删除。