Last active
January 17, 2023 01:20
-
-
Save rickhull/d027f4d620d2efdc160af91d6560da0d to your computer and use it in GitHub Desktop.
What are the available Unix Socket types in Ruby (on Linux)?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
best [:SOCK_STREAM, :SOCK_DGRAM, :SOCK_SEQPACKET] | |
:SOCK_STREAM TYPE SOCK_STREAM | |
:SOCK_DGRAM TYPE SOCK_DGRAM | |
:SOCK_SEQPACKET TYPE SOCK_SEQPACKET | |
other [nil, :SOCK_RAW] | |
nil TYPE SOCK_STREAM | |
:SOCK_RAW TYPE SOCK_DGRAM | |
unsupported [:SOCK_RDM, :SOCK_PACKET, :SOCK_NONBLOCK, :SOCK_CLOEXEC] | |
:SOCK_RDM Errno::ESOCKTNOSUPPORT | |
:SOCK_PACKET Errno::ESOCKTNOSUPPORT | |
:SOCK_NONBLOCK Errno::ESOCKTNOSUPPORT | |
:SOCK_CLOEXEC Errno::ESOCKTNOSUPPORT | |
invalid [:RAW_SOCK] | |
:RAW_SOCK SocketError | |
1 DEBUG 0 | |
2 REUSEADDR 0 | |
3 TYPE SOCK_STREAM | |
4 ERROR Success (0) | |
5 DONTROUTE 0 | |
6 BROADCAST 0 | |
7 SNDBUF 212992 | |
8 RCVBUF 212992 | |
9 KEEPALIVE 0 | |
10 OOBINLINE 0 | |
11 NO_CHECK "\x00\x00\x00\x00" | |
12 PRIORITY "\x00\x00\x00\x00" | |
13 LINGER off 0sec | |
14 optname:14 "\x00\x00\x00\x00" | |
15 REUSEPORT "\x00\x00\x00\x00" | |
16 PASSCRED "\x00\x00\x00\x00" | |
17 PEERCRED pid=143083 euid=1000 egid=100 (ucred) | |
18 RCVLOWAT 1 | |
19 SNDLOWAT 1 | |
20 RCVTIMEO 0.000000sec | |
21 SNDTIMEO 0.000000sec | |
25 BINDTODEVICE "" | |
26 ATTACH_FILTER "" | |
29 TIMESTAMP "\x00\x00\x00\x00" | |
30 ACCEPTCONN 0 | |
31 PEERSEC "kernel\x00" | |
34 PASSSEC "\x00\x00\x00\x00" | |
35 TIMESTAMPNS "\x00\x00\x00\x00" | |
36 MARK "\x00\x00\x00\x00" | |
37 TIMESTAMPING "\x00\x00\x00\x00\x00\x00\x00\x00" | |
38 PROTOCOL "\x00\x00\x00\x00" | |
39 DOMAIN "\x01\x00\x00\x00" | |
40 RXQ_OVFL "\x00\x00\x00\x00" | |
41 WIFI_STATUS "\x00\x00\x00\x00" | |
42 PEEK_OFF "\xFF\xFF\xFF\xFF" | |
43 NOFCS "\x00\x00\x00\x00" | |
44 LOCK_FILTER "\x00\x00\x00\x00" | |
45 SELECT_ERR_QUEUE "\x00\x00\x00\x00" | |
46 BUSY_POLL "\x00\x00\x00\x00" | |
47 MAX_PACING_RATE "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" | |
48 BPF_EXTENSIONS "@\x00\x00\x00" | |
49 optname:49 "\xFF\xFF\xFF\xFF" | |
55 optname:55 "\x00\x00\x00\x00\x00@\x03\x00\x00\x00\x00\x00\x00@\x03\x00\x00\x00\x00\x00\x00\x00\x00 | |
56 optname:56 "\x00\x00\x00\x00" | |
57 optname:57 "2\x10\x00\x00\x00\x00\x00\x00" | |
59 optname:59 "\x01\x00\x00\x00d\x00\x00\x00\xE3\x03\x00\x00" | |
60 optname:60 "\x00\x00\x00\x00" | |
61 optname:61 "\x00\x00\x00\x00\x00\x00\x00\x00" | |
62 optname:62 "\x00\x00\x00\x00" | |
63 optname:63 "\x00\x00\x00\x00" | |
64 optname:64 "\x00\x00\x00\x00" | |
66 optname:66 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" | |
67 optname:67 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" | |
69 optname:69 "\x00\x00\x00\x00" | |
72 optname:72 "\x00\x00\x00\x00" | |
check DGRAM sockopts against RAW sockopts | |
value mismatch: [57]: "optname:57 \"3\\x10\\x00\\x00\\x00\\x00\\x00\\x00\"" "optname:57 \"5\\x10\\x00\\x00\\x00\\x00\\x00\\x00\"" | |
DONE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# NOTE: these are _Unix_ sockets, not network sockets | |
require 'socket' | |
# get the level 1 socket option for num | |
def get_opt sock, num | |
sock.getsockopt(1, num) | |
end | |
# a short readable string version of the socket option | |
def string_opt sock, num | |
get_opt(sock, num).inspect[30, 99].chop | |
end | |
# get the socket type, option number 3 | |
def get_type sock | |
string_opt sock, Socket::SO_TYPE # 3 | |
end | |
# return an array of strings | |
def brute_sockopts sock | |
ary = [] | |
99.times { |i| | |
begin | |
str = string_opt(sock, i) | |
rescue Errno::ENOPROTOOPT, Errno::EINVAL | |
next | |
end | |
ary[i] = str | |
} | |
ary | |
end | |
# man page for unix sockets: | |
# SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET | |
# let's try: | |
socktypes = { | |
best: [:SOCK_STREAM, :SOCK_DGRAM, :SOCK_SEQPACKET], | |
other: [nil, :SOCK_RAW], | |
unsupported: [:SOCK_RDM, :SOCK_PACKET, :SOCK_NONBLOCK, :SOCK_CLOEXEC], | |
invalid: [:RAW_SOCK], | |
} | |
socktypes.each { |group, types| | |
puts [group, types.inspect].join("\t") | |
types.each { |type| | |
if type.nil? | |
a, b = UNIXSocket.pair | |
else | |
begin | |
a, b = UNIXSocket.pair(type) | |
rescue StandardError => e | |
puts [type.inspect, e.class].join("\t") | |
next | |
end | |
end | |
puts [type.inspect, get_type(a)].join("\t") | |
a.close; b.close | |
} | |
puts | |
} | |
sock_stream, other_stream = UNIXSocket.pair(:SOCK_STREAM) | |
other_stream.close | |
opts_stream = brute_sockopts(sock_stream) | |
puts opts_stream.map.with_index { |val, idx| | |
val and [idx, val].join("\t") | |
}.compact.join("\n") | |
sock_dgram, other_dgram = UNIXSocket.pair(:DGRAM) | |
other_dgram.close | |
opts_dgram = brute_sockopts(sock_dgram) | |
sock_nil, other_nil = UNIXSocket.pair | |
other_nil.close | |
opts_nil = brute_sockopts(sock_nil) | |
sock_raw, other_raw = UNIXSocket.pair(:RAW) | |
other_raw.close | |
opts_raw = brute_sockopts(sock_raw) | |
puts | |
puts "check DGRAM sockopts against RAW sockopts" | |
opts_dgram.each.with_index { |val, idx| | |
other = opts_raw[idx] | |
if val.class != other.class | |
puts format("class mismatch: [%i]: %s %s", idx, val.class, other.class) | |
end | |
if val != other | |
puts format("value mismatch: [%i]: %s %s", idx, val.inspect, other.inspect) | |
end | |
} | |
puts "DONE" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment