net/server_epoll.lua
author Kim Alvefur <zash@zash.se>
Sat, 24 Feb 2018 13:46:16 +0100
changeset 8543 ba9fd886b34d
parent 8510 71ef6d509105
child 8544 8186114329d6
permissions -rw-r--r--
net.server_epoll: Call onconnect listener on first successful read or write
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
-- Prosody IM
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
-- Copyright (C) 2016 Kim Alvefur
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
--
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
-- This project is MIT/X11 licensed. Please see the
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
-- COPYING file in the source package for more information.
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
--
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
-- server_epoll
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
--  Server backend based on https://luarocks.org/modules/zash/lua-epoll
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
local t_sort = table.sort;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
local t_insert = table.insert;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
local t_remove = table.remove;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
local t_concat = table.concat;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    15
local setmetatable = setmetatable;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
local tostring = tostring;
7586
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
    17
local pcall = pcall;
7800
d0c32d86724f server_epoll: Flush and close all connections before quitting mainloop so no data is lost in buffers
Kim Alvefur <zash@zash.se>
parents: 7799
diff changeset
    18
local next = next;
7797
424bbbeb9257 server_epoll: Add closeall() method for closing all clients and servers
Kim Alvefur <zash@zash.se>
parents: 7740
diff changeset
    19
local pairs = pairs;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
local log = require "util.logger".init("server_epoll");
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
local epoll = require "epoll";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
local socket = require "socket";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
local luasec = require "ssl";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
local gettime = require "util.time".now;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    25
local createtable = require "util.table".create;
7740
f93b3083b46b net.server_epoll: Use _SOCKETINVALID from LuaSocket
Kim Alvefur <zash@zash.se>
parents: 7710
diff changeset
    26
local _SOCKETINVALID = socket._SOCKETINVALID or -1;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
7604
ce20546d7714 net.server_epoll: Make sure a recent LuaSocket is avaliable
Kim Alvefur <zash@zash.se>
parents: 7603
diff changeset
    28
assert(socket.tcp6 and socket.tcp4, "Incompatible LuaSocket version");
ce20546d7714 net.server_epoll: Make sure a recent LuaSocket is avaliable
Kim Alvefur <zash@zash.se>
parents: 7603
diff changeset
    29
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
local _ENV = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
7660
252823632401 net.server_epoll: Support for setting configuration parameters
Kim Alvefur <zash@zash.se>
parents: 7640
diff changeset
    32
local default_config = { __index = {
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
	read_timeout = 900;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    34
	write_timeout = 7;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    35
	tcp_backlog = 128;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    36
	accept_retry_interval = 10;
7563
785fa1138293 net.server_epoll: Continue reading after a slight delay if there is buffered data after a read
Kim Alvefur <zash@zash.se>
parents: 7562
diff changeset
    37
	read_retry_delay = 1e-06;
7602
afbda0bd9cfc net.server_epoll: Add separate timout for initial connection
Kim Alvefur <zash@zash.se>
parents: 7601
diff changeset
    38
	connect_timeout = 20;
7601
335b5ce06062 net.server_epoll: TLS handshake timeout
Kim Alvefur <zash@zash.se>
parents: 7600
diff changeset
    39
	handshake_timeout = 60;
7626
a1c040a5754f net.server_epoll: Make maximum wait time configurable
Kim Alvefur <zash@zash.se>
parents: 7609
diff changeset
    40
	max_wait = 86400;
7661
e14a124c4d73 net.server_epoll: Make minimum poll wait time configurable
Kim Alvefur <zash@zash.se>
parents: 7660
diff changeset
    41
	min_wait = 1e-06;
7660
252823632401 net.server_epoll: Support for setting configuration parameters
Kim Alvefur <zash@zash.se>
parents: 7640
diff changeset
    42
}};
252823632401 net.server_epoll: Support for setting configuration parameters
Kim Alvefur <zash@zash.se>
parents: 7640
diff changeset
    43
local cfg = default_config.__index;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
local fds = createtable(10, 0); -- FD -> conn
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
    46
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
    47
-- Timer and scheduling --
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
    48
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
local timers = {};
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    50
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    51
local function noop() end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    52
local function closetimer(t)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    53
	t[1] = 0;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    54
	t[2] = noop;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    55
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    56
7576
0f0a6febbc5a net.server_epoll: Add some comments
Kim Alvefur <zash@zash.se>
parents: 7567
diff changeset
    57
-- Set to true when timers have changed
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    58
local resort_timers = false;
7576
0f0a6febbc5a net.server_epoll: Add some comments
Kim Alvefur <zash@zash.se>
parents: 7567
diff changeset
    59
0f0a6febbc5a net.server_epoll: Add some comments
Kim Alvefur <zash@zash.se>
parents: 7567
diff changeset
    60
-- Add absolute timer
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    61
local function at(time, f)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    62
	local timer = { time, f, close = closetimer };
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    63
	t_insert(timers, timer);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    64
	resort_timers = true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    65
	return timer;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    66
end
7576
0f0a6febbc5a net.server_epoll: Add some comments
Kim Alvefur <zash@zash.se>
parents: 7567
diff changeset
    67
0f0a6febbc5a net.server_epoll: Add some comments
Kim Alvefur <zash@zash.se>
parents: 7567
diff changeset
    68
-- Add relative timer
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    69
local function addtimer(timeout, f)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    70
	return at(gettime() + timeout, f);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    71
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    72
7576
0f0a6febbc5a net.server_epoll: Add some comments
Kim Alvefur <zash@zash.se>
parents: 7567
diff changeset
    73
-- Run callbacks of expired timers
0f0a6febbc5a net.server_epoll: Add some comments
Kim Alvefur <zash@zash.se>
parents: 7567
diff changeset
    74
-- Return time until next timeout
7661
e14a124c4d73 net.server_epoll: Make minimum poll wait time configurable
Kim Alvefur <zash@zash.se>
parents: 7660
diff changeset
    75
local function runtimers(next_delay, min_wait)
7632
0fcde9869cc1 net.server_epoll: Return early in the event of zero timers
Kim Alvefur <zash@zash.se>
parents: 7631
diff changeset
    76
	-- Any timers at all?
0fcde9869cc1 net.server_epoll: Return early in the event of zero timers
Kim Alvefur <zash@zash.se>
parents: 7631
diff changeset
    77
	if not timers[1] then
0fcde9869cc1 net.server_epoll: Return early in the event of zero timers
Kim Alvefur <zash@zash.se>
parents: 7631
diff changeset
    78
		return next_delay;
0fcde9869cc1 net.server_epoll: Return early in the event of zero timers
Kim Alvefur <zash@zash.se>
parents: 7631
diff changeset
    79
	end
0fcde9869cc1 net.server_epoll: Return early in the event of zero timers
Kim Alvefur <zash@zash.se>
parents: 7631
diff changeset
    80
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    81
	if resort_timers then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    82
		-- Sort earliest timers to the end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    83
		t_sort(timers, function (a, b) return a[1] > b[1]; end);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    84
		resort_timers = false;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    85
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    86
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    87
	-- Iterate from the end and remove completed timers
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    88
	for i = #timers, 1, -1 do
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    89
		local timer = timers[i];
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    90
		local t, f = timer[1], timer[2];
