Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 5 Apr 2014 23:02:46 +0200
From:      Bernd Walter <ticso@cicely7.cicely.de>
To:        freebsd-net@freebsd.org
Cc:        Bernd Walter <ticso@cicely7.cicely.de>
Subject:   SCTP binds to IPs outside of jail
Message-ID:  <20140405210246.GB58138@cicely7.cicely.de>

next in thread | raw e-mail | index | archive | help
So far I've tested this on FreeBSD-9.2 BETA2 r254053M only.
The modifications are to allow IPv6 multicast support within jail
which only makes a difference for multicast addresses and some multicast
loopback checksum bugs - both changes are open PR.

I've created an AF_INET6 SCTP one to many socket to receive incoming
messages.
The process was started within a jail.
Now netstat -anW lists all host IPv6 IPs, not just those of the jail.
Also not sure why this AF_INET6 socket is shown as sctp46.

This is the relevant C++ code part to open the socket:
int
setup_sctp_socket(uint16_t port)
{
        int sc = socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP);
        {
                // reuse address
                long val = 1;
                setsockopt(sc, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
                // XXX error handling
        }
        {
                // no delay
                long val = 1;
                setsockopt(sc, SOL_SOCKET, SCTP_NODELAY, &val, sizeof(val));
                // XXX error handling
        }
        {
                // eeor mode (last write needs MSG_EOR to declare end of message)
                // Linux has MSG_MORE negative send flag
                long val = 1;
                setsockopt(sc, SOL_SOCKET, SCTP_EXPLICIT_EOR, &val, sizeof(val));
                // XXX error handling
        }
#if 0
        {
                struct sctp_initmsg init;
                bzero(&init, sizeof(init));
                init.sinit_num_ostreams = HDB_STREAMS;
                init.sinit_max_instreams = HDB_STREAMS;
                // SOL_SCTP instead of IPPROTO_SCTP on Linux
                setsockopt(sc, IPPROTO_SCTP, SCTP_INITMSG, &init, (socklen_t)sizeof(struct sctp_initmsg));
                // XXX error handling
        }
#endif
        {
                struct sockaddr_in6 addr;
                bzero(&addr, sizeof(addr));
                addr.sin6_len         = sizeof(addr);
                addr.sin6_family      = AF_INET6;
                addr.sin6_port        = htons(port);
                bind(sc, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
                // XXX error handling
        }
        {
                // enable heartbeats at 1000ms
                struct sctp_paddrparams paddr_params;
                bzero(&paddr_params, sizeof(paddr_params));
                paddr_params.spp_address.ss_family = AF_INET6;
                paddr_params.spp_flags = SPP_HB_ENABLE;
                paddr_params.spp_hbinterval = 1000;
                // SOL_SCTP instead of IPPROTO_SCTP on Linux
                setsockopt(sc, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &paddr_params, sizeof(paddr_params)); 
                // XXX error handling
        }
        {
                struct sctp_event_subscribe events;
                bzero(&events, sizeof(events));

                events.sctp_data_io_event = 1; // we need io_events to know where the message came from

                // subscribe to other events as well for testing
                events.sctp_association_event = 1;
                events.sctp_address_event = 1;
                events.sctp_send_failure_event = 1;
                events.sctp_peer_error_event = 1;
                events.sctp_shutdown_event = 1;
                events.sctp_partial_delivery_event = 1;
                events.sctp_adaptation_layer_event = 1;
                events.sctp_authentication_event = 1;
                events.sctp_sender_dry_event = 1;
                events.sctp_stream_reset_event = 1;

                setsockopt(sc, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(events));
                // XXX error handling
        }
        {
                // setup send and receive buffers (default on FreeBSD 9.x)
                long val;
                val = 1864135;
                setsockopt(sc, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val));
                // XXX error handling
                val = 1864135;
                setsockopt(sc, SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
                // XXX error handling
        }
        listen (sc, 1); // listen is required to allow incoming associations, but no listen queue
        // XXX error handling

        return sc;
}

-- 
B.Walter <bernd@bwct.de> http://www.bwct.de
Modbus/TCP Ethernet I/O Baugruppen, ARM basierte FreeBSD Rechner uvm.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140405210246.GB58138>