Skip to content

Commit

Permalink
Merge pull request #142 from daipom/excluded-port-ranges
Browse files Browse the repository at this point in the history
Consider excluded port ranges for Windows
  • Loading branch information
ashie committed Mar 14, 2023
2 parents 85d4dba + 81203fd commit cf8da8f
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 8 deletions.
30 changes: 25 additions & 5 deletions lib/serverengine/socket_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,10 @@ def self.generate_path
port = ENV['SERVERENGINE_SOCKETMANAGER_PORT']
return port.to_i if port

for port in get_dynamic_port_range
if `netstat -na | findstr "#{port}"`.length == 0
return port
end
end
excluded_port_ranges = get_excluded_port_ranges
get_dynamic_port_range
.reject { |port| excluded_port_ranges.any? { |range| range.cover?(port) } }
.find { |port| `netstat -na | findstr "#{port}"`.length == 0 }
else
base_dir = (ENV['SERVERENGINE_SOCKETMANAGER_SOCK_DIR'] || '/tmp')
File.join(base_dir, 'SERVERENGINE_SOCKETMANAGER_' + Time.now.utc.iso8601 + '_' + Process.pid.to_s)
Expand Down Expand Up @@ -203,6 +202,27 @@ def self.get_dynamic_port_range
return 49152..65535
end
end

def self.get_excluded_port_ranges
# Example output of netsh:
#
# Protocol tcp Port Exclusion Ranges
#
# Start Port End Port
# ---------- --------
# 2869 2869
# 49152 49251
# 50000 50059 *
# 57095 57194
#
# * - Administered port exclusions.
#
`netsh int ipv4 show excludedportrange tcp`
.force_encoding("ASCII-8BIT")
.lines
.map { |line| line.match(/\s*(\d+)\s*(\d+)[\s\*]*/) ? $1.to_i..$2.to_i : nil }
.compact
end
end
end

Expand Down
21 changes: 18 additions & 3 deletions spec/socket_manager_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'socket'
require 'rr'

describe ServerEngine::SocketManager do
include_context 'test server and worker'
Expand All @@ -21,9 +22,23 @@

if ServerEngine.windows?
context 'Server.generate_path' do
it 'returns socket path as port number' do
path = SocketManager::Server.generate_path
expect(path).to be_between(49152, 65535)
context 'with socket path as port number' do
it 'returns a port in the dynamic port range' do
path = SocketManager::Server.generate_path
expect(path).to be_between(49152, 65535)
end

it 'returns a port which is not excluded' do
excluded_port_ranges = [
49152..49251,
50000..50059,
]
RR.stub(SocketManager::Server).get_excluded_port_ranges { excluded_port_ranges }
path = SocketManager::Server.generate_path
excluded_port_ranges.each do |range|
expect(path).not_to be_between(range.first, range.last)
end
end
end

it 'can be changed via environment variable' do
Expand Down

0 comments on commit cf8da8f

Please sign in to comment.