7627
23fb3a084956 net.server_epoll: Comments
Kim Alvefur <zash@zash.se>
parents: 7626
diff changeset
    91
		-- Get time for every iteration to increase accuracy
23fb3a084956 net.server_epoll: Comments
Kim Alvefur <zash@zash.se>
parents: 7626
diff changeset
    92
		local now = gettime();
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    93
		if t > now then
7576
0f0a6febbc5a net.server_epoll: Add some comments
Kim Alvefur <zash@zash.se>
parents: 7567
diff changeset
    94
			-- This timer should not fire yet
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    95
			local diff = t - now;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    96
			if diff < next_delay then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    97
				next_delay = diff;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    98
			end
7561
3a2fe8e10eeb net.server_epoll: Fix calculation of next timer event
Kim Alvefur <zash@zash.se>
parents: 7560
diff changeset
    99
			break;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   100
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   101
		local new_timeout = f(now);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   102
		if new_timeout then
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   103
			-- Schedule for 'delay' from the time actually scheduled,
7627
23fb3a084956 net.server_epoll: Comments
Kim Alvefur <zash@zash.se>
parents: 7626
diff changeset
   104
			-- not from now, in order to prevent timer drift.
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   105
			timer[1] = t + new_timeout;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   106
			resort_timers = true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   107
		else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   108
			t_remove(timers, i);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   109
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   110
	end
7661
e14a124c4d73 net.server_epoll: Make minimum poll wait time configurable
Kim Alvefur <zash@zash.se>
parents: 7660
diff changeset
   111
e14a124c4d73 net.server_epoll: Make minimum poll wait time configurable
Kim Alvefur <zash@zash.se>
parents: 7660
diff changeset
   112
	if resort_timers or next_delay < min_wait then
7561
3a2fe8e10eeb net.server_epoll: Fix calculation of next timer event
Kim Alvefur <zash@zash.se>
parents: 7560
diff changeset
   113
		-- Timers may be added from within a timer callback.
7576
0f0a6febbc5a net.server_epoll: Add some comments
Kim Alvefur <zash@zash.se>
parents: 7567
diff changeset
   114
		-- Those would not be considered for next_delay,
7561
3a2fe8e10eeb net.server_epoll: Fix calculation of next timer event
Kim Alvefur <zash@zash.se>
parents: 7560
diff changeset
   115
		-- and we might sleep for too long, so instead
3a2fe8e10eeb net.server_epoll: Fix calculation of next timer event
Kim Alvefur <zash@zash.se>
parents: 7560
diff changeset
   116
		-- we return a shorter timeout so we can
3a2fe8e10eeb net.server_epoll: Fix calculation of next timer event
Kim Alvefur <zash@zash.se>
parents: 7560
diff changeset
   117
		-- properly sort all new timers.
7661
e14a124c4d73 net.server_epoll: Make minimum poll wait time configurable
Kim Alvefur <zash@zash.se>
parents: 7660
diff changeset
   118
		next_delay = min_wait;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   119
	end
7661
e14a124c4d73 net.server_epoll: Make minimum poll wait time configurable
Kim Alvefur <zash@zash.se>
parents: 7660
diff changeset
   120
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   121
	return next_delay;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   122
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   123
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   124
-- Socket handler interface
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   125
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   126
local interface = {};
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   127
local interface_mt = { __index = interface };
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   128
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   129
function interface_mt:__tostring()
7588
b64218c816de net.server_epoll: Improve string representation of connections
Kim Alvefur <zash@zash.se>
parents: 7587
diff changeset
   130
	if self.sockname and self.peername then
b64218c816de net.server_epoll: Improve string representation of connections
Kim Alvefur <zash@zash.se>
parents: 7587
diff changeset
   131
		return ("FD %d (%s, %d, %s, %d)"):format(self:getfd(), self.peername, self.peerport, self.sockname, self.sockport);
b64218c816de net.server_epoll: Improve string representation of connections
Kim Alvefur <zash@zash.se>
parents: 7587
diff changeset
   132
	elseif self.sockname or self.peername then
b64218c816de net.server_epoll: Improve string representation of connections
Kim Alvefur <zash@zash.se>
parents: 7587
diff changeset
   133
		return ("FD %d (%s, %d)"):format(self:getfd(), self.sockname or self.peername, self.sockport or self.peerport);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   134
	end
7588
b64218c816de net.server_epoll: Improve string representation of connections
Kim Alvefur <zash@zash.se>
parents: 7587
diff changeset
   135
	return ("%s FD %d"):format(tostring(self.conn), self:getfd());
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   136
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   137
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   138
-- Replace the listener and tell the old one
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   139
function interface:setlistener(listeners)
7607
36408ef6c8c9 net.server_epoll: Call ondetach when listeners are replaced
Kim Alvefur <zash@zash.se>
parents: 7606
diff changeset
   140
	self:on("detach");
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   141
	self.listeners = listeners;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   142
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   143
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   144
-- Call a listener callback
7586
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   145
function interface:on(what, ...)
8009
be374a5778f3 net.server_epoll: Log if there's a connection without listeners
Kim Alvefur <zash@zash.se>
parents: 7913
diff changeset
   146
	if not self.listeners then
be374a5778f3 net.server_epoll: Log if there's a connection without listeners
Kim Alvefur <zash@zash.se>
parents: 7913
diff changeset
   147
		log("error", "%s has no listeners", self);
be374a5778f3 net.server_epoll: Log if there's a connection without listeners
Kim Alvefur <zash@zash.se>
parents: 7913
diff changeset
   148
		return;
be374a5778f3 net.server_epoll: Log if there's a connection without listeners
Kim Alvefur <zash@zash.se>
parents: 7913
diff changeset
   149
	end
7586
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   150
	local listener = self.listeners["on"..what];
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   151
	if not listener then
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   152
		-- log("debug", "Missing listener 'on%s'", what); -- uncomment for development and debugging
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   153
		return;
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   154
	end
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   155
	local ok, err = pcall(listener, self, ...);
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   156
	if not ok then
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   157
		log("error", "Error calling on%s: %s", what, err);
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   158
	end
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   159
	return err;
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   160
end
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   161
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   162
-- Return the file descriptor number
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   163
function interface:getfd()
7589
846fdbbc62ba net.server_epoll: Return something as FD when no connection exists
Kim Alvefur <zash@zash.se>
parents: 7588
diff changeset
   164
	if self.conn then
846fdbbc62ba net.server_epoll: Return something as FD when no connection exists
Kim Alvefur <zash@zash.se>
parents: 7588
diff changeset
   165
		return self.conn:getfd();
846fdbbc62ba net.server_epoll: Return something as FD when no connection exists
Kim Alvefur <zash@zash.se>
parents: 7588
diff changeset
   166
	end
7740
f93b3083b46b net.server_epoll: Use _SOCKETINVALID from LuaSocket
Kim Alvefur <zash@zash.se>
parents: 7710
diff changeset
   167
	return _SOCKETINVALID;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   168
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   169
8274
c09deab9989e net.server_epoll: Add interface:server() method to match server_event (fixes c2s:show traceback in telnet console)
Kim Alvefur <zash@zash.se>
parents: 8094
diff changeset
   170
