server.lua
author matthew@silver
Sun, 24 Aug 2008 18:01:20 +0100
changeset 5 57e4eb3aeac0
child 9 cb210ac67af8
permissions -rw-r--r--
Added all the files to please hg :/
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
     1
--[[
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
     2
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
     3
        server.lua by blastbeat
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
     4
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
     5
        - this script contains the server loop of the program
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
     6
        - other scripts can reg a server here
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
     7
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
     8
]]--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
     9
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    10
----------------------------------// DECLARATION //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    11
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    12
--// constants //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    13
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    14
local STAT_UNIT = 1 / ( 1024 * 1024 )    -- mb
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    15
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    16
--// lua functions //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    17
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    18
local function use( what ) return _G[ what ] end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    19
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    20
local type = use "type"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    21
local pairs = use "pairs"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    22
local ipairs = use "ipairs"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    23
local tostring = use "tostring"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    24
local collectgarbage = use "collectgarbage"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    25
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    26
--// lua libs //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    27
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    28
local table = use "table"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    29
local coroutine = use "coroutine"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    30
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    31
--// lua lib methods //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    32
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    33
local table_concat = table.concat
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    34
local table_remove = table.remove
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    35
local string_sub = use'string'.sub
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    36
local coroutine_wrap = coroutine.wrap
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    37
local coroutine_yield = coroutine.yield
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    38
local print = print;
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    39
local out_put = function () end --print;
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    40
local out_error = print;
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    41
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    42
--// extern libs //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    43
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    44
local luasec = require "ssl"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    45
local luasocket = require "socket"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    46
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    47
--// extern lib methods //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    48
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    49
local ssl_wrap = ( luasec and luasec.wrap )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    50
local socket_bind = luasocket.bind
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    51
local socket_select = luasocket.select
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    52
local ssl_newcontext = ( luasec and luasec.newcontext )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    53
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    54
--// functions //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    55
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    56
local loop
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    57
local stats
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    58
local addtimer
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    59
local closeall
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    60
local addserver
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    61
local firetimer
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    62
local closesocket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    63
local removesocket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    64
local wrapserver
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    65
local wraptcpclient
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    66
local wrapsslclient
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    67
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    68
--// tables //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    69
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    70
local listener
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    71
local readlist
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    72
local writelist
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    73
local socketlist
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    74
local timelistener
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    75
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    76
--// simple data types //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    77
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    78
local _
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    79
local readlen = 0    -- length of readlist
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    80
local writelen = 0    -- lenght of writelist
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    81
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    82
local sendstat= 0
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    83
local receivestat = 0
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    84
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    85
----------------------------------// DEFINITION //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    86
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    87
listener = { }    -- key = port, value = table
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    88
readlist = { }    -- array with sockets to read from
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    89
writelist = { }    -- arrary with sockets to write to
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    90
socketlist = { }    -- key = socket, value = wrapped socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    91
timelistener = { }
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    92
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    93
stats = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    94
    return receivestat, sendstat
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    95
end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    96
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    97
wrapserver = function( listener, socket, ip, serverport, mode, sslctx )    -- this function wraps a server
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    98
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
    99
    local dispatch, disconnect = listener.listener, listener.disconnect    -- dangerous
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   100
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   101
    local wrapclient, err
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   102
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   103
    if sslctx then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   104
        if not ssl_newcontext then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   105
            return nil, "luasec not found"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   106
