diff --git a/pkgs/racket-doc/scribblings/reference/networking.scrbl b/pkgs/racket-doc/scribblings/reference/networking.scrbl index 6f098fcaa0..71a44bace7 100644 --- a/pkgs/racket-doc/scribblings/reference/networking.scrbl +++ b/pkgs/racket-doc/scribblings/reference/networking.scrbl @@ -619,6 +619,20 @@ or @racket[0] if the socket is unconnected. If the given port has been closed, the @exnraise[exn:fail:network].} +@deftogether[( +@defproc[(udp-set-ttl! [udp-socket udp?] [ttl byte?]) void?] +@defproc[(udp-ttl [udp-socket udp?]) byte?] +)]{ + +@margin-note{Time-to-live settings correspond to the +@as-index{@tt{IP_TTL}} setting of the socket.} + +Sets or retrieves the current time-to-live setting of +@racket[udp-socket]. + +@history[#:added "7.5.0.5"]} + + @deftogether[( @defproc[(udp-multicast-join-group! [udp-socket udp?] [multicast-addr string?] diff --git a/pkgs/racket-test-core/tests/racket/udp.rktl b/pkgs/racket-test-core/tests/racket/udp.rktl index 9603db3895..85f6dac37c 100644 --- a/pkgs/racket-test-core/tests/racket/udp.rktl +++ b/pkgs/racket-test-core/tests/racket/udp.rktl @@ -55,6 +55,20 @@ (test #f udp-bound? udp1) (test #f udp-connected? udp1) +(define original-ttl (udp-ttl udp1)) +(test #t byte? original-ttl) +(test (void) udp-set-ttl! udp1 255) +(test 255 udp-ttl udp1) +(test (void) udp-set-ttl! udp1 0) +(test 0 udp-ttl udp1) +(test (void) udp-set-ttl! udp1 original-ttl) +(err/rt-test (udp-ttl 0)) +(err/rt-test (udp-ttl 'no)) +(err/rt-test (udp-set-ttl! 0 64)) +(err/rt-test (udp-set-ttl! udp1 -1)) +(err/rt-test (udp-set-ttl! udp1 256)) +(err/rt-test (udp-set-ttl! udp1 'x)) + (err/rt-test (udp-set-receive-buffer-size! udp1 -1)) (err/rt-test (udp-set-receive-buffer-size! udp1 0)) (err/rt-test (udp-set-receive-buffer-size! udp1 (expt 2 300)) diff --git a/racket/src/io/network/error.rkt b/racket/src/io/network/error.rkt index c917974c56..265136ba63 100644 --- a/racket/src/io/network/error.rkt +++ b/racket/src/io/network/error.rkt @@ -3,7 +3,8 @@ "../host/error.rkt") (provide raise-network-error - raise-network-arguments-error) + raise-network-arguments-error + raise-network-option-error) (define (raise-network-error who orig-err base-msg) (define err (remap-rktio-error orig-err)) @@ -37,3 +38,6 @@ "\n socket: " ((error-value->string-handler) u (error-print-width))) (current-continuation-marks)))) + +(define (raise-network-option-error who mode v) + (raise-network-error who v (string-append mode "sockopt failed"))) diff --git a/racket/src/io/network/udp-multicast.rkt b/racket/src/io/network/udp-multicast.rkt index 53d7a760a2..5c4fb04d3e 100644 --- a/racket/src/io/network/udp-multicast.rkt +++ b/racket/src/io/network/udp-multicast.rkt @@ -67,7 +67,7 @@ (define (raise-option-error who mode v) (end-atomic) - (raise-network-error who v (string-append mode "sockopt failed"))) + (raise-network-option-error who mode v)) ;; ---------------------------------------- diff --git a/racket/src/io/network/udp-socket.rkt b/racket/src/io/network/udp-socket.rkt index a4d29a00cc..a2f15d9a35 100644 --- a/racket/src/io/network/udp-socket.rkt +++ b/racket/src/io/network/udp-socket.rkt @@ -17,6 +17,9 @@ udp-bind! udp-connect! + udp-ttl + udp-set-ttl! + check-udp-closed handle-error-immediately udp-default-family @@ -158,10 +161,11 @@ (check who udp? u) (atomically (check-udp-closed who u) - (define v (rktio_udp_ttl rktio (udp-s u))) + (define v (rktio_udp_get_ttl rktio (udp-s u))) (cond [(rktio-error? v) - (raise-option-error who "get" v)] + (end-atomic) + (raise-network-option-error who "get" v)] [else v]))) (define/who (udp-set-ttl! u ttl) @@ -171,4 +175,5 @@ (check-udp-closed who u) (define r (rktio_udp_set_ttl rktio (udp-s u) ttl)) (when (rktio-error? r) - (raise-option-error who "set" r)))) + (end-atomic) + (raise-network-option-error who "set" r)))) diff --git a/racket/src/io/network/udp.rkt b/racket/src/io/network/udp.rkt index e5986d4725..ef9d41a6e7 100644 --- a/racket/src/io/network/udp.rkt +++ b/racket/src/io/network/udp.rkt @@ -11,6 +11,8 @@ udp-connected? udp-bind! udp-connect! + udp-ttl + udp-set-ttl! udp-send udp-send* diff --git a/racket/src/rktio/rktio.rktl b/racket/src/rktio/rktio.rktl index 4cb28e851a..341fd1edf0 100644 --- a/racket/src/rktio/rktio.rktl +++ b/racket/src/rktio/rktio.rktl @@ -596,6 +596,18 @@ rktio_ok_t rktio_udp_set_receive_buffer_size (((ref rktio_t) rktio) ((ref rktio_fd_t) rfd) (int size))) +(define-function/errno + #f + () + rktio_ok_t + rktio_udp_set_ttl + (((ref rktio_t) rktio) ((ref rktio_fd_t) rfd) (int ttl_val))) +(define-function/errno + RKTIO_PROP_ERROR + () + rktio_tri_t + rktio_udp_get_ttl + (((ref rktio_t) rktio) ((ref rktio_fd_t) rfd))) (define-function/errno RKTIO_PROP_ERROR () diff --git a/racket/src/rktio/rktio_network.c b/racket/src/rktio/rktio_network.c index fa7c17ffb3..0cdb330e9e 100644 --- a/racket/src/rktio/rktio_network.c +++ b/racket/src/rktio/rktio_network.c @@ -1955,7 +1955,7 @@ int rktio_udp_set_multicast_loopback(rktio_t *rktio, rktio_fd_t *rfd, int on) int rktio_udp_get_ttl(rktio_t *rktio, rktio_fd_t *rfd) { rktio_socket_t s = rktio_fd_socket(rktio, rfd); - u_char ttl; + int ttl; rktio_sockopt_len_t ttl_len = sizeof(ttl); int status; @@ -1971,7 +1971,7 @@ int rktio_udp_get_ttl(rktio_t *rktio, rktio_fd_t *rfd) int rktio_udp_set_ttl(rktio_t *rktio, rktio_fd_t *rfd, int ttl_val) { rktio_socket_t s = rktio_fd_socket(rktio, rfd); - u_char ttl = ttl_val; + int ttl = ttl_val; rktio_sockopt_len_t ttl_len = sizeof(ttl); int status;