1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Socket定数に無い定数を無理やり使う

Posted at

事の発端

Windows 7 で IP層のフラグ Don't Fragmentation を OFF にしたいと思い。以下のように設定。

require 'socket'

s0 = TCPServer.open("", 12345)
p s0.setsockopt(:IP, Socket::IP_DONTFRAG, 0) # => uninitialized constant Socket::IP_DONTFRAG (NameError)

Socket::IP_TTLはうまくいくので、指定が間違っているのではなさそう。

p s0.setsockopt(:IP, Socket::IP_TTL, 255) # => 0

定数が本当にないのか?

require 'socket'
require 'pp'

pp Socket.constants # => [
 :Option,
 :Constants,
 :SOCK_STREAM,
 :SOCK_DGRAM,
 :SOCK_RAW,
 :SOCK_RDM,
 :SOCK_SEQPACKET,
 :AF_UNSPEC,
 :PF_UNSPEC,
 :AF_INET,
 :PF_INET,
 :AF_INET6,
 :PF_INET6,
 :AF_UNIX,
 :PF_UNIX,
 :AF_IPX,
 :PF_IPX,
 :AF_APPLETALK,
 :PF_APPLETALK,
 :AF_IMPLINK,
 :PF_IMPLINK,
 :AF_PUP,
 :PF_PUP,
 :AF_CHAOS,
 :PF_CHAOS,
 :AF_NS,
 :PF_NS,
 :AF_ISO,
 :PF_ISO,
 :AF_OSI,
 :PF_OSI,
 :AF_ECMA,
 :PF_ECMA,
 :AF_DATAKIT,
 :PF_DATAKIT,
 :AF_CCITT,
 :PF_CCITT,
 :AF_SNA,
 :PF_SNA,
 :AF_DLI,
 :PF_DLI,
 :AF_LAT,
 :PF_LAT,
 :AF_HYLINK,
 :PF_HYLINK,
 :AF_NETBIOS,
 :AF_ATM,
 :PF_ATM,
 :AF_MAX,
 :PF_MAX,
 :MSG_OOB,
 :MSG_PEEK,
 :MSG_DONTROUTE,
 :MSG_WAITALL,
 :SOL_SOCKET,
 :IPPROTO_IP,
 :IPPROTO_ICMP,
 :IPPROTO_IGMP,
 :IPPROTO_GGP,
 :IPPROTO_TCP,
 :IPPROTO_PUP,
 :IPPROTO_UDP,
 :IPPROTO_IDP,
 :IPPROTO_ND,
 :IPPROTO_AH,
 :IPPROTO_DSTOPTS,
 :IPPROTO_ESP,
 :IPPROTO_FRAGMENT,
 :IPPROTO_HOPOPTS,
 :IPPROTO_ICMPV6,
 :IPPROTO_IPV6,
 :IPPROTO_NONE,
 :IPPROTO_ROUTING,
 :IPPROTO_RAW,
 :IPPROTO_MAX,
 :IPPORT_RESERVED,
 :IPPORT_USERRESERVED,
 :INADDR_ANY,
 :INADDR_BROADCAST,
 :INADDR_LOOPBACK,
 :INADDR_UNSPEC_GROUP,
 :INADDR_ALLHOSTS_GROUP,
 :INADDR_MAX_LOCAL_GROUP,
 :INADDR_NONE,
 :IP_OPTIONS,
 :IP_HDRINCL,
 :IP_TOS,
 :IP_TTL,
 :IP_MULTICAST_IF,
 :IP_MULTICAST_TTL,
 :IP_MULTICAST_LOOP,
 :IP_ADD_MEMBERSHIP,
 :IP_DROP_MEMBERSHIP,
 :IP_PKTINFO,
 :IP_UNBLOCK_SOURCE,
 :IP_BLOCK_SOURCE,
 :IP_ADD_SOURCE_MEMBERSHIP,
 :IP_DROP_SOURCE_MEMBERSHIP,
 :SO_DEBUG,
 :SO_REUSEADDR,
 :SO_TYPE,
 :SO_ERROR,
 :SO_DONTROUTE,
 :SO_BROADCAST,
 :SO_SNDBUF,
 :SO_RCVBUF,
 :SO_KEEPALIVE,
 :SO_OOBINLINE,
 :SO_LINGER,
 :SO_RCVLOWAT,
 :SO_SNDLOWAT,
 :SO_RCVTIMEO,
 :SO_SNDTIMEO,
 :SO_ACCEPTCONN,
 :SO_USELOOPBACK,
 :TCP_NODELAY,
 :EAI_AGAIN,
 :EAI_BADFLAGS,
 :EAI_FAIL,
 :EAI_FAMILY,
 :EAI_MEMORY,
 :EAI_NODATA,
 :EAI_NONAME,
 :EAI_SERVICE,
 :EAI_SOCKTYPE,
 :AI_PASSIVE,
 :AI_CANONNAME,
 :AI_NUMERICHOST,
 :NI_MAXHOST,
 :NI_MAXSERV,
 :NI_NOFQDN,
 :NI_NUMERICHOST,
 :NI_NAMEREQD,
 :NI_NUMERICSERV,
 :NI_DGRAM,
 :SHUT_RD,
 :SHUT_WR,
 :SHUT_RDWR,
 :IPV6_JOIN_GROUP,
 :IPV6_LEAVE_GROUP,
 :IPV6_MULTICAST_HOPS,
 :IPV6_MULTICAST_IF,
 :IPV6_MULTICAST_LOOP,
 :IPV6_UNICAST_HOPS,
 :IPV6_HOPLIMIT,
 :IPV6_PKTINFO,
 :INET_ADDRSTRLEN,
 :INET6_ADDRSTRLEN,
 :SOMAXCONN,
 :UDPSource,
 :WaitReadable,
 :WaitWritable,
 :SEEK_SET,
 :SEEK_CUR,
 :SEEK_END,
 :RDONLY,
 :WRONLY,
 :RDWR,
 :APPEND,
 :CREAT,
 :EXCL,
 :NONBLOCK,
 :TRUNC,
 :BINARY,
 :LOCK_SH,
 :LOCK_EX,
 :LOCK_UN,
 :LOCK_NB,
 :NULL,
 :FNM_NOESCAPE,
 :FNM_PATHNAME,
 :FNM_DOTMATCH,
 :FNM_CASEFOLD,
 :FNM_EXTGLOB,
 :FNM_SYSCASE]

