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