Included Modules

Unicorn::SocketHelper

Constants

TCP_DEFER_ACCEPT

from /usr/include/linux/tcp.h

TCP_DEFER_ACCEPT_DEFAULT

The semantics for TCP_DEFER_ACCEPT changed in Linux 2.6.32+ with commit d1b99ba41d6c5aa1ed2fc634323449dd656899e9 This change shouldn’t affect Unicorn users behind nginx (a value of 1 remains an optimization), but Rainbows! users may want to use a higher value on Linux 2.6.32+ to protect against denial-of-service attacks

TCP_CORK

do not send out partial frames (Linux)

TCP_NOPUSH

do not send out partial frames (FreeBSD)

Public Class Methods

sock_name(sock) click to toggle source

Returns the configuration name of a socket as a string. sock may be a string value, in which case it is returned as-is Warning: TCP sockets may not always return the name given to it.

     # File lib/unicorn/socket_helper.rb, line 143
143:     def sock_name(sock)
144:       case sock
145:       when String then sock
146:       when UNIXServer
147:         Socket.unpack_sockaddr_un(sock.getsockname)
148:       when TCPServer
149:         Socket.unpack_sockaddr_in(sock.getsockname).reverse!.join(':')
150:       when Socket
151:         begin
152:           Socket.unpack_sockaddr_in(sock.getsockname).reverse!.join(':')
153:         rescue ArgumentError
154:           Socket.unpack_sockaddr_un(sock.getsockname)
155:         end
156:       else
157:         raise ArgumentError, "Unhandled class #{sock.class}: #{sock.inspect}"
158:       end
159:     end

Public Instance Methods

accf_arg(af_name) click to toggle source

struct accept_filter_arg {

  char af_name[16];
  char af_arg[240];

};

af_name is either “httpready” or “dataready”, though other filters may be supported by FreeBSD

    # File lib/unicorn/socket_helper.rb, line 43
43:         def accf_arg(af_name)
44:           [ af_name, nil ].pack('a16a240')
45:         end
bind_listen(address = '0.0.0.0:8080', opt = {}) click to toggle source

creates a new server, socket. address may be a HOST:PORT or an absolute path to a UNIX socket. address can even be a Socket object in which case it is immediately returned

     # File lib/unicorn/socket_helper.rb, line 110
110:     def bind_listen(address = '0.0.0.0:8080', opt = {})
111:       return address unless String === address
112: 
113:       sock = if address[0] == //
114:         if File.exist?(address)
115:           if File.socket?(address)
116:             if self.respond_to?(:logger)
117:               logger.info "unlinking existing socket=#{address}"
118:             end
119:             File.unlink(address)
120:           else
121:             raise ArgumentError,
122:                   "socket=#{address} specified but it is not a socket!"
123:           end
124:         end
125:         old_umask = File.umask(opt[:umask] || 0)
126:         begin
127:           UNIXServer.new(address)
128:         ensure
129:           File.umask(old_umask)
130:         end
131:       elsif address =~ /^(\d+\.\d+\.\d+\.\d+):(\d+)$/
132:         TCPServer.new($1, $2.to_i)
133:       else
134:         raise ArgumentError, "Don't know how to bind: #{address}"
135:       end
136:       set_server_sockopt(sock, opt)
137:       sock
138:     end
log_buffer_sizes(sock, pfx = '') click to toggle source
     # File lib/unicorn/socket_helper.rb, line 100
100:     def log_buffer_sizes(sock, pfx = '')
101:       respond_to?(:logger) or return
102:       rcvbuf = sock.getsockopt(SOL_SOCKET, SO_RCVBUF).unpack('i')
103:       sndbuf = sock.getsockopt(SOL_SOCKET, SO_SNDBUF).unpack('i')
104:       logger.info "#{pfx}#{sock_name(sock)} rcvbuf=#{rcvbuf} sndbuf=#{sndbuf}"
105:     end
server_cast(sock) click to toggle source

casts a given Socket to be a TCPServer or UNIXServer

     # File lib/unicorn/socket_helper.rb, line 164