... ない。何故ないのかは不明。

setsockopt に Integer 直接入れたら行けんじゃね?

rubyのリファレンスのSocket#setsockoptを見てみると。
setsockopt(2)を参照してくださいとの記載が。見ると、引数はintの模様。
rubyから整数を渡してやったらそのまま設定されるんじゃないか説浮上。

Windows の Don't Fragment 定数値

MSDNに記載あり。https://msdn.microsoft.com/ja-jp/library/windows/desktop/ms738586(v=vs.85).aspx

IP_DONT_FRAGMENTがそれっぽい。定義はWinsock2.hを見ろと。ふむふむ。

色々検索してサイトを渡り歩いていると以下のサイトに出会う。

なんか不穏なことが書いてあるけど、9か14を使えばいいのね。

ruby は ws2tcpip.h を使っている。

9か14を使えってのはわかったけど、どっち使うか。

ruby の github リポジトリを眺めてると ws2tcpip.h を使ってたので、14が正解。
https://github.com/ruby/ruby/blob/f150a381db5b51552b714e9a5893654cd056962c/include/ruby/win32.h#L42

setsockopt に Integer を直接入れてみる。

require 'socket'

s0 = TCPServer.open("", 12345)
p s0.setsockopt(:IP, 14, 0) # => 0

いけたっぽい?

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?