416 |
416 |
417 function interface:ssl() |
417 function interface:ssl() |
418 return self._tls; |
418 return self._tls; |
419 end |
419 end |
420 |
420 |
421 function interface:starttls(ctx) |
421 function interface:starttls(tls_ctx) |
422 if ctx then self.tls = ctx; end |
422 if tls_ctx then self.tls_ctx = tls_ctx; end |
423 if self.writebuffer and self.writebuffer[1] then |
423 if self.writebuffer and self.writebuffer[1] then |
424 log("debug", "Start TLS on %s after write", tostring(self)); |
424 log("debug", "Start TLS on %s after write", tostring(self)); |
425 self.ondrain = interface.starttls; |
425 self.ondrain = interface.starttls; |
426 self.starttls = false; |
426 self.starttls = false; |
427 self:setflags(nil, true); -- make sure wantwrite is set |
427 self:setflags(nil, true); -- make sure wantwrite is set |
428 else |
428 else |
429 log("debug", "Start TLS on %s now", tostring(self)); |
429 log("debug", "Start TLS on %s now", tostring(self)); |
430 self:setflags(false, false); |
430 self:setflags(false, false); |
431 local conn, err = luasec.wrap(self.conn, ctx or self.tls); |
431 local conn, err = luasec.wrap(self.conn, tls_ctx or self.tls_ctx); |
432 if not conn then |
432 if not conn then |
433 self:on("disconnect", err); |
433 self:on("disconnect", err); |
434 self:destroy(); |
434 self:destroy(); |
435 return conn, err; |
435 return conn, err; |
436 end |
436 end |
468 self:on("disconnect", err); |
468 self:on("disconnect", err); |
469 self:destroy(); |
469 self:destroy(); |
470 end |
470 end |
471 end |
471 end |
472 |
472 |
473 local function wrapsocket(client, server, pattern, listeners, tls) -- luasocket object -> interface object |
473 local function wrapsocket(client, server, pattern, listeners, tls_ctx) -- luasocket object -> interface object |
474 client:settimeout(0); |
474 client:settimeout(0); |
475 local conn = setmetatable({ |
475 local conn = setmetatable({ |
476 conn = client; |
476 conn = client; |
477 _server = server; |
477 _server = server; |
478 created = gettime(); |
478 created = gettime(); |
479 listeners = listeners; |
479 listeners = listeners; |
480 _pattern = pattern or (server and server._pattern); |
480 _pattern = pattern or (server and server._pattern); |
481 writebuffer = {}; |
481 writebuffer = {}; |
482 tls = tls; |
482 tls_ctx = tls_ctx; |
483 }, interface_mt); |
483 }, interface_mt); |
484 |
484 |
485 if client.getpeername then |
485 if client.getpeername then |
486 conn.peername, conn.peerport = client:getpeername(); |
486 conn.peername, conn.peerport = client:getpeername(); |
487 end |
487 end |
498 if not conn then |
498 if not conn then |
499 log("debug", "Error accepting new client: %s, server will be paused for %ds", err, cfg.accept_retry_interval); |
499 log("debug", "Error accepting new client: %s, server will be paused for %ds", err, cfg.accept_retry_interval); |
500 self:pausefor(cfg.accept_retry_interval); |
500 self:pausefor(cfg.accept_retry_interval); |
501 return; |
501 return; |
502 end |
502 end |
503 local client = wrapsocket(conn, self, nil, self.listeners, self.tls); |
503 local client = wrapsocket(conn, self, nil, self.listeners, self.tls_ctx); |
504 log("debug", "New connection %s", tostring(client)); |
504 log("debug", "New connection %s", tostring(client)); |
505 client:init(); |
505 client:init(); |
506 end |
506 end |
507 |
507 |
508 -- Initialization |
508 -- Initialization |
509 function interface:init() |
509 function interface:init() |
510 if self.tls and not self._tls then |
510 if self.tls_ctx and not self._tls then |
511 return self:starttls(); |
511 return self:starttls(); |
512 else |
512 else |
513 self:setwritetimeout(); |
513 self:setwritetimeout(); |
514 return self:setflags(true, true); |
514 return self:setflags(true, true); |
515 end |
515 end |
546 end |
546 end |
547 self.onconnect = noop; |
547 self.onconnect = noop; |
548 self:on("connect"); |
548 self:on("connect"); |
549 end |
549 end |
550 |
550 |
551 local function addserver(addr, port, listeners, pattern, tls) |
551 local function addserver(addr, port, listeners, pattern, tls_ctx) |
552 local conn, err = socket.bind(addr, port, cfg.tcp_backlog); |
552 local conn, err = socket.bind(addr, port, cfg.tcp_backlog); |
553 if not conn then return conn, err; end |
553 if not conn then return conn, err; end |
554 conn:settimeout(0); |
554 conn:settimeout(0); |
555 local server = setmetatable({ |
555 local server = setmetatable({ |
556 conn = conn; |
556 conn = conn; |
557 created = gettime(); |
557 created = gettime(); |
558 listeners = listeners; |
558 listeners = listeners; |
559 _pattern = pattern; |
559 _pattern = pattern; |
560 onreadable = interface.onacceptable; |
560 onreadable = interface.onacceptable; |
561 tls = tls; |
561 tls_ctx = tls_ctx; |
562 sockname = addr; |
562 sockname = addr; |
563 sockport = port; |
563 sockport = port; |
564 }, interface_mt); |
564 }, interface_mt); |
565 server:setflags(true, false); |
565 server:setflags(true, false); |
566 return server; |
566 return server; |
567 end |
567 end |
568 |
568 |
569 -- COMPAT |
569 -- COMPAT |
570 local function wrapclient(conn, addr, port, listeners, pattern, tls) |
570 local function wrapclient(conn, addr, port, listeners, pattern, tls_ctx) |
571 local client = wrapsocket(conn, nil, pattern, listeners, tls); |
571 local client = wrapsocket(conn, nil, pattern, listeners, tls_ctx); |
572 if not client.peername then |
572 if not client.peername then |
573 client.peername, client.peerport = addr, port; |
573 client.peername, client.peerport = addr, port; |
574 end |
574 end |
575 client:init(); |
575 client:init(); |
576 return client; |
576 return client; |
577 end |
577 end |
578 |
578 |
579 -- New outgoing TCP connection |
579 -- New outgoing TCP connection |
580 local function addclient(addr, port, listeners, pattern, tls) |
580 local function addclient(addr, port, listeners, pattern, tls_ctx) |
581 local conn, err = socket.tcp(); |
581 local conn, err = socket.tcp(); |
582 if not conn then return conn, err; end |
582 if not conn then return conn, err; end |
583 conn:settimeout(0); |
583 conn:settimeout(0); |
584 conn:connect(addr, port); |
584 conn:connect(addr, port); |
585 local client = wrapsocket(conn, nil, pattern, listeners, tls) |
585 local client = wrapsocket(conn, nil, pattern, listeners, tls_ctx) |
586 client:init(); |
586 client:init(); |
587 return client, conn; |
587 return client, conn; |
588 end |
588 end |
589 |
589 |
590 local function watchfd(fd, onreadable, onwriteable) |
590 local function watchfd(fd, onreadable, onwriteable) |