When #+ipv6 also try to resolve an IPv4 address if the connection cannot be established with the IPv6 address. · Issue #75 · usocket/usocket · GitHub
Skip to content

When #+ipv6 also try to resolve an IPv4 address if the connection cannot be established with the IPv6 address. #75

Description

@informatimago

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):

#+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)))))))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions