[usocket-cvs] r119 - in usocket/trunk: . backend doc notes
ehuelsmann at common-lisp.net
ehuelsmann at common-lisp.net
Wed Oct 18 06:56:34 UTC 2006
Author: ehuelsmann
Date: Wed Oct 18 02:56:33 2006
New Revision: 119
Added:
usocket/trunk/backend/scl.lisp
usocket/trunk/notes/accept-apis.txt
Modified:
usocket/trunk/condition.lisp
usocket/trunk/doc/design.txt
usocket/trunk/usocket.asd
usocket/trunk/usocket.lisp
Log:
Add Scieneer support.
Donated by Douglas Crosher <dtc at scieneer dot com>.
Added: usocket/trunk/backend/scl.lisp
==============================================================================
--- (empty file)
+++ usocket/trunk/backend/scl.lisp Wed Oct 18 02:56:33 2006
@@ -0,0 +1,101 @@
+;;;; $Id: scl.lisp$
+;;;; $URL: svn://common-lisp.net/project/usocket/svn/usocket/trunk/backend/scl.lisp $
+
+;;;; See LICENSE for licensing information.
+
+(in-package :usocket)
+
+(defparameter +scl-error-map+
+ (append +unix-errno-condition-map+
+ +unix-errno-error-map+))
+
+(defun scl-map-socket-error (err &key condition socket)
+ (let ((usock-err (cdr (assoc err +scl-error-map+ :test #'member))))
+ (cond (usock-err
+ (if (subtypep usock-err 'error)
+ (error usock-err :socket socket)
+ (signal usock-err :socket socket)))
+ (t
+ (error 'unknown-error
+ :socket socket
+ :real-error condition)))))
+
+(defun handle-condition (condition &optional (socket nil))
+ "Dispatch correct usocket condition."
+ (etypecase condition
+ (ext::socket-error
+ (format t "erron: ~D~%" (ext::socket-errno condition))
+ (scl-map-socket-error (ext::socket-errno condition)
+ :socket socket
+ :condition condition))
+ (error
+ (error 'unknown-error
+ :real-condition condition
+ :socket socket))))
+
+(defun socket-connect (host port)
+ (let* ((socket
+ (with-mapped-conditions (nil)
+ (ext:connect-to-inet-socket (host-to-hbo host) port :kind :stream)))
+ (stream (sys:make-fd-stream socket :input t :output t
+ :element-type 'character
+ :buffering :full)))
+ ;;###FIXME the above line probably needs an :external-format
+ (make-socket :socket socket :stream stream)))
+
+(defmethod socket-close ((usocket usocket))
+ "Close socket."
+ (with-mapped-conditions (usocket)
+ (ext:close-socket (socket usocket))))
+
+(defmethod get-local-name ((usocket usocket))
+ (multiple-value-bind (address port)
+ (with-mapped-conditions (usocket)
+ (ext:get-socket-host-and-port (socket usocket)))
+ (values (hbo-to-vector-quad address) port)))
+
+(defmethod get-peer-name ((usocket usocket))
+ (multiple-value-bind (address port)
+ (with-mapped-conditions (usocket)
+ (ext:get-peer-host-and-port (socket usocket)))
+ (values (hbo-to-vector-quad address) port)))
+
+(defmethod get-local-address ((usocket usocket))
+ (nth-value 0 (get-local-name usocket)))
+
+(defmethod get-peer-address ((usocket usocket))
+ (nth-value 0 (get-peer-name usocket)))
+
+(defmethod get-local-port ((usocket usocket))
+ (nth-value 1 (get-local-name usocket)))
+
+(defmethod get-peer-port ((usocket usocket))
+ (nth-value 1 (get-peer-name usocket)))
+
+
+(defun get-host-by-address (address)
+ (multiple-value-bind (host errno)
+ (ext:lookup-host-entry (host-byte-order address))
+ (cond (host
+ (ext:host-entry-name host))
+ (t
+ (let ((condition (cdr (assoc errno +unix-ns-error-map+))))
+ (cond (condition
+ (error condition :host-or-ip address))
+ (t
+ (error 'ns-unknown-error :host-or-ip address
+ :real-error errno))))))))
+
+(defun get-hosts-by-name (name)
+ (multiple-value-bind (host errno)
+ (ext:lookup-host-entry name)
+ (cond (host
+ (mapcar #'hbo-to-vector-quad
+ (ext:host-entry-addr-list host)))
+ (t
+ (let ((condition (cdr (assoc errno +unix-ns-error-map+))))
+ (cond (condition
+ (error condition :host-or-ip name))
+ (t
+ (error 'ns-unknown-error :host-or-ip name
+ :real-error errno))))))))
Modified: usocket/trunk/condition.lisp
==============================================================================
--- usocket/trunk/condition.lisp (original)
+++ usocket/trunk/condition.lisp Wed Oct 18 02:56:33 2006
@@ -102,8 +102,8 @@
;; isn't really an error: there's just no data to return.
;; with lisp, we just return NIL (indicating no data) instead of
;; raising an exception...
- (ns-host-not-found
- ns-no-recovery)
+ (ns-host-not-found-error
+ ns-no-recovery-error)
(ns-error))
(define-condition ns-unknown-error (ns-error)
Modified: usocket/trunk/doc/design.txt
==============================================================================
--- usocket/trunk/doc/design.txt (original)
+++ usocket/trunk/doc/design.txt Wed Oct 18 02:56:33 2006
@@ -13,7 +13,7 @@
* Motivation
* Design goal
* Functional requirements
-
+ * Comments on the functional requirements
@@ -83,6 +83,33 @@
- OpenMCL
+The lifetime of a socket can be described with these steps:
+
+ 1. Socket creation (socket() function)
+ 2. Socket initializaiton (setsockopt(), bind() and listen()/connect() funcs)
+ 3. Socket use (accept() / recv[from], send[to])
+ 4. Socket termination (shutdown())
+ 5. Socket destruction (close())
+
+While for most applications steps 1-3 can be condensed into 1 (which most
+implementations do), if the library wants to be extensible into other
+domains than IP, a means should be provided to do socket initialization
+without knowing what parameters to accept beforehand: other protocols
+require parameters for setsockopt we will not know about in advance.
+
+There are several possibilities to address this issue:
+
+ a. Force the 3 steps apart [hard to get done with the current status
+ for some implementations, as they are currently integrated in the
+ public interface].
+ b. Find a mechanism to pass options which we want setsockopt to
+ be called with. Problem: what to do with implementations which
+ don't support setting of all options *before* the bind() call?
+ Does it matter that some options may be set after the bind()
+ call? What if they're not set before connect() [buffer size changes
+ have to be set before connect()]?
+ c. ... ?
+
Comments on the design above
============================
Added: usocket/trunk/notes/accept-apis.txt
==============================================================================
--- (empty file)
+++ usocket/trunk/notes/accept-apis.txt Wed Oct 18 02:56:33 2006
@@ -0,0 +1,173 @@
+
+ -*- text -*-
+
+Part of 'Step 3': Server/passive tcp socket interfaces supplied by
+the different implementations in order to provide the same externally.
+
+
+ABCL
+====
+
+ - ext:make-server-socket port
+ - ext:socket-accept socket
+ - ext:socket-close socket
+
+Allegro
+=======
+
+ - socket:make-socket :type :stream :connect :passive
+ :local-port <port> :reuse-address t :backlog <nr>
+ :local-host <host-ip>
+ - socket:accept-connection sock &key wait
+ - close
+
+
+clisp
+=====
+
+ - socket:socket-server &optional port &key interface backlog
+ - socket:socket-server-close sock
+ - socket:socket-server-host sock
+ - socket:socket-server-port sock
+ - socket:socket-accept sock &key element-type external-format buffered timeout
+ - socket:socket-options sock &rest options
+
+... and ofcourse, there's the raw-sockets
+
+CMUCL
+=====
+
+ - ext:create-inet-listener port &optional kind
+ &key reuseaddress backlog interface
+ - ext:accept-tcp-connection socket
+
+
+LispWorks
+=========
+
+ - comm::get-fd-from-socket (socket-os-fd lispworks-socket)
+ - comm::create-tcp-socket-for-service port
+ (may use comm::*use_so_reuseaddr* for that socket option)
+ misses the ability to specify an interface to bind to.
+ - comm::socket-close
+
+
+OpenMCL
+=======
+
+ - openmcl-socket:accept-connection
+ - openmcl-socket:make-socket :local-host <if> :local-port port
+ :reuse-address t :type :stream :connect :passive
+ :backlog <nr>
+ - close
+
+
+SBCL
+====
+
+ - make-instance 'inet-socket
+ - sb-bsd-sockets:sockopt-*
+ - sb-bsd-sockets:socket-bind
+ - sb-bsd-sockets:socket-listen
+ - sb-bsd-sockets:socket-accept
+
+
+;;
+;;
+;; The above APIs are good enough to implement a simple
+;; accept interface, but doesn't give access to specifying
+;; socket options before the socket is bound to the interface
+;; ==> This may only actually be required for SO_REUSEADDRESS?!???
+;;
+;; The other option would be to use lots of FFI - where needed -
+;; and use the (mostly internal) glue routines from the implementations
+
+
+ABCL
+====
+
+ With ABCL - lacking a good sockets API - it's still possible to implement
+ whatever we need to get good access...
+
+
+Allegro
+=======
+
+ Hmm. The accept function in this implementation does not allow limiting
+ connections to a given host/ip, but it does allow to create sockets
+ with mostly the right options.
+
+ Is that enough reason to do this entirely in ffi?!
+
+ Also, doing this in FFI would require to reverse engineer the creation
+ of socket streams. Maybe Franz tech support could help there though.
+
+ Need to investigate the IPC_* symbols an the sockets package:
+ there are lots of functions which look like they should be useable.
+
+
+clisp
+=====
+
+ This implementation allows access to the full sockets as described
+ in http://clisp.cons.org/impnotes/rawsock.html.
+
+
+CMUCL
+=====
+
+ Provides (in unix package):
+
+ - unix-accept
+ - unix-bind
+ - unix-listen
+ - unix-socket
+
+ Provides (in extentions):
+
+ - inet-sockaddr
+ - get-socket-option
+ - set-socket-option
+ - create-inet-listener port &key host reuse-address backlog
+
+
+LispWorks
+=========
+
+ The implementation provides a lot of undocumented functions the library
+ could tap into:
+
+ - comm::socket
+ - comm::bind
+ - comm::accept
+ - comm::getsockopt
+ - comm::setsockopt
+ - comm::initialize-sockaddr_in (helper)
+ - comm::streams-from-fd (helper)
+
+
+OpenMCL
+=======
+
+ - make-socket provides all options which we'll need to set,
+ it doesn't however provide access to [gs]etsockopt...
+
+
+SBCL
+====
+
+ provides (in sb-bsd-sockets):
+ socket-bind
+ socket-accept
+ sokcet-listen
+
+ provides (in sb-bsd-sockets-internal [sockint]):
+ getsockopt
+ setsockopt
+
+ SO-* constants
+ TCP-* constant(s)
+ AF-* constants (and, since AF-* == IF-*, we don't need others)
+
+
+
Modified: usocket/trunk/usocket.asd
==============================================================================
--- usocket/trunk/usocket.asd (original)
+++ usocket/trunk/usocket.asd Wed Oct 18 02:56:33 2006
@@ -28,6 +28,8 @@
:depends-on ("condition"))
#+cmu (:file "cmucl" :pathname "backend/cmucl"
:depends-on ("condition"))
+ #+scl (:file "scl" :pathname "backend/scl"
+ :depends-on ("condition"))
#+sbcl (:file "sbcl" :pathname "backend/sbcl"
:depends-on ("condition"))
#+lispworks (:file "lispworks" :pathname "backend/lispworks"
Modified: usocket/trunk/usocket.lisp
==============================================================================
--- usocket/trunk/usocket.lisp (original)
+++ usocket/trunk/usocket.lisp Wed Oct 18 02:56:33 2006
@@ -164,8 +164,8 @@
(string (let ((ip (ignore-errors
(dotted-quad-to-vector-quad host))))
(if (and ip (= 4 (length ip)))
- ip
- (host-to-hbo (get-host-by-name host)))))
+ (host-byte-order ip)
+ (host-to-hbo (get-host-by-name host)))))
((vector t 4) (host-byte-order host))
(integer host))))
@@ -186,9 +186,19 @@
;;
(setf (documentation 'socket-connect 'function)
- "Connect to `host' on `port'. `host' is assumed to be a string of
+ "Connect to `host' on `port'. `host' is assumed to be a string or
an IP address represented in vector notation, such as #(192 168 1 1).
`port' is assumed to be an integer.
Returns a usocket object.")
+;; Documentation for the function
+;;
+;; (defun SOCKET-LISTEN (host port &key local-ip local-port
+;; reuseaddress backlog) ..)
+
+
+;; Documentation for the function
+;;
+;; (defun SOCKET-ACCEPT (socket &key element-type external-format
+;; buffered timeout) ..)
More information about the usocket-cvs
mailing list