--        elseif not cfg_get "use_ssl" then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   107
--            return nil, "ssl is deactivated"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   108
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   109
        if type( sslctx ) ~= "table" then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   110
            out_error "server.lua: wrong server sslctx"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   111
            return nil, "wrong server sslctx"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   112
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   113
        sslctx, err = ssl_newcontext( sslctx )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   114
        if not sslctx then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   115
            err = err or "wrong sslctx parameters"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   116
            out_error( "server.lua: ", err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   117
            return nil, err
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   118
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   119
        wrapclient = wrapsslclient
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   120
    else
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   121
        wrapclient = wraptcpclient
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   122
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   123
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   124
    local accept = socket.accept
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   125
    local close = socket.close
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   126
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   127
    --// public methods of the object //--    
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   128
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   129
    local handler = { }
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   130
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   131
    handler.shutdown = function( ) end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   132
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   133
    --[[handler.listener = function( data, err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   134
        return ondata( handler, data, err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   135
    end]]
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   136
    handler.ssl = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   137
        return sslctx and true or false
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   138
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   139
    handler.close = function( closed )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   140
        _ = not closed and close( socket )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   141
        writelen = removesocket( writelist, socket, writelen )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   142
        readlen = removesocket( readlist, socket, readlen )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   143
        socketlist[ socket ] = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   144
        handler = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   145
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   146
    handler.ip = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   147
        return ip
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   148
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   149
    handler.serverport = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   150
        return serverport
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   151
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   152
    handler.socket = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   153
        return socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   154
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   155
    handler.receivedata = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   156
        local client, err = accept( socket )    -- try to accept
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   157
        if client then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   158
            local ip, clientport = client:getpeername( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   159
            client:settimeout( 0 )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   160
            local handler, client, err = wrapclient( listener, client, ip, serverport, clientport, mode, sslctx )    -- wrap new client socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   161
            if err then    -- error while wrapping ssl socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   162
                return false
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   163
            end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   164
            out_put( "server.lua: accepted new client connection from ", ip, ":", clientport )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   165
            return dispatch( handler )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   166
        elseif err then    -- maybe timeout or something else
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   167
            out_put( "server.lua: error with new client connection: ", err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   168
            return false
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   169
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   170
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   171
    return handler
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   172
end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   173
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   174
wrapsslclient = function( listener, socket, ip, serverport, clientport, mode, sslctx )    -- this function wraps a ssl cleint
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   175
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   176
    local dispatch, disconnect = listener.listener, listener.disconnect
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   177
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   178
    --// transform socket to ssl object //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   179
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   180
    local err
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   181
    socket, err = ssl_wrap( socket, sslctx )    -- wrap socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   182
    if err then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   183
        out_put( "server.lua: ssl error: ", err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   184
        return nil, nil, err    -- fatal error
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   185
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   186
    socket:settimeout( 0 )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   187
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   188
    --// private closures of the object //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   189
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   190
    local writequeue = { }    -- buffer for messages to send
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   191
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   192
    local eol   -- end of buffer
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   193
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   194
    local sstat, rstat = 0, 0
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   195
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   196
    --// local import of socket methods //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   197
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   198
    local send = socket.send
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   199
    local receive = socket.receive
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   200
    local close = socket.close
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   201
    --local shutdown = socket.shutdown
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   202
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   203
    --// public methods of the object //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   204
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   205
    local handler = { }
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   206
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   207
    handler.getstats = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   208
        return rstat, sstat
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   209
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   210
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   211
    handler.listener = function( data, err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   212
        return listener( handler, data, err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   213
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   214
    handler.ssl = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   215
        return true
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   216
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   217
    handler.send = function( _, data, i, j )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   218
            return send( socket, data, i, j )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   219
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   220
    handler.receive = function( pattern, prefix )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   221
            return receive( socket, pattern, prefix )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   222
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   223
    handler.shutdown = function( pattern )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   224
        --return shutdown( socket, pattern )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   225
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   226
    handler.close = function( closed )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   227
        close( socket )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   228
        writelen = ( eol and removesocket( writelist, socket, writelen ) ) or writelen
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   229
        readlen = removesocket( readlist, socket, readlen )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   230
        socketlist[ socket ] = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   231
        out_put "server.lua: closed handler and removed socket from list"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   232
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   233
    handler.ip = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   234
        return ip
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   235
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   236
    handler.serverport = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   237
        return serverport
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   238
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   239
    handler.clientport = function( ) 
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   240
        return clientport
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   241
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   242
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   243
    handler.write = function( data )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   244
        if not eol then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   245
            writelen = writelen + 1
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   246
            writelist[ writelen ] = socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   247
            eol = 0
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   248
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   249
        eol = eol + 1
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   250
        writequeue[ eol ] = data
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   251
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   252
    handler.writequeue = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   253
        return writequeue
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   254
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   255
    handler.socket = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   256
        return socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   257
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   258
    handler.mode = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   259
        return mode
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   260
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   261
    handler._receivedata = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   262
        local data, err, part = receive( socket, mode )    -- receive data in "mode"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   263
        if not err or ( err == "timeout" or err == "wantread" ) then    -- received something
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   264
            local data = data or part or ""
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   265
            local count = #data * STAT_UNIT
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   266
            rstat = rstat + count
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   267
            receivestat = receivestat + count
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   268
            out_put( "server.lua: read data '", data, "', error: ", err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   269
            return dispatch( handler, data, err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   270
        else    -- connections was closed or fatal error
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   271
            out_put( "server.lua: client ", ip, ":", clientport, " error: ", err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   272
            handler.close( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   273
            disconnect( handler, err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   274
            writequeue = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   275
            handler = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   276
            return false
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   277
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   278
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   279
    handler._dispatchdata = function( )    -- this function writes data to handlers
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   280
        local buffer = table_concat( writequeue, "", 1, eol )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   281
        local succ, err, byte = send( socket, buffer )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   282
        local count = ( succ or 0 ) * STAT_UNIT
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   283
        sstat = sstat + count
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   284
        sendstat = sendstat + count
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   285
        out_put( "server.lua: sended '", buffer, "', bytes: ", succ, ", error: ", err, ", part: ", byte, ", to: ", ip, ":", clientport )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   286
        if succ then    -- sending succesful
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   287
            --writequeue = { }
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   288
            eol = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   289
            writelen = removesocket( writelist, socket, writelen )    -- delete socket from writelist
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   290
            return true
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   291
        elseif byte and ( err == "timeout" or err == "wantwrite" ) then    -- want write
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   292
            buffer = string_sub( buffer, byte + 1, -1 )    -- new buffer
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   293
            writequeue[ 1 ] = buffer    -- insert new buffer in queue
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   294
            eol = 1
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   295
            return true
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   296
        else    -- connection was closed during sending or fatal error
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   297
            out_put( "server.lua: client ", ip, ":", clientport, " error: ", err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   298
            handler.close( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   299
            disconnect( handler, err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   300
            writequeue = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   301
            handler = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   302
            return false
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   303
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   304
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   305
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   306
    -- // COMPAT // --
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   307
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   308
    handler.getIp = handler.ip
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   309
    handler.getPort = handler.clientport
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   310
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   311
    --// handshake //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   312
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   313
    local wrote
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   314
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   315
    handler.handshake = coroutine_wrap( function( client )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   316
            local err
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   317
            for i = 1, 10 do    -- 10 handshake attemps
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   318
                _, err = client:dohandshake( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   319
                if not err then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   320
                    out_put( "server.lua: ssl handshake done" )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   321
                    writelen = ( wrote and removesocket( writelist, socket, writelen ) ) or writelen
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   322
                    handler.receivedata = handler._receivedata    -- when handshake is done, replace the handshake function with regular functions
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   323
                    handler.dispatchdata = handler._dispatchdata
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   324
                    return dispatch( handler )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   325
                else
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   326
                    out_put( "server.lua: error during ssl handshake: ", err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   327
                    if err == "wantwrite" then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   328
                        if wrote == nil then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   329
                            writelen = writelen + 1
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   330
                            writelist[ writelen ] = client
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   331
                            wrote = true
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   332
                        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   333
                    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   334
                    coroutine_yield( handler, nil, err )    -- handshake not finished
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   335
                end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   336
            end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   337
            _ = err ~= "closed" and close( socket )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   338
            handler.close( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   339
            disconnect( handler, err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   340
            writequeue = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   341
            handler = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   342
            return false    -- handshake failed
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   343
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   344
    )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   345
    handler.receivedata = handler.handshake
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   346
    handler.dispatchdata = handler.handshake
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   347
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   348
    handler.handshake( socket )    -- do handshake
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   349
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   350
    socketlist[ socket ] = handler
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   351
    readlen = readlen + 1
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   352
    readlist[ readlen ] = socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   353
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   354
    return handler, socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   355
end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   356
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   357
wraptcpclient = function( listener, socket, ip, serverport, clientport, mode )    -- this function wraps a socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   358
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   359
    local dispatch, disconnect = listener.listener, listener.disconnect
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   360
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   361
    --// private closures of the object //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   362
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   363
    local writequeue = { }    -- list for messages to send
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   364
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   365
    local eol
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   366
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   367
    local rstat, sstat = 0, 0
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   368
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   369
    --// local import of socket methods //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   370
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   371
    local send = socket.send
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   372
    local receive = socket.receive
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   373
    local close = socket.close
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   374
    local shutdown = socket.shutdown
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   375
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   376
    --// public methods of the object //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   377
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   378
    local handler = { }
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   379
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   380
    handler.getstats = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   381
        return rstat, sstat
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   382
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   383
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   384
    handler.listener = function( data, err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   385
        return listener( handler, data, err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   386
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   387
    handler.ssl = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   388
        return false
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   389
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   390
    handler.send = function( _, data, i, j )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   391
            return send( socket, data, i, j )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   392
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   393
    handler.receive = function( pattern, prefix )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   394
            return receive( socket, pattern, prefix )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   395
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   396
    handler.shutdown = function( pattern )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   397
        return shutdown( socket, pattern )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   398
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   399
    handler.close = function( closed )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   400
        _ = not closed and shutdown( socket )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   401
        _ = not closed and close( socket )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   402
        writelen = ( eol and removesocket( writelist, socket, writelen ) ) or writelen
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   403
        readlen = removesocket( readlist, socket, readlen )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   404
        socketlist[ socket ] = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   405
        out_put "server.lua: closed handler and removed socket from list"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   406
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   407
    handler.ip = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   408
        return ip
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   409
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   410
    handler.serverport = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   411
        return serverport
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   412
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   413
    handler.clientport = function( ) 
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   414
        return clientport
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   415
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   416
    handler.write = function( data )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   417
        if not eol then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   418
            writelen = writelen + 1
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   419
            writelist[ writelen ] = socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   420
            eol = 0
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   421
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   422
        eol = eol + 1
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   423
        writequeue[ eol ] = data
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   424
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   425
    handler.writequeue = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   426
        return writequeue
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   427
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   428
    handler.socket = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   429
        return socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   430
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   431
    handler.mode = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   432
        return mode
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   433
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   434
    handler.receivedata = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   435
        local data, err, part = receive( socket, mode )    -- receive data in "mode"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   436
        if not err or ( err == "timeout" or err == "wantread" ) then    -- received something
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   437
            local data = data or part or ""
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   438
            local count = #data * STAT_UNIT
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   439
            rstat = rstat + count
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   440
            receivestat = receivestat + count
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   441
            out_put( "server.lua: read data '", data, "', error: ", err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   442
            return dispatch( handler, data, err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   443
        else    -- connections was closed or fatal error
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   444
            out_put( "server.lua: client ", ip, ":", clientport, " error: ", err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   445
            handler.close( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   446
            disconnect( handler, err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   447
            writequeue = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   448
            handler = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   449
            return false
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   450
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   451
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   452
    handler.dispatchdata = function( )    -- this function writes data to handlers
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   453
        local buffer = table_concat( writequeue, "", 1, eol )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   454
        local succ, err, byte = send( socket, buffer )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   455
        local count = ( succ or 0 ) * STAT_UNIT
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   456
        sstat = sstat + count
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   457
        sendstat = sendstat + count
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   458
        out_put( "server.lua: sended '", buffer, "', bytes: ", succ, ", error: ", err, ", part: ", byte, ", to: ", ip, ":", clientport )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   459
        if succ then    -- sending succesful
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   460
            --writequeue = { }
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   461
            eol = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   462
            writelen = removesocket( writelist, socket, writelen )    -- delete socket from writelist
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   463
            return true
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   464
        elseif byte and ( err == "timeout" or err == "wantwrite" ) then    -- want write
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   465
            buffer = string_sub( buffer, byte + 1, -1 )    -- new buffer
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   466
            writequeue[ 1 ] = buffer    -- insert new buffer in queue
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   467
            eol = 1
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   468
            return true
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   469
        else    -- connection was closed during sending or fatal error
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   470
            out_put( "server.lua: client ", ip, ":", clientport, " error: ", err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   471
            handler.close( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   472
            disconnect( handler, err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   473
            writequeue = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   474
            handler = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   475
            return false
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   476
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   477
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   478
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   479
    -- // COMPAT // --
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   480
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   481
    handler.getIp = handler.ip
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   482
    handler.getPort = handler.clientport
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   483
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   484
    socketlist[ socket ] = handler
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   485
    readlen = readlen + 1
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   486
    readlist[ readlen ] = socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   487
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   488
    return handler, socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   489
end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   490
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   491
addtimer = function( listener )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   492
    timelistener[ #timelistener + 1 ] = listener
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   493
end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   494
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   495
firetimer = function( listener )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   496
    for i, listener in ipairs( timelistener ) do
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   497
        listener( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   498
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   499
end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   500
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   501
addserver = function( listeners, port, addr, mode, sslctx )    -- this function provides a way for other scripts to reg a server
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   502
    local err
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   503
    if type( listeners ) ~= "table" then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   504
        err = "invalid listener table"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   505
    else
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   506
        for name, func in pairs( listeners ) do
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   507
            if type( func ) ~= "function" then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   508
                err = "invalid listener function"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   509
                break
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   510
            end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   511
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   512
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   513
    if not type( port ) == "number" or not ( port >= 0 and port <= 65535 ) then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   514
        err = "invalid port"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   515
    elseif listener[ port ] then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   516
        err=  "listeners on port '" .. port .. "' already exist"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   517
    elseif sslctx and not luasec then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   518
        err = "luasec not found"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   519
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   520
    if err then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   521
        out_error( "server.lua: ", err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   522
        return nil, err
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   523
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   524
    addr = addr or "*"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   525
    local server, err = socket_bind( addr, port )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   526
    if err then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   527
        out_error( "server.lua: ", err )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   528
        return nil, err
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   529
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   530
    local handler, err = wrapserver( listeners, server, addr, port, mode, sslctx )    -- wrap new server socket
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   531
    if not handler then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   532
        server:close( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   533
        return nil, err
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   534
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   535
    server:settimeout( 0 )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   536
    readlen = readlen + 1
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   537
    readlist[ readlen ] = server
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   538
    listener[ port ] = listeners
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   539
    socketlist[ server ] = handler
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   540
    out_put( "server.lua: new server listener on ", addr, ":", port )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   541
    return true
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   542
end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   543
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   544
removesocket = function( tbl, socket, len )    -- this function removes sockets from a list
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   545
    for i, target in ipairs( tbl ) do
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   546
        if target == socket then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   547
            len = len - 1
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   548
            table_remove( tbl, i )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   549
            return len
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   550
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   551
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   552
    return len
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   553
end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   554
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   555
closeall = function( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   556
    for _, handler in pairs( socketlist ) do
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   557
        handler.shutdown( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   558
        handler.close( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   559
        socketlist[ _ ] = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   560
    end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   561
    writelist, readlist, socketlist = { }, { }, { }
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   562
end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   563
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   564
closesocket = function( socket )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   565
    writelen = removesocket( writelist, socket, writelen )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   566
    readlen = removesocket( readlist, socket, readlen )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   567
    socketlist[ socket ] = nil
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   568
    socket:close( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   569
end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   570
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   571
loop = function( )    -- this is the main loop of the program
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   572
    --signal_set( "hub", "run" )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   573
    repeat
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   574
        local read, write, err = socket_select( readlist, writelist, 1 )    -- 1 sec timeout, nice for timers
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   575
        for i, socket in ipairs( write ) do    -- send data waiting in writequeues
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   576
            local handler = socketlist[ socket ]
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   577
            if handler then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   578
                handler.dispatchdata( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   579
            else
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   580
                closesocket( socket )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   581
                out_put "server.lua: found no handler and closed socket (writelist)"    -- this should not happen
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   582
            end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   583
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   584
        for i, socket in ipairs( read ) do    -- receive data
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   585
            local handler = socketlist[ socket ]
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   586
            if handler then
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   587
                handler.receivedata( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   588
            else
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   589
                closesocket( socket )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   590
                out_put "server.lua: found no handler and closed socket (readlist)"    -- this can happen
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   591
            end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   592
        end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   593
        firetimer( )
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   594
        --collectgarbage "collect"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   595
    until false --signal_get "hub" ~= "run"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   596
    return --signal_get "hub"
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   597
end
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   598
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   599
----------------------------------// BEGIN //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   600
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   601
----------------------------------// PUBLIC INTERFACE //--
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   602
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   603
return {
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   604
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   605
    add = addserver,
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   606
    loop = loop,
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   607
    stats = stats,
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   608
    closeall = closeall,
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   609
    addtimer = addtimer,
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   610
57e4eb3aeac0 Added all the files to please hg :/
matthew@silver
parents:
diff changeset
   611
}