IMO, there's little reason to split the implementation in two for #-ipv6 and #+ipv6 (openmcl.lisp vs clozure.lisp).
In any case, when #+ipv6, if there is no server behind the IPv6 address, try the IPv4 address!
eg. in clozure.lisp (perhaps other places would apply too):
#+ipv6
(defun socket-connect (host port &key (protocol :stream) element-type
timeout deadline nodelay
local-host local-port)
(when (eq nodelay :if-supported)
(setf nodelay t))
(with-mapped-conditions (nil host)
(let (remote local mcl-sock)
(loop
:for address-family :in '(:internet6 :internet)
:do (tagbody
(setf remote (when (and host port)
(openmcl-socket:resolve-address :host (host-to-hostname host)
:port port
:socket-type protocol
:address-family address-family))
local (when (and local-host local-port)
(openmcl-socket:resolve-address :host (host-to-hostname local-host)
:port local-port
:socket-type protocol
:address-family address-family))
mcl-sock (handler-bind
((ccl:socket-creation-error
(lambda (err)
(if (eq address-family :internet6) ; the first try, let's ignore the error
(go :continue))
(signal err))))
(apply #'openmcl-socket:make-socket
`(:type ,protocol
,@(when (or remote local)
`(:address-family ,(openmcl-socket:socket-address-family (or remote local))))
,@(when remote
`(:remote-address ,remote))
,@(when local
`(:local-address ,local))
:format ,(to-format element-type protocol)
:external-format ,ccl:*default-external-format*
:deadline ,deadline
:nodelay ,nodelay
:connect-timeout ,timeout
:input-timeout ,timeout))))
(loop-finish)
:continue))
(ecase protocol
(:stream
(make-stream-socket :stream mcl-sock :socket mcl-sock))
(:datagram
(make-datagram-socket mcl-sock :connected-p (and remote t)))))))
Related to #66
IMO, there's little reason to split the implementation in two for #-ipv6 and #+ipv6 (openmcl.lisp vs clozure.lisp).
In any case, when #+ipv6, if there is no server behind the IPv6 address, try the IPv4 address!
eg. in clozure.lisp (perhaps other places would apply too):