164:     def server_cast(sock)
165:       begin
166:         Socket.unpack_sockaddr_in(sock.getsockname)
167:         TCPServer.for_fd(sock.fileno)
168:       rescue ArgumentError
169:         UNIXServer.for_fd(sock.fileno)
170:       end
171:     end
set_server_sockopt(sock, opt) click to toggle source
    # File lib/unicorn/socket_helper.rb, line 81
81:     def set_server_sockopt(sock, opt)
82:       opt ||= {}
83: 
84:       TCPSocket === sock and set_tcp_sockopt(sock, opt)
85: 
86:       if opt[:rcvbuf] || opt[:sndbuf]
87:         log_buffer_sizes(sock, "before: ")
88:         sock.setsockopt(SOL_SOCKET, SO_RCVBUF, opt[:rcvbuf]) if opt[:rcvbuf]
89:         sock.setsockopt(SOL_SOCKET, SO_SNDBUF, opt[:sndbuf]) if opt[:sndbuf]
90:         log_buffer_sizes(sock, " after: ")
91:       end
92:       sock.listen(opt[:backlog] || 1024)
93:       rescue => e
94:         if respond_to?(:logger)
95:           logger.error "error setting socket options: #{e.inspect}"
96:           logger.error e.backtrace.join("\n")
97:         end
98:     end
set_tcp_sockopt(sock, opt) click to toggle source
    # File lib/unicorn/socket_helper.rb, line 49
49:     def set_tcp_sockopt(sock, opt)
50: 
51:       # highly portable, but off by default because we don't do keepalive
52:       if defined?(TCP_NODELAY) && ! (val = opt[:tcp_nodelay]).nil?
53:         sock.setsockopt(IPPROTO_TCP, TCP_NODELAY, val ? 1 : 0)
54:       end
55: 
56:       unless (val = opt[:tcp_nopush]).nil?
57:         val = val ? 1 : 0
58:         if defined?(TCP_CORK) # Linux
59:           sock.setsockopt(IPPROTO_TCP, TCP_CORK, val)
60:         elsif defined?(TCP_NOPUSH) # TCP_NOPUSH is untested (FreeBSD)
61:           sock.setsockopt(IPPROTO_TCP, TCP_NOPUSH, val)
62:         end
63:       end
64: 
65:       # No good reason to ever have deferred accepts off
66:       # (except maybe benchmarking)
67:       if defined?(TCP_DEFER_ACCEPT)
68:         # this differs from nginx, since nginx doesn't allow us to
69:         # configure the the timeout...
70:         tmp = { :tcp_defer_accept => true }.update(opt)
71:         seconds = tmp[:tcp_defer_accept]
72:         seconds = TCP_DEFER_ACCEPT_DEFAULT if seconds == true
73:         seconds and sock.setsockopt(SOL_TCP, TCP_DEFER_ACCEPT, seconds)
74:       elsif defined?(SO_ACCEPTFILTER) && respond_to?(:accf_arg)
75:         tmp = { :accept_filter => 'httpready' }.update(opt)
76:         name = tmp[:accept_filter] and
77:           sock.setsockopt(SOL_SOCKET, SO_ACCEPTFILTER, accf_arg(name))
78:       end
79:     end

Private Instance Methods

sock_name(sock) click to toggle source

Returns the configuration name of a socket as a string. sock may be a string value, in which case it is returned as-is Warning: TCP sockets may not always return the name given to it.

     # File lib/unicorn/socket_helper.rb, line 143
143:     def sock_name(sock)
144:       case sock
145:       when String then sock
146:       when UNIXServer
147:         Socket.unpack_sockaddr_un(sock.getsockname)
148:       when TCPServer
149:         Socket.unpack_sockaddr_in(sock.getsockname).reverse!.join(':')
150:       when Socket
151:         begin
152:           Socket.unpack_sockaddr_in(sock.getsockname).reverse!.join(':')
153:         rescue ArgumentError
154:           Socket.unpack_sockaddr_un(sock.getsockname)
155:         end
156:       else
157:         raise ArgumentError, "Unhandled class #{sock.class}: #{sock.inspect}"
158:       end
159:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.