function interface:server()
c09deab9989e net.server_epoll: Add interface:server() method to match server_event (fixes c2s:show traceback in telnet console)
Kim Alvefur <zash@zash.se>
parents: 8094
diff changeset
   171
	return self._server or self;
c09deab9989e net.server_epoll: Add interface:server() method to match server_event (fixes c2s:show traceback in telnet console)
Kim Alvefur <zash@zash.se>
parents: 8094
diff changeset
   172
end
c09deab9989e net.server_epoll: Add interface:server() method to match server_event (fixes c2s:show traceback in telnet console)
Kim Alvefur <zash@zash.se>
parents: 8094
diff changeset
   173
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   174
-- Get IP address
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   175
function interface:ip()
7587
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   176
	return self.peername or self.sockname;
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   177
end
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   178
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   179
-- Get a port number, doesn't matter which
7587
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   180
function interface:port()
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   181
	return self.sockport or self.peerport;
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   182
end
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   183
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   184
-- Get local port number
7587
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   185
function interface:clientport()
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   186
	return self.sockport;
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   187
end
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   188
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   189
-- Get remote port
7587
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   190
function interface:serverport()
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   191
	if self.sockport then
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   192
		return self.sockport;
8274
c09deab9989e net.server_epoll: Add interface:server() method to match server_event (fixes c2s:show traceback in telnet console)
Kim Alvefur <zash@zash.se>
parents: 8094
diff changeset
   193
	elseif self._server then
c09deab9989e net.server_epoll: Add interface:server() method to match server_event (fixes c2s:show traceback in telnet console)
Kim Alvefur <zash@zash.se>
parents: 8094
diff changeset
   194
		self._server:port();
7587
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   195
	end
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   196
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   197
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   198
-- Return underlying socket
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   199
function interface:socket()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   200
	return self.conn;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   201
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   202
7913
91db637be237 net.server_epoll: Add method for changing read pattern
Kim Alvefur <zash@zash.se>
parents: 7820
diff changeset
   203
function interface:set_mode(new_mode)
91db637be237 net.server_epoll: Add method for changing read pattern
Kim Alvefur <zash@zash.se>
parents: 7820
diff changeset
   204
	self._pattern = new_mode;
91db637be237 net.server_epoll: Add method for changing read pattern
Kim Alvefur <zash@zash.se>
parents: 7820
diff changeset
   205
end
91db637be237 net.server_epoll: Add method for changing read pattern
Kim Alvefur <zash@zash.se>
parents: 7820
diff changeset
   206
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   207
function interface:setoption(k, v)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   208
	-- LuaSec doesn't expose setoption :(
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   209
	if self.conn.setoption then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   210
		self.conn:setoption(k, v);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   211
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   212
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   213
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   214
-- Timeout for detecting dead or idle sockets
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   215
function interface:setreadtimeout(t)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   216
	if t == false then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   217
		if self._readtimeout then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   218
			self._readtimeout:close();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   219
			self._readtimeout = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   220
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   221
		return
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   222
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   223
	t = t or cfg.read_timeout;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   224
	if self._readtimeout then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   225
		self._readtimeout[1] = gettime() + t;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   226
		resort_timers = true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   227
	else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   228
		self._readtimeout = addtimer(t, function ()
7586
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   229
			if self:on("readtimeout") then
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   230
				return cfg.read_timeout;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   231
			else
7586
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   232
				self:on("disconnect", "read timeout");
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   233
				self:destroy();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   234
			end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   235
		end);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   236
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   237
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   238
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   239
-- Timeout for detecting dead sockets
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   240
function interface:setwritetimeout(t)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   241
	if t == false then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   242
		if self._writetimeout then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   243
			self._writetimeout:close();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   244
			self._writetimeout = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   245
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   246
		return
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   247
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   248
	t = t or cfg.write_timeout;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   249
	if self._writetimeout then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   250
		self._writetimeout[1] = gettime() + t;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   251
		resort_timers = true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   252
	else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   253
		self._writetimeout = addtimer(t, function ()
7586
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   254
			self:on("disconnect", "write timeout");
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   255
			self:destroy();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   256
		end);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   257
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   258
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   259
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   260
-- lua-epoll flag for currently requested poll state
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   261
function interface:flags()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   262
	if self._wantread then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   263
		if self._wantwrite then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   264
			return "rw";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   265
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   266
		return "r";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   267
	elseif self._wantwrite then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   268
		return "w";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   269
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   270
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   271
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   272
-- Add or remove sockets or modify epoll flags
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   273
function interface:setflags(r, w)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   274
	if r ~= nil then self._wantread = r; end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   275
	if w ~= nil then self._wantwrite = w; end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   276
	local flags = self:flags();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   277
	local currentflags = self._flags;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   278
	if flags == currentflags then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   279
		return true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   280
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   281
	local fd = self:getfd();
7605
a4d5eec36a17 net.server_epoll: Prevent invalid FDs from being added to epoll
Kim Alvefur <zash@zash.se>
parents: 7604
diff changeset
   282
	if fd < 0 then
a4d5eec36a17 net.server_epoll: Prevent invalid FDs from being added to epoll
Kim Alvefur <zash@zash.se>
parents: 7604
diff changeset
   283
		self._wantread, self._wantwrite = nil, nil;
a4d5eec36a17 net.server_epoll: Prevent invalid FDs from being added to epoll
Kim Alvefur <zash@zash.se>
parents: 7604
diff changeset
   284
		return nil, "invalid fd";
a4d5eec36a17 net.server_epoll: Prevent invalid FDs from being added to epoll
Kim Alvefur <zash@zash.se>
parents: 7604
diff changeset
   285
	end
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   286
	local op = "mod";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   287
	if not flags then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   288
		op = "del";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   289
	elseif not currentflags then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   290
		op = "add";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   291
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   292
	local ok, err = epoll.ctl(op, fd, flags);
7590
ff81a34bffb0 net.server_epoll: Comment some overly verbose logging
Kim Alvefur <zash@zash.se>
parents: 7589
diff changeset
   293
--	log("debug", "epoll_ctl(%q, %d, %q) -> %s" .. (err and ", %q" or ""),
ff81a34bffb0 net.server_epoll: Comment some overly verbose logging
Kim Alvefur <zash@zash.se>
parents: 7589
diff changeset
   294
--		op, fd, flags or "", tostring(ok), err);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   295
	if not ok then return ok, err end
7628
6afafd6d4ef0 net.server_epoll: Move management of fd registry to :setflags
Kim Alvefur <zash@zash.se>
parents: 7627
diff changeset
   296
	if op == "add" then
6afafd6d4ef0 net.server_epoll: Move management of fd registry to :setflags
Kim Alvefur <zash@zash.se>
parents: 7627
diff changeset
   297
		fds[fd] = self;
6afafd6d4ef0 net.server_epoll: Move management of fd registry to :setflags
Kim Alvefur <zash@zash.se>
parents: 7627
diff changeset
   298
	elseif op == "del" then
