1#!/usr/bin/perl
2
3use v5;
4use strict;
5use warnings;
6
7use Test::More;
8
9use IO::Socket::IP;
10
11use Errno qw( EACCES );
12use Socket qw( SOL_SOCKET SO_REUSEADDR SO_REUSEPORT SO_BROADCAST );
13
14TODO: {
15   local $TODO = "SO_REUSEADDR doesn't appear to work on cygwin smokers" if $^O eq "cygwin";
16   # I honestly have no idea why this fails, and people don't seem to be able
17   # to reproduce it on a development box. I'll mark it TODO for now until we
18   # can gain any more insight into it.
19
20   my $sock = IO::Socket::IP->new(
21      LocalHost => "127.0.0.1",
22      Type      => SOCK_STREAM,
23      Listen    => 1,
24      ReuseAddr => 1,
25   ) or die "Cannot socket() - $@";
26
27   ok( $sock->getsockopt( SOL_SOCKET, SO_REUSEADDR ), 'SO_REUSEADDR set' );
28
29   $sock = IO::Socket::IP->new(
30      LocalHost => "127.0.0.1",
31      Type      => SOCK_STREAM,
32      Listen    => 1,
33      Sockopts  => [
34         [ SOL_SOCKET, SO_REUSEADDR ],
35      ],
36   ) or die "Cannot socket() - $@";
37
38   ok( $sock->getsockopt( SOL_SOCKET, SO_REUSEADDR ), 'SO_REUSEADDR set via Sockopts' );
39}
40
41SKIP: {
42   # Some OSes don't implement SO_REUSEPORT
43   skip "No SO_REUSEPORT constant", 1 unless defined eval { SO_REUSEPORT };
44   skip "No support for SO_REUSEPORT", 1 unless defined eval {
45      my $s;
46      socket( $s, Socket::PF_INET, Socket::SOCK_STREAM, 0 ) and
47         setsockopt( $s, SOL_SOCKET, SO_REUSEPORT, 1 ) };
48
49   my $sock = IO::Socket::IP->new(
50      LocalHost => "127.0.0.1",
51      Type      => SOCK_STREAM,
52      Listen    => 1,
53      ReusePort => 1,
54   ) or die "Cannot socket() - $@";
55
56   ok( $sock->getsockopt( SOL_SOCKET, SO_REUSEPORT ), 'SO_REUSEPORT set' );
57}
58
59SKIP: {
60   # Some OSes need special privileges to set SO_BROADCAST
61   $! = 0;
62   my $sock = IO::Socket::IP->new(
63      LocalHost => "127.0.0.1",
64      Type      => SOCK_DGRAM,
65      Broadcast => 1,
66   );
67   skip "Privileges required to set broadcast on datagram socket", 1 if !$sock and $! == EACCES;
68   die "Cannot socket() - $@" unless $sock;
69
70   ok( $sock->getsockopt( SOL_SOCKET, SO_BROADCAST ), 'SO_BROADCAST set' );
71}
72
73done_testing;
74