From a3102c4c1eb4595cf1c3d3b3c243384e12b75b0c Mon Sep 17 00:00:00 2001 From: Alex Shinn Date: Sun, 14 Jul 2013 18:32:48 +0900 Subject: [PATCH] Adding additional constants and the ability to set addrinfo hints. Setting the default hints to AI_PASSIVE so that standard listeners (including those created implicitly by run-net-server) can listen on all addresses. --- examples/echo-server.scm | 15 +++++++++------ lib/chibi/accept.c | 8 ++++++++ lib/chibi/net.scm | 10 ++++++++-- lib/chibi/net.sld | 6 ++++-- lib/chibi/net.stub | 16 ++++++++++++++-- lib/chibi/net/server.scm | 4 ++-- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/examples/echo-server.scm b/examples/echo-server.scm index fcdde84a..ca7be695 100644 --- a/examples/echo-server.scm +++ b/examples/echo-server.scm @@ -1,20 +1,23 @@ -;; Simple R7RS echo server, using (srfi 18) threads and the -;; run-net-server utility from (chibi net server). +;; Simple R7RS echo server, using the run-net-server utility from +;; (chibi net server). -(import (scheme base) (scheme write) (srfi 18) (chibi net server)) +(import (scheme base) (scheme write) (chibi net) (chibi net server)) ;; Copy each input line to output. (define (echo-handler in out sock addr) (let ((line (read-line in))) (cond ((not (or (eof-object? line) (equal? line ""))) - (display "read: ") (write line) (newline) + ;; log the request to stdout + (display "read: ") (write line) + (display " from ") (display (sockaddr-name (address-info-address addr))) + (newline) + ;; write and flush the response (display line out) (newline out) (flush-output-port out) - (thread-yield!) (echo-handler in out sock addr))))) -;; Start the server on localhost:5556 dispatching clients to echo-handler. +;; Start the server on *:5556 dispatching clients to echo-handler. (run-net-server 5556 echo-handler) diff --git a/lib/chibi/accept.c b/lib/chibi/accept.c index 5b391bf1..0d73352d 100644 --- a/lib/chibi/accept.c +++ b/lib/chibi/accept.c @@ -39,3 +39,11 @@ sexp sexp_listen (sexp ctx, sexp self, sexp fileno, sexp backlog) { #endif return (res == 0) ? SEXP_TRUE : SEXP_FALSE; } + +sexp sexp_sockaddr_name (sexp ctx, sexp self, struct sockaddr* addr) { + char buf[20]; + struct sockaddr_in *sa = (struct sockaddr_in *)addr; + unsigned char *ptr = (unsigned char *)&(sa->sin_addr); + sprintf(buf, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]); + return sexp_c_string(ctx, buf, -1); +} diff --git a/lib/chibi/net.scm b/lib/chibi/net.scm index 6778afb0..05186168 100644 --- a/lib/chibi/net.scm +++ b/lib/chibi/net.scm @@ -1,6 +1,11 @@ ;; Copyright (c) 2010-2012 Alex Shinn. All rights reserved. ;; BSD-style license: http://synthcode.com/license.txt +;;> \subsubsubsection{\scheme{(make-address-info family socktype proto [hints])}} + +(define (make-address-info family socktype proto . o) + (%make-address-info family socktype proto (if (pair? o) (car o) 0))) + ;;> \subsubsubsection{\scheme{(get-address-info host service [addrinfo])}} ;;> Create and return a new addrinfo structure for the given host @@ -13,9 +18,10 @@ (if (integer? service) (number->string service) service) (if (and (pair? o) (car o)) (car o) - (make-address-info address-family/inet + (make-address-info address-family/unspecified socket-type/stream - ip-proto/tcp)))) + ip-proto/ip + ai/passive)))) ;;> Opens a client net connection to \var{host}, a string, ;;> on port \var{service}, which can be a string such as diff --git a/lib/chibi/net.sld b/lib/chibi/net.sld index a1cd1dea..6a24e035 100644 --- a/lib/chibi/net.sld +++ b/lib/chibi/net.sld @@ -2,12 +2,14 @@ (define-library (chibi net) (export sockaddr? address-info? get-address-info make-address-info socket connect bind accept listen open-socket-pair + sockaddr-name with-net-io open-net-io make-listener-socket address-info-family address-info-socket-type address-info-protocol address-info-address address-info-address-length address-info-next - address-family/unix address-family/inet + address-family/unix address-family/inet address-family/unspecified socket-type/stream socket-type/datagram socket-type/raw - ip-proto/tcp ip-proto/udp + ip-proto/ip ip-proto/tcp ip-proto/udp + ai/passive ai/canonname ai/numeric-host get-socket-option set-socket-option! level/socket socket-opt/debug socket-opt/broadcast socket-opt/reuseaddr socket-opt/keepalive socket-opt/oobinline socket-opt/sndbuf diff --git a/lib/chibi/net.stub b/lib/chibi/net.stub index 2049765e..e6fe6c3f 100644 --- a/lib/chibi/net.stub +++ b/lib/chibi/net.stub @@ -10,12 +10,13 @@ predicate: sockaddr?) (define-c-struct addrinfo - constructor: (make-address-info ai_family ai_socktype ai_protocol) + constructor: (%make-address-info ai_family ai_socktype ai_protocol ai_flags) finalizer: freeaddrinfo predicate: address-info? (int ai_family address-info-family) (int ai_socktype address-info-socket-type) (int ai_protocol address-info-protocol) + (int ai_flags address-info-flags) ((link sockaddr) ai_addr address-info-address) (size_t ai_addrlen address-info-address-length) ((link addrinfo) ai_next address-info-next)) @@ -24,7 +25,8 @@ ;;/ (define-c errno (%get-address-info getaddrinfo) - (string string (maybe-null addrinfo) (result free addrinfo))) + ((maybe-null string) (maybe-null string) (maybe-null addrinfo) + (result free addrinfo))) ;;> Bind a name to a socket. @@ -54,13 +56,23 @@ (define-c errno (open-socket-pair "socketpair") (int int int (result (array fileno 2)))) +;;> Return the IP address of a sockaddr as an "N.N.N.N" string. + +(define-c sexp (sockaddr-name "sexp_sockaddr_name") + ((value ctx sexp) (value self sexp) sockaddr)) + +(define-c-const int (address-family/unspecified "AF_UNSPEC")) (define-c-const int (address-family/unix "AF_UNIX")) (define-c-const int (address-family/inet "AF_INET")) (define-c-const int (socket-type/stream "SOCK_STREAM")) (define-c-const int (socket-type/datagram "SOCK_DGRAM")) (define-c-const int (socket-type/raw "SOCK_RAW")) +(define-c-const int (ip-proto/ip "IPPROTO_IP")) (define-c-const int (ip-proto/tcp "IPPROTO_TCP")) (define-c-const int (ip-proto/udp "IPPROTO_UDP")) +(define-c-const int (ai/passive "AI_PASSIVE")) +(define-c-const int (ai/canonname "AI_CANONNAME")) +(define-c-const int (ai/numeric-host "AI_NUMERICHOST")) ;;> The constants for the addrinfo struct. ;;/ diff --git a/lib/chibi/net/server.scm b/lib/chibi/net/server.scm index 4701c1ef..118be8e5 100644 --- a/lib/chibi/net/server.scm +++ b/lib/chibi/net/server.scm @@ -5,7 +5,7 @@ (define (make-socket-listener-thunk listener port) (lambda () - (let ((addr (get-address-info "localhost" port))) + (let ((addr (get-address-info #f port))) (cond ((accept listener (address-info-address addr) @@ -17,7 +17,7 @@ (cond ((integer? x) (make-socket-listener-thunk - (make-listener-socket (get-address-info "localhost" x)) + (make-listener-socket (get-address-info #f x)) x)) ((address-info? x) (make-socket-listener-thunk (make-listener-socket x) 80))