6afafd6d4ef0 net.server_epoll: Move management of fd registry to :setflags
Kim Alvefur <zash@zash.se>
parents: 7627
diff changeset
   299
		fds[fd] = nil;
6afafd6d4ef0 net.server_epoll: Move management of fd registry to :setflags
Kim Alvefur <zash@zash.se>
parents: 7627
diff changeset
   300
	end
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   301
	self._flags = flags;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   302
	return true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   303
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   304
7576
0f0a6febbc5a net.server_epoll: Add some comments
Kim Alvefur <zash@zash.se>
parents: 7567
diff changeset
   305
-- Called when socket is readable
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   306
function interface:onreadable()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   307
	local data, err, partial = self.conn:receive(self._pattern);
7690
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   308
	if data then
8543
ba9fd886b34d net.server_epoll: Call onconnect listener on first successful read or write
Kim Alvefur <zash@zash.se>
parents: 8510
diff changeset
   309
		self:onconnect();
7690
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   310
		self:on("incoming", data);
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   311
	else
8543
ba9fd886b34d net.server_epoll: Call onconnect listener on first successful read or write
Kim Alvefur <zash@zash.se>
parents: 8510
diff changeset
   312
		if partial and partial ~= "" then
ba9fd886b34d net.server_epoll: Call onconnect listener on first successful read or write
Kim Alvefur <zash@zash.se>
parents: 8510
diff changeset
   313
			self:onconnect();
7690
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   314
			self:on("incoming", partial, err);
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   315
		end
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   316
		if err == "wantread" then
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   317
			self:setflags(true, nil);
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   318
		elseif err == "wantwrite" then
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   319
			self:setflags(nil, true);
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   320
		elseif err ~= "timeout" then
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   321
			self:on("disconnect", err);
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   322
			self:destroy()
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   323
			return;
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   324
		end
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   325
	end
7694
a5ad858f3a93 net.server_epoll: Check that connection still exists after callback, fixes traceback when closed
Kim Alvefur <zash@zash.se>
parents: 7690
diff changeset
   326
	if not self.conn then return; end
7609
f40f1d9b7872 net.server_epoll: Set timers before calling onincoming, fixes traceback if connection is closed before onincoming returns
Kim Alvefur <zash@zash.se>
parents: 7607
diff changeset
   327
	if self.conn:dirty() then
f40f1d9b7872 net.server_epoll: Set timers before calling onincoming, fixes traceback if connection is closed before onincoming returns
Kim Alvefur <zash@zash.se>
parents: 7607
diff changeset
   328
		self:setreadtimeout(false);
f40f1d9b7872 net.server_epoll: Set timers before calling onincoming, fixes traceback if connection is closed before onincoming returns
Kim Alvefur <zash@zash.se>
parents: 7607
diff changeset
   329
		self:pausefor(cfg.read_retry_delay);
f40f1d9b7872 net.server_epoll: Set timers before calling onincoming, fixes traceback if connection is closed before onincoming returns
Kim Alvefur <zash@zash.se>
parents: 7607
diff changeset
   330
	else
f40f1d9b7872 net.server_epoll: Set timers before calling onincoming, fixes traceback if connection is closed before onincoming returns
Kim Alvefur <zash@zash.se>
parents: 7607
diff changeset
   331
		self:setreadtimeout();
f40f1d9b7872 net.server_epoll: Set timers before calling onincoming, fixes traceback if connection is closed before onincoming returns
Kim Alvefur <zash@zash.se>
parents: 7607
diff changeset
   332
	end
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   333
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   334
7576
0f0a6febbc5a net.server_epoll: Add some comments
Kim Alvefur <zash@zash.se>
parents: 7567
diff changeset
   335
-- Called when socket is writable
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   336
function interface:onwriteable()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   337
	local buffer = self.writebuffer;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   338
	local data = t_concat(buffer);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   339
	local ok, err, partial = self.conn:send(data);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   340
	if ok then
8543
ba9fd886b34d net.server_epoll: Call onconnect listener on first successful read or write
Kim Alvefur <zash@zash.se>
parents: 8510
diff changeset
   341
		if data ~= "" then
ba9fd886b34d net.server_epoll: Call onconnect listener on first successful read or write
Kim Alvefur <zash@zash.se>
parents: 8510
diff changeset
   342
			for i = #buffer, 1, -1 do
ba9fd886b34d net.server_epoll: Call onconnect listener on first successful read or write
Kim Alvefur <zash@zash.se>
parents: 8510
diff changeset
   343
				buffer[i] = nil;
ba9fd886b34d net.server_epoll: Call onconnect listener on first successful read or write
Kim Alvefur <zash@zash.se>
parents: 8510
diff changeset
   344
			end
ba9fd886b34d net.server_epoll: Call onconnect listener on first successful read or write
Kim Alvefur <zash@zash.se>
parents: 8510
diff changeset
   345
			self:setflags(nil, false);
ba9fd886b34d net.server_epoll: Call onconnect listener on first successful read or write
Kim Alvefur <zash@zash.se>
parents: 8510
diff changeset
   346
			self:setwritetimeout(false);
ba9fd886b34d net.server_epoll: Call onconnect listener on first successful read or write
Kim Alvefur <zash@zash.se>
parents: 8510
diff changeset
   347
			self:ondrain(); -- Be aware of writes in ondrain
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   348
		end
8543
ba9fd886b34d net.server_epoll: Call onconnect listener on first successful read or write
Kim Alvefur <zash@zash.se>
parents: 8510
diff changeset
   349
		self:onconnect();
7592
125e4f2e0b65 net.server_epoll: Return early on successful write
Kim Alvefur <zash@zash.se>
parents: 7591
diff changeset
   350
		return;
8543
ba9fd886b34d net.server_epoll: Call onconnect listener on first successful read or write
Kim Alvefur <zash@zash.se>
parents: 8510
diff changeset
   351
	elseif partial then
7594
138f16eb39fb net.server_epoll: Improve syntax
Kim Alvefur <zash@zash.se>
parents: 7593
diff changeset
   352
		buffer[1] = data:sub(partial+1);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   353
		for i = #buffer, 2, -1 do
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   354
			buffer[i] = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   355
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   356
		self:setwritetimeout();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   357
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   358
	if err == "wantwrite" or err == "timeout" then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   359
		self:setflags(nil, true);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   360
	elseif err == "wantread" then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   361
		self:setflags(true, nil);
7690
ae24deae6488 net.server_epoll: Separate ok from err branch more
Kim Alvefur <zash@zash.se>
parents: 7661
diff changeset
   362
	elseif err ~= "timeout" then
7586
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   363
		self:on("disconnect", err);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   364
		self:destroy();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   365
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   366
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   367
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   368
-- The write buffer has been successfully emptied
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   369
function interface:ondrain()
8011
62ed3795be13 net.server_epoll: Attempt to simplify state control
Kim Alvefur <zash@zash.se>
parents: 8010
diff changeset
   370
	return self:on("drain");
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   371
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   372
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   373
-- Add data to write buffer and set flag for wanting to write
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   374
function interface:write(data)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   375
	local buffer = self.writebuffer;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   376
	if buffer then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   377
		t_insert(buffer, data);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   378
	else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   379
		self.writebuffer = { data };
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   380
	end
7553
8c2bc1b6d84a net.server_epoll: Remove last traces of code for bypassing buffering on writable sockets
Kim Alvefur <zash@zash.se>
parents: 7550
diff changeset
   381
	self:setwritetimeout();
8c2bc1b6d84a net.server_epoll: Remove last traces of code for bypassing buffering on writable sockets
Kim Alvefur <zash@zash.se>
parents: 7550
diff changeset
   382
	self:setflags(nil, true);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   383
	return #data;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   384
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   385
interface.send = interface.write;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   386
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   387
-- Close, possibly after writing is done
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   388
function interface:close()
8010
67f8954875a4 net.server_epoll: Check write buffer for remaining data to write when closing
Kim Alvefur <zash@zash.se>
parents: 8009
diff changeset
   389
	if self.writebuffer and self.writebuffer[1] then
7596
0266434d7df1 net.server_epoll: Prevent further writing after closing a socket
Kim Alvefur <zash@zash.se>
parents: 7595
diff changeset
   390
		self:setflags(false, true); -- Flush final buffer contents
0266434d7df1 net.server_epoll: Prevent further writing after closing a socket
Kim Alvefur <zash@zash.se>
parents: 7595
diff changeset
   391
		self.write, self.send = noop, noop; -- No more writing
7558
f3abb5f891eb net.server_epoll: Some logging when closing a connection
Kim Alvefur <zash@zash.se>
parents: 7557
diff changeset
   392
		log("debug", "Close %s after writing", tostring(self));
8011
62ed3795be13 net.server_epoll: Attempt to simplify state control
Kim Alvefur <zash@zash.se>
parents: 8010
diff changeset
   393
		self.ondrain = interface.close;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   394
	else
7595
10d2f008321d net.server_epoll: Additional logging of connects and TLS
Kim Alvefur <zash@zash.se>
parents: 7594
diff changeset
   395
		log("debug", "Close %s now", tostring(self));
7596
0266434d7df1 net.server_epoll: Prevent further writing after closing a socket
Kim Alvefur <zash@zash.se>
parents: 7595
diff changeset
   396
		self.write, self.send = noop, noop;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   397
		self.close = noop;
7586
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   398
		self:on("disconnect");
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   399
		self:destroy();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   400
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   401
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   402
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   403
function interface:destroy()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   404
	self:setflags(false, false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   405
	self:setwritetimeout(false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   406
	self:setreadtimeout(false);
7597
5e884501a9ac net.server_epoll: Prevent anything from happening to destroyed sockets
Kim Alvefur <zash@zash.se>
parents: 7596
diff changeset
   407
	self.onreadable = noop;
5e884501a9ac net.server_epoll: Prevent anything from happening to destroyed sockets
Kim Alvefur <zash@zash.se>
parents: 7596
diff changeset
   408
	self.onwriteable = noop;
5e884501a9ac net.server_epoll: Prevent anything from happening to destroyed sockets
Kim Alvefur <zash@zash.se>
parents: 7596
diff changeset
   409
	self.destroy = noop;
5e884501a9ac net.server_epoll: Prevent anything from happening to destroyed sockets
Kim Alvefur <zash@zash.se>
parents: 7596
diff changeset
   410
	self.close = noop;
5e884501a9ac net.server_epoll: Prevent anything from happening to destroyed sockets
Kim Alvefur <zash@zash.se>
parents: 7596
diff changeset
   411
	self.on = noop;
5e884501a9ac net.server_epoll: Prevent anything from happening to destroyed sockets
Kim Alvefur <zash@zash.se>
parents: 7596
diff changeset
   412
	self.conn:close();
5e884501a9ac net.server_epoll: Prevent anything from happening to destroyed sockets
Kim Alvefur <zash@zash.se>
parents: 7596
diff changeset
   413
	self.conn = nil;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   414
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   415
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   416
function interface:ssl()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   417
	return self._tls;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   418
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   419
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   420
function interface:starttls(ctx)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   421
	if ctx then self.tls = ctx; end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   422
	if self.writebuffer and self.writebuffer[1] then
7595
10d2f008321d net.server_epoll: Additional logging of connects and TLS
Kim Alvefur <zash@zash.se>
parents: 7594
diff changeset
   423
		log("debug", "Start TLS on %s after write", tostring(self));
8011
62ed3795be13 net.server_epoll: Attempt to simplify state control
Kim Alvefur <zash@zash.se>
parents: 8010
diff changeset
   424
		self.ondrain = interface.starttls;
62ed3795be13 net.server_epoll: Attempt to simplify state control
Kim Alvefur <zash@zash.se>
parents: 8010
diff changeset
   425
		self.starttls = false;
7606
4e2b019ff176 net.server_epoll: Make sure wantwrite is set when starting TLS
Kim Alvefur <zash@zash.se>
parents: 7605
diff changeset
   426
		self:setflags(nil, true); -- make sure wantwrite is set
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   427
	else
7595
10d2f008321d net.server_epoll: Additional logging of connects and TLS
Kim Alvefur <zash@zash.se>
parents: 7594
diff changeset
   428
		log("debug", "Start TLS on %s now", tostring(self));
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   429
		self:setflags(false, false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   430
		local conn, err = luasec.wrap(self.conn, ctx or self.tls);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   431
		if not conn then
7586
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   432
			self:on("disconnect", err);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   433
			self:destroy();
7598
166b2e0766a4 net.server_epoll: Return status from starttls method
Kim Alvefur <zash@zash.se>
parents: 7597
diff changeset
   434
			return conn, err;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   435
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   436
		conn:settimeout(0);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   437
		self.conn = conn;
8011
62ed3795be13 net.server_epoll: Attempt to simplify state control
Kim Alvefur <zash@zash.se>
parents: 8010
diff changeset
   438
		self.ondrain = nil;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   439
		self.onwriteable = interface.tlshandskake;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   440
		self.onreadable = interface.tlshandskake;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   441
		self:setflags(true, true);
7601
335b5ce06062 net.server_epoll: TLS handshake timeout
Kim Alvefur <zash@zash.se>
parents: 7600
diff changeset
   442
		self:setwritetimeout(cfg.handshake_timeout);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   443
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   444
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   445
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   446
function interface:tlshandskake()
7601
335b5ce06062 net.server_epoll: TLS handshake timeout
Kim Alvefur <zash@zash.se>
parents: 7600
diff changeset
   447
	self:setwritetimeout(false);
335b5ce06062 net.server_epoll: TLS handshake timeout
Kim Alvefur <zash@zash.se>
parents: 7600
diff changeset
   448
	self:setreadtimeout(false);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   449
	local ok, err = self.conn:dohandshake();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   450
	if ok then
7595
10d2f008321d net.server_epoll: Additional logging of connects and TLS
Kim Alvefur <zash@zash.se>
parents: 7594
diff changeset
   451
		log("debug", "TLS handshake on %s complete", tostring(self));
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   452
		self.onwriteable = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   453
		self.onreadable = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   454
		self._tls = true;
8011
62ed3795be13 net.server_epoll: Attempt to simplify state control
Kim Alvefur <zash@zash.se>
parents: 8010
diff changeset
   455
		self:on("status", "ssl-handshake-complete");
62ed3795be13 net.server_epoll: Attempt to simplify state control
Kim Alvefur <zash@zash.se>
parents: 8010
diff changeset
   456
		self:init();
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   457
	elseif err == "wantread" then
7595
10d2f008321d net.server_epoll: Additional logging of connects and TLS
Kim Alvefur <zash@zash.se>
parents: 7594
diff changeset
   458
		log("debug", "TLS handshake on %s to wait until readable", tostring(self));
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   459
		self:setflags(true, false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   460
		self:setreadtimeout(cfg.handshake_timeout);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   461
	elseif err == "wantwrite" then
7595
10d2f008321d net.server_epoll: Additional logging of connects and TLS
Kim Alvefur <zash@zash.se>
parents: 7594
diff changeset
   462
		log("debug", "TLS handshake on %s to wait until writable", tostring(self));
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   463
		self:setflags(false, true);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   464
		self:setwritetimeout(cfg.handshake_timeout);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   465
	else
7595
10d2f008321d net.server_epoll: Additional logging of connects and TLS
Kim Alvefur <zash@zash.se>
parents: 7594
diff changeset
   466
		log("debug", "TLS handshake error on %s: %s", tostring(self), err);
7586
0498daffa6f0 net.server_epoll: Call callbacks through common method in protected mode
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
   467
		self:on("disconnect", err);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   468
		self:destroy();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   469
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   470
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   471
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   472
local function wrapsocket(client, server, pattern, listeners, tls) -- luasocket object -> interface object
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   473
	client:settimeout(0);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   474
	local conn = setmetatable({
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   475
		conn = client;
8274
c09deab9989e net.server_epoll: Add interface:server() method to match server_event (fixes c2s:show traceback in telnet console)
Kim Alvefur <zash@zash.se>
parents: 8094
diff changeset
   476
		_server = server;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   477
		created = gettime();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   478
		listeners = listeners;
7814
24f99d11b792 net.server_epoll: Fix traceback if wrapclient called without a pattern or parent server
Kim Alvefur <zash@zash.se>
parents: 7803
diff changeset
   479
		_pattern = pattern or (server and server._pattern);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   480
		writebuffer = {};
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   481
		tls = tls;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   482
	}, interface_mt);
7594
138f16eb39fb net.server_epoll: Improve syntax
Kim Alvefur <zash@zash.se>
parents: 7593
diff changeset
   483
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   484
	if client.getpeername then
7587
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   485
		conn.peername, conn.peerport = client:getpeername();
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   486
	end
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   487
	if client.getsockname then
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   488
		conn.sockname, conn.sockport = client:getsockname();
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   489
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   490
	return conn;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   491
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   492
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   493
-- A server interface has new incoming connections waiting
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   494
-- This replaces the onreadable callback
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   495
function interface:onacceptable()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   496
	local conn, err = self.conn:accept();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   497
	if not conn then
7577
97b8506118a9 net.server_epoll: Fix missing quotes in logging call
Kim Alvefur <zash@zash.se>
parents: 7576
diff changeset
   498
		log("debug", "Error accepting new client: %s, server will be paused for %ds", err, cfg.accept_retry_interval);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   499
		self:pausefor(cfg.accept_retry_interval);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   500
		return;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   501
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   502
	local client = wrapsocket(conn, self, nil, self.listeners, self.tls);
7595
10d2f008321d net.server_epoll: Additional logging of connects and TLS
Kim Alvefur <zash@zash.se>
parents: 7594
diff changeset
   503
	log("debug", "New connection %s", tostring(client));
7600
cd34aa6b1632 net.server_epoll: Refactor to use common initialization
Kim Alvefur <zash@zash.se>
parents: 7599
diff changeset
   504
	client:init();
cd34aa6b1632 net.server_epoll: Refactor to use common initialization
Kim Alvefur <zash@zash.se>
parents: 7599
diff changeset
   505
end
cd34aa6b1632 net.server_epoll: Refactor to use common initialization
Kim Alvefur <zash@zash.se>
parents: 7599
diff changeset
   506
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   507
-- Initialization
7600
cd34aa6b1632 net.server_epoll: Refactor to use common initialization
Kim Alvefur <zash@zash.se>
parents: 7599
diff changeset
   508
function interface:init()
cd34aa6b1632 net.server_epoll: Refactor to use common initialization
Kim Alvefur <zash@zash.se>
parents: 7599
diff changeset
   509
	if self.tls and not self._tls then
cd34aa6b1632 net.server_epoll: Refactor to use common initialization
Kim Alvefur <zash@zash.se>
parents: 7599
diff changeset
   510
		return self:starttls();
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   511
	else
7629
e56343d50293 net.server_epoll: Tailcalls
Kim Alvefur <zash@zash.se>
parents: 7628
diff changeset
   512
		self:setwritetimeout();
8509
174fd716c9fa server_epoll: Rework how socket readyness is detected
Kim Alvefur <zash@zash.se>
parents: 8274
diff changeset
   513
		return self:setflags(true, true);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   514
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   515
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   516
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   517
function interface:pause()
7629
e56343d50293 net.server_epoll: Tailcalls
Kim Alvefur <zash@zash.se>
parents: 7628
diff changeset
   518
	return self:setflags(false);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   519
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   520
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   521
function interface:resume()
7629
e56343d50293 net.server_epoll: Tailcalls
Kim Alvefur <zash@zash.se>
parents: 7628
diff changeset
   522
	return self:setflags(true);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   523
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   524
7627
23fb3a084956 net.server_epoll: Comments
Kim Alvefur <zash@zash.se>
parents: 7626
diff changeset
   525
-- Pause connection for some time
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   526
function interface:pausefor(t)
7562
b1b27dedf4cf net.server_epoll: Replace any previous pausefor timer
Kim Alvefur <zash@zash.se>
parents: 7561
diff changeset
   527
	if self._pausefor then
b1b27dedf4cf net.server_epoll: Replace any previous pausefor timer
Kim Alvefur <zash@zash.se>
parents: 7561
diff changeset
   528
		self._pausefor:close();
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   529
	end
7562
b1b27dedf4cf net.server_epoll: Replace any previous pausefor timer
Kim Alvefur <zash@zash.se>
parents: 7561
diff changeset
   530
	if t == false then return; end
b1b27dedf4cf net.server_epoll: Replace any previous pausefor timer
Kim Alvefur <zash@zash.se>
parents: 7561
diff changeset
   531
	self:setflags(false);
b1b27dedf4cf net.server_epoll: Replace any previous pausefor timer
Kim Alvefur <zash@zash.se>
parents: 7561
diff changeset
   532
	self._pausefor = addtimer(t, function ()
b1b27dedf4cf net.server_epoll: Replace any previous pausefor timer
Kim Alvefur <zash@zash.se>
parents: 7561
diff changeset
   533
		self._pausefor = nil;
7710
7bb1cc7278b6 net.server_epoll: Make sure socket exists before checking if there is buffered data in it
Kim Alvefur <zash@zash.se>
parents: 7694
diff changeset
   534
		if self.conn and self.conn:dirty() then
7563
785fa1138293 net.server_epoll: Continue reading after a slight delay if there is buffered data after a read
Kim Alvefur <zash@zash.se>
parents: 7562
diff changeset
   535
			self:onreadable();
785fa1138293 net.server_epoll: Continue reading after a slight delay if there is buffered data after a read
Kim Alvefur <zash@zash.se>
parents: 7562
diff changeset
   536
		end
7631
7f2159eac697 net.server_epoll: Fix timer returning boolean
Kim Alvefur <zash@zash.se>
parents: 7630
diff changeset
   537
		self:setflags(true);
7562
b1b27dedf4cf net.server_epoll: Replace any previous pausefor timer
Kim Alvefur <zash@zash.se>
parents: 7561
diff changeset
   538
	end);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   539
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   540
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   541
-- Connected!
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   542
function interface:onconnect()
8543
ba9fd886b34d net.server_epoll: Call onconnect listener on first successful read or write
Kim Alvefur <zash@zash.se>
parents: 8510
diff changeset
   543
	self.onconnect = noop;
ba9fd886b34d net.server_epoll: Call onconnect listener on first successful read or write
Kim Alvefur <zash@zash.se>
parents: 8510
diff changeset
   544
	self:on("connect");
8509
174fd716c9fa server_epoll: Rework how socket readyness is detected
Kim Alvefur <zash@zash.se>
parents: 8274
diff changeset
   545
end
174fd716c9fa server_epoll: Rework how socket readyness is detected
Kim Alvefur <zash@zash.se>
parents: 8274
diff changeset
   546
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   547
local function addserver(addr, port, listeners, pattern, tls)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   548
	local conn, err = socket.bind(addr, port, cfg.tcp_backlog);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   549
	if not conn then return conn, err; end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   550
	conn:settimeout(0);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   551
	local server = setmetatable({
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   552
		conn = conn;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   553
		created = gettime();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   554
		listeners = listeners;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   555
		_pattern = pattern;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   556
		onreadable = interface.onacceptable;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   557
		tls = tls;
7587
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   558
		sockname = addr;
98ee3ed105cf net.server_epoll: Collect and expose local and remote address and ports
Kim Alvefur <zash@zash.se>
parents: 7586
diff changeset
   559
		sockport = port;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   560
	}, interface_mt);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   561
	server:setflags(true, false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   562
	return server;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   563
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   564
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   565
-- COMPAT
7554
838212918f11 net.server_epoll: Rename arguments and varibles for consistensy
Kim Alvefur <zash@zash.se>
parents: 7553
diff changeset
   566
local function wrapclient(conn, addr, port, listeners, pattern, tls)
7600
cd34aa6b1632 net.server_epoll: Refactor to use common initialization
Kim Alvefur <zash@zash.se>
parents: 7599
diff changeset
   567
	local client = wrapsocket(conn, nil, pattern, listeners, tls);
cd34aa6b1632 net.server_epoll: Refactor to use common initialization
Kim Alvefur <zash@zash.se>
parents: 7599
diff changeset
   568
	if not client.peername then
cd34aa6b1632 net.server_epoll: Refactor to use common initialization
Kim Alvefur <zash@zash.se>
parents: 7599
diff changeset
   569
		client.peername, client.peerport = addr, port;
cd34aa6b1632 net.server_epoll: Refactor to use common initialization
Kim Alvefur <zash@zash.se>
parents: 7599
diff changeset
   570
	end
cd34aa6b1632 net.server_epoll: Refactor to use common initialization
Kim Alvefur <zash@zash.se>
parents: 7599
diff changeset
   571
	client:init();
7554
838212918f11 net.server_epoll: Rename arguments and varibles for consistensy
Kim Alvefur <zash@zash.se>
parents: 7553
diff changeset
   572
	return client;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   573
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   574
7803
dadf9ba290c5 server_epoll: Add some comments describing some functions
Kim Alvefur <zash@zash.se>
parents: 7802
diff changeset
   575
-- New outgoing TCP connection
7556
4f3e4a092348 net.server_epoll: Make addclient use wrapclient
Kim Alvefur <zash@zash.se>
parents: 7555
diff changeset
   576
local function addclient(addr, port, listeners, pattern, tls)
7599
2c4ba55b616c net.server_epoll: Connect async in addclient
Kim Alvefur <zash@zash.se>
parents: 7598
diff changeset
   577
	local conn, err = socket.tcp();
7556
4f3e4a092348 net.server_epoll: Make addclient use wrapclient
Kim Alvefur <zash@zash.se>
parents: 7555
diff changeset
   578
	if not conn then return conn, err; end
4f3e4a092348 net.server_epoll: Make addclient use wrapclient
Kim Alvefur <zash@zash.se>
parents: 7555
diff changeset
   579
	conn:settimeout(0);
7599
2c4ba55b616c net.server_epoll: Connect async in addclient
Kim Alvefur <zash@zash.se>
parents: 7598
diff changeset
   580
	conn:connect(addr, port);
7600
cd34aa6b1632 net.server_epoll: Refactor to use common initialization
Kim Alvefur <zash@zash.se>
parents: 7599
diff changeset
   581
	local client = wrapsocket(conn, nil, pattern, listeners, tls)
cd34aa6b1632 net.server_epoll: Refactor to use common initialization
Kim Alvefur <zash@zash.se>
parents: 7599
diff changeset
   582
	client:init();
7559
1f777b38b66c net.server_epoll: Make addclient conform to API (expected by net.http.request)
Kim Alvefur <zash@zash.se>
parents: 7558
diff changeset
   583
	return client, conn;
7556
4f3e4a092348 net.server_epoll: Make addclient use wrapclient
Kim Alvefur <zash@zash.se>
parents: 7555
diff changeset
   584
end
4f3e4a092348 net.server_epoll: Make addclient use wrapclient
Kim Alvefur <zash@zash.se>
parents: 7555
diff changeset
   585
7803
dadf9ba290c5 server_epoll: Add some comments describing some functions
Kim Alvefur <zash@zash.se>
parents: 7802
diff changeset
   586
-- Dump all data from one connection into another
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   587
local function link(from, to)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   588
	from.listeners = setmetatable({
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   589
		onincoming = function (_, data)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   590
			from:pause();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   591
			to:write(data);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   592
		end,
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   593
	}, {__index=from.listeners});
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   594
	to.listeners = setmetatable({
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   595
		ondrain = function ()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   596
			from:resume();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   597
		end,
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   598
	}, {__index=to.listeners});
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   599
	from:setflags(true, nil);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   600
	to:setflags(nil, true);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   601
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   602
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   603
-- XXX What uses this?
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   604
-- net.adns
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   605
function interface:set_send(new_send)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   606
	self.send = new_send;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   607
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   608
7803
dadf9ba290c5 server_epoll: Add some comments describing some functions
Kim Alvefur <zash@zash.se>
parents: 7802
diff changeset
   609
-- Close all connections and servers
7797
424bbbeb9257 server_epoll: Add closeall() method for closing all clients and servers
Kim Alvefur <zash@zash.se>
parents: 7740
diff changeset
   610
local function closeall()
7802
93643a61858a server_epoll: Ignore unused loop variable [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7800
diff changeset
   611
	for fd, conn in pairs(fds) do -- luacheck: ignore 213/fd
7797
424bbbeb9257 server_epoll: Add closeall() method for closing all clients and servers
Kim Alvefur <zash@zash.se>
parents: 7740
diff changeset
   612
		conn:close();
424bbbeb9257 server_epoll: Add closeall() method for closing all clients and servers
Kim Alvefur <zash@zash.se>
parents: 7740
diff changeset
   613
	end
424bbbeb9257 server_epoll: Add closeall() method for closing all clients and servers
Kim Alvefur <zash@zash.se>
parents: 7740
diff changeset
   614
end
424bbbeb9257 server_epoll: Add closeall() method for closing all clients and servers
Kim Alvefur <zash@zash.se>
parents: 7740
diff changeset
   615
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   616
local quitting = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   617
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   618
-- Signal main loop about shutdown via above upvalue
7799
12609aee3b3b server_epoll: Handle the argument to setquitting like server_select
Kim Alvefur <zash@zash.se>
parents: 7798
diff changeset
   619
local function setquitting(quit)
12609aee3b3b server_epoll: Handle the argument to setquitting like server_select
Kim Alvefur <zash@zash.se>
parents: 7798
diff changeset
   620
	if quit then
12609aee3b3b server_epoll: Handle the argument to setquitting like server_select
Kim Alvefur <zash@zash.se>
parents: 7798
diff changeset
   621
		quitting = "quitting";
7800
d0c32d86724f server_epoll: Flush and close all connections before quitting mainloop so no data is lost in buffers
Kim Alvefur <zash@zash.se>
parents: 7799
diff changeset
   622
		closeall();
7799
12609aee3b3b server_epoll: Handle the argument to setquitting like server_select
Kim Alvefur <zash@zash.se>
parents: 7798
diff changeset
   623
	else
12609aee3b3b server_epoll: Handle the argument to setquitting like server_select
Kim Alvefur <zash@zash.se>
parents: 7798
diff changeset
   624
		quitting = nil;
12609aee3b3b server_epoll: Handle the argument to setquitting like server_select
Kim Alvefur <zash@zash.se>
parents: 7798
diff changeset
   625
	end
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   626
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   627
7640
cccea9136b2d net.server_epoll: More comments
Kim Alvefur <zash@zash.se>
parents: 7633
diff changeset
   628
-- Main loop
7798
03081bd5c5bb net.server_epoll: Add the 'once' argument to loop for parity with server_select
Kim Alvefur <zash@zash.se>
parents: 7797
diff changeset
   629
local function loop(once)
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   630
	repeat
7661
e14a124c4d73 net.server_epoll: Make minimum poll wait time configurable
Kim Alvefur <zash@zash.se>
parents: 7660
diff changeset
   631
		local t = runtimers(cfg.max_wait, cfg.min_wait);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   632
		local fd, r, w = epoll.wait(t);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   633
		if fd then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   634
			local conn = fds[fd];
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   635
			if conn then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   636
				if r then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   637
					conn:onreadable();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   638
				end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   639
				if w then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   640
					conn:onwriteable();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   641
				end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   642
			else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   643
				log("debug", "Removing unknown fd %d", fd);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   644
				epoll.ctl("del", fd);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   645
			end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   646
		elseif r ~= "timeout" then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   647
			log("debug", "epoll_wait error: %s", tostring(r));
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   648
		end
7800
d0c32d86724f server_epoll: Flush and close all connections before quitting mainloop so no data is lost in buffers
Kim Alvefur <zash@zash.se>
parents: 7799
diff changeset
   649
	until once or (quitting and next(fds) == nil);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   650
	return quitting;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   651
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   652
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   653
return {
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   654
	get_backend = function () return "epoll"; end;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   655
	addserver = addserver;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   656
	addclient = addclient;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   657
	add_task = addtimer;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   658
	at = at;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   659
	loop = loop;
7797
424bbbeb9257 server_epoll: Add closeall() method for closing all clients and servers
Kim Alvefur <zash@zash.se>
parents: 7740
diff changeset
   660
	closeall = closeall;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   661
	setquitting = setquitting;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   662
	wrapclient = wrapclient;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   663
	link = link;
7660
252823632401 net.server_epoll: Support for setting configuration parameters
Kim Alvefur <zash@zash.se>
parents: 7640
diff changeset
   664
	set_config = function (newconfig)
252823632401 net.server_epoll: Support for setting configuration parameters
Kim Alvefur <zash@zash.se>
parents: 7640
diff changeset
   665
		cfg = setmetatable(newconfig, default_config);
252823632401 net.server_epoll: Support for setting configuration parameters
Kim Alvefur <zash@zash.se>
parents: 7640
diff changeset
   666
	end;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   667
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   668
	-- libevent emulation
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   669
	event = { EV_READ = "r", EV_WRITE = "w", EV_READWRITE = "rw", EV_LEAVE = -1 };
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   670
	addevent = function (fd, mode, callback)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   671
		local function onevent(self)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   672
			local ret = self:callback();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   673
			if ret == -1 then
7820
4e3654031693 net.server_epoll: Reuse interface metatable for event compat layer
Kim Alvefur <zash@zash.se>
parents: 7814
diff changeset
   674
				self:setflags(false, false);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   675
			elseif ret then
7820
4e3654031693 net.server_epoll: Reuse interface metatable for event compat layer
Kim Alvefur <zash@zash.se>
parents: 7814
diff changeset
   676
				self:setflags(mode == "r" or mode == "rw", mode == "w" or mode == "rw");
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   677
			end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   678
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   679
7820
4e3654031693 net.server_epoll: Reuse interface metatable for event compat layer
Kim Alvefur <zash@zash.se>
parents: 7814
diff changeset
   680
		local conn = setmetatable({
4e3654031693 net.server_epoll: Reuse interface metatable for event compat layer
Kim Alvefur <zash@zash.se>
parents: 7814
diff changeset
   681
			getfd = function () return fd; end;
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   682
			callback = callback;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   683
			onreadable = onevent;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   684
			onwriteable = onevent;
7820
4e3654031693 net.server_epoll: Reuse interface metatable for event compat layer
Kim Alvefur <zash@zash.se>
parents: 7814
diff changeset
   685
			close = function (self)
4e3654031693 net.server_epoll: Reuse interface metatable for event compat layer
Kim Alvefur <zash@zash.se>
parents: 7814
diff changeset
   686
				self:setflags(false, false);
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   687
				fds[fd] = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   688
			end;
7820
4e3654031693 net.server_epoll: Reuse interface metatable for event compat layer
Kim Alvefur <zash@zash.se>
parents: 7814
diff changeset
   689
		}, interface_mt);
4e3654031693 net.server_epoll: Reuse interface metatable for event compat layer
Kim Alvefur <zash@zash.se>
parents: 7814
diff changeset
   690
		local ok, err = conn:setflags(mode == "r" or mode == "rw", mode == "w" or mode == "rw");
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   691
		if not ok then return ok, err; end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   692
		return conn;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   693
	end;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   694
};