["/*\t$NetBSD: svr4_32_sockio.c,v PI:FP:1.2.10.1END_PI 2002/07/22 14:53:27 lukem Exp $\t */\n\n/*-\n * Copyright (c) 1995 The NetBSD Foundation, Inc.\n * All rights reserved.\n *\n * This code is derived from software contributed to The NetBSD Foundation\n * by Christos Zoulas.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. All advertising materials mentioning features or use of this software\n * must display the following acknowledgement:\n * This product includes software developed by the NetBSD\n * Foundation, Inc. and its contributors.\n * 4. Neither the name of The NetBSD Foundation nor the names of its\n * contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS\n * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\n * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS\n * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n * POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \n__KERNEL_RCSID(0, \"$NetBSD: svr4_32_sockio.c,v PI:FP:1.2.10.1END_PI 2002/07/22 14:53:27 lukem Exp $\");\n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\nstatic int bsd_to_svr4_flags __P((int));\n\n#define bsd_to_svr4_flag(a) \\\n\tif (bf & __CONCAT(I,a))\tsf |= __CONCAT(SVR4_I,a)\n\nstatic int\nbsd_to_svr4_flags(bf)\n\tint bf;\n{\n\tint sf = 0;\n\tbsd_to_svr4_flag(FF_UP);\n\tbsd_to_svr4_flag(FF_BROADCAST);\n\tbsd_to_svr4_flag(FF_DEBUG);\n\tbsd_to_svr4_flag(FF_LOOPBACK);\n\tbsd_to_svr4_flag(FF_POINTOPOINT);\n\tbsd_to_svr4_flag(FF_NOTRAILERS);\n\tbsd_to_svr4_flag(FF_RUNNING);\n\tbsd_to_svr4_flag(FF_NOARP);\n\tbsd_to_svr4_flag(FF_PROMISC);\n\tbsd_to_svr4_flag(FF_ALLMULTI);\n\tbsd_to_svr4_flag(FF_MULTICAST);\n\treturn sf;\n}\n\nint\nsvr4_32_sock_ioctl(fp, p, retval, fd, cmd, data)\n\tstruct file *fp;\n\tstruct proc *p;\n\tregister_t *retval;\n\tint fd;\n\tu_long cmd;\n\tcaddr_t data;\n{\n\tint error;\n\tint (*ctl) __P((struct file *, u_long, caddr_t, struct proc *)) =\n\t\t\tfp->f_ops->fo_ioctl;\n\n\t*retval = 0;\n\n\tswitch (cmd) {\n\tcase SVR4_SIOCGIFNUM:\n\t\t{\n\t\t\tstruct ifnet *ifp;\n\t\t\tstruct ifaddr *ifa;\n\t\t\tint ifnum = 0;\n\n\t\t\t/*\n\t\t\t * This does not return the number of physical\n\t\t\t * interfaces (if_index), but the number of interfaces\n\t\t\t * + addresses like ifconf() does, because this number\n\t\t\t * is used by code that will call SVR4_SIOCGIFCONF to\n\t\t\t * find the space needed for SVR4_SIOCGIFCONF. So we\n\t\t\t * count the number of ifreq entries that the next\n\t\t\t * SVR4_SIOCGIFCONF will return. Maybe a more correct\n\t\t\t * fix is to make SVR4_SIOCGIFCONF return only one\n\t\t\t * entry per physical interface?\n\t\t\t */\n\n\t\t\tfor (ifp = ifnet.tqh_first;\n\t\t\t ifp != 0; ifp = ifp->if_list.tqe_next)\n\t\t\t\tif ((ifa = ifp->if_addrlist.tqh_first) == NULL)\n\t\t\t\t\tifnum++;\n\t\t\t\telse\n\t\t\t\t\tfor (;ifa != NULL;\n\t\t\t\t\t ifa = ifa->ifa_list.tqe_next)\n\t\t\t\t\t\tifnum++;\n\n\n\t\t\tDPRINTF((\"SIOCGIFNUM %d\\n\", ifnum));\n\t\t\treturn copyout(&ifnum, data, sizeof(ifnum));\n\t\t}\n\n\tcase SVR4_32_SIOCGIFFLAGS:\n\t\t{\n\t\t\tstruct ifreq br;\n\t\t\tstruct svr4_32_ifreq sr;\n\n\t\t\tif ((error = copyin(data, &sr, sizeof(sr))) != 0)\n\t\t\t\treturn error;\n\n\t\t\t(void) strncpy(br.ifr_name, sr.svr4_ifr_name,\n\t\t\t sizeof(br.ifr_name));\n\n\t\t\tif ((error = (*ctl)(fp, SIOCGIFFLAGS, \n\t\t\t\t\t (caddr_t) &br, p)) != 0) {\n\t\t\t\tDPRINTF((\"SIOCGIFFLAGS %s: error %d\\n\", \n\t\t\t\t\t sr.svr4_ifr_name, error));\n\t\t\t\treturn error;\n\t\t\t}\n\n\t\t\tsr.svr4_ifr_flags = bsd_to_svr4_flags(br.ifr_flags);\n\t\t\tDPRINTF((\"SIOCGIFFLAGS %s = %x\\n\", \n\t\t\t\tsr.svr4_ifr_name, sr.svr4_ifr_flags));\n\t\t\treturn copyout(&sr, data, sizeof(sr));\n\t\t}\n\n\tcase SVR4_32_SIOCGIFCONF:\n\t\t{\n\t\t\tstruct svr4_32_ifconf sc;\n\t\t\tstruct ifconf ifc;\n\n\t\t\tif ((error = copyin(data, &sc, sizeof(sc))) != 0)\n\t\t\t\treturn error;\n\n\t\t\tDPRINTF((\"ifreq %ld svr4_32_ifreq %ld ifc_len %d\\n\",\n\t\t\t\t(unsigned long)sizeof(struct ifreq),\n\t\t\t\t(unsigned long)sizeof(struct svr4_32_ifreq),\n\t\t\t\tsc.svr4_32_ifc_len));\n\n\t\t\tifc.ifc_len = sc.svr4_32_ifc_len;\n\t\t\tifc.ifc_buf = (caddr_t)(uintptr_t)sc.ifc_ifcu.ifcu_buf;\n\n\t\t\tif ((error = (*ctl)(fp, OSIOCGIFCONF,\n\t\t\t\t\t (caddr_t) &ifc, p)) != 0)\n\t\t\t\treturn error;\n\n\t\t\tDPRINTF((\"SIOCGIFCONF\\n\"));\n\t\t\treturn 0;\n\t\t}\n\n\n\tdefault:\n\t\tDPRINTF((\"Unknown svr4_32 sockio %lx\\n\", cmd));\n\t\treturn 0;\t/* ENOSYS really */\n\t}\n}\n", "/*\n Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file\n\n This file is part of 0MQ.\n\n 0MQ is free software; you can redistribute it and/or modify it under\n the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation; either version 3 of the License, or\n (at your option) any later version.\n\n 0MQ is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with this program. If not, see .\n*/\n\n#include \"platform.hpp\"\n\n#ifdef ZMQ_HAVE_OPENPGM\n\n#ifdef ZMQ_HAVE_WINDOWS\n#include \"windows.hpp\"\n#endif\n\n#ifdef ZMQ_HAVE_LINUX\n#include \n#endif\n\n#include \n#include \n#include \n\n#include \"options.hpp\"\n#include \"pgm_socket.hpp\"\n#include \"config.hpp\"\n#include \"err.hpp\"\n#include \"random.hpp\"\n#include \"stdint.hpp\"\n\n#ifndef MSG_ERRQUEUE\n#define MSG_ERRQUEUE 0x2000\n#endif\n\nzmq::pgm_socket_t::pgm_socket_t (bool receiver_, const options_t &options_) :\n sock (NULL),\n options (options_),\n receiver (receiver_),\n pgm_msgv (NULL),\n pgm_msgv_len (0),\n nbytes_rec (0),\n nbytes_processed (0),\n pgm_msgv_processed (0)\n{\n}\n\n// Resolve PGM socket address.\n// network_ of the form :\n// e.g. eth0;PI:FP:239.192.0.1END_PI:7500\n// link-local;224.250.0.1,224.250.0.2;PI:FP:224.250.0.3END_PI:8000\n// ;[fe80::1%en0]:7500\nint zmq::pgm_socket_t::init_address (const char *network_,\n struct pgm_addrinfo_t **res, uint16_t *port_number)\n{\n // Parse port number, start from end for IPv6\n const char *port_delim = strrchr (network_, ':');\n if (!port_delim) {\n errno = EINVAL;\n return -1;\n }\n\n *port_number = atoi (port_delim + 1);\n \n char network [256];\n if (port_delim - network_ >= (int) sizeof (network) - 1) {\n errno = EINVAL;\n return -1;\n }\n memset (network, '\\0', sizeof (network));\n memcpy (network, network_, port_delim - network_);\n\n pgm_error_t *pgm_error = NULL;\n struct pgm_addrinfo_t hints;\n\n memset (&hints, 0, sizeof (hints));\n hints.ai_family = AF_UNSPEC;\n if (!pgm_getaddrinfo (network, NULL, res, &pgm_error)) {\n\n // Invalid parameters don't set pgm_error_t.\n zmq_assert (pgm_error != NULL);\n if (pgm_error->domain == PGM_ERROR_DOMAIN_IF &&\n\n // NB: cannot catch EAI_BADFLAGS.\n ( pgm_error->code != PGM_ERROR_SERVICE &&\n pgm_error->code != PGM_ERROR_SOCKTNOSUPPORT)) {\n\n // User, host, or network configuration or transient error.\n pgm_error_free (pgm_error);\n errno = EINVAL;\n return -1;\n }\n\n // Fatal OpenPGM internal error.\n zmq_assert (false);\n }\n return 0;\n}\n\n// Create, bind and connect PGM socket.\nint zmq::pgm_socket_t::init (bool udp_encapsulation_, const char *network_)\n{\n // Can not open transport before destroying old one.\n zmq_assert (sock == NULL);\n zmq_assert (options.rate > 0);\n\n // Zero counter used in msgrecv.\n nbytes_rec = 0;\n nbytes_processed = 0;\n pgm_msgv_processed = 0;\n\n uint16_t port_number;\n struct pgm_addrinfo_t *res = NULL;\n sa_family_t sa_family;\n\n pgm_error_t *pgm_error = NULL;\n\n if (init_address(network_, &res, &port_number) < 0) {\n goto err_abort;\n }\n\n zmq_assert (res != NULL);\n\n // Pick up detected IP family.\n sa_family = res->ai_send_addrs[0].gsr_group.ss_family;\n\n // Create IP/PGM or UDP/PGM socket.\n if (udp_encapsulation_) {\n if (!pgm_socket (&sock, sa_family, SOCK_SEQPACKET, IPPROTO_UDP,\n &pgm_error)) {\n\n // Invalid parameters don't set pgm_error_t.\n zmq_assert (pgm_error != NULL);\n if (pgm_error->domain == PGM_ERROR_DOMAIN_SOCKET && (\n pgm_error->code != PGM_ERROR_BADF &&\n pgm_error->code != PGM_ERROR_FAULT &&\n pgm_error->code != PGM_ERROR_NOPROTOOPT &&\n pgm_error->code != PGM_ERROR_FAILED))\n\n // User, host, or network configuration or transient error.\n goto err_abort;\n\n // Fatal OpenPGM internal error.\n zmq_assert (false);\n }\n\n // All options are of data type int\n const int encapsulation_port = port_number;\n if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_UDP_ENCAP_UCAST_PORT,\n &encapsulation_port, sizeof (encapsulation_port)))\n goto err_abort;\n if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_UDP_ENCAP_MCAST_PORT,\n &encapsulation_port, sizeof (encapsulation_port)))\n goto err_abort;\n }\n else {\n if (!pgm_socket (&sock, sa_family, SOCK_SEQPACKET, IPPROTO_PGM,\n &pgm_error)) {\n\n // Invalid parameters don't set pgm_error_t.\n zmq_assert (pgm_error != NULL);\n if (pgm_error->domain == PGM_ERROR_DOMAIN_SOCKET && (\n pgm_error->code != PGM_ERROR_BADF &&\n pgm_error->code != PGM_ERROR_FAULT &&\n pgm_error->code != PGM_ERROR_NOPROTOOPT &&\n pgm_error->code != PGM_ERROR_FAILED))\n\n // User, host, or network configuration or transient error.\n goto err_abort;\n\n // Fatal OpenPGM internal error.\n zmq_assert (false);\n }\n }\n\n {\n\t\tconst int rcvbuf = (int) options.rcvbuf;\n\t\tif (rcvbuf) {\n\t\t if (!pgm_setsockopt (sock, SOL_SOCKET, SO_RCVBUF, &rcvbuf,\n\t\t sizeof (rcvbuf)))\n\t\t goto err_abort;\n\t\t}\n\n\t\tconst int sndbuf = (int) options.sndbuf;\n\t\tif (sndbuf) {\n\t\t if (!pgm_setsockopt (sock, SOL_SOCKET, SO_SNDBUF, &sndbuf,\n\t\t sizeof (sndbuf)))\n\t\t goto err_abort;\n\t\t}\n\n\t\tconst int max_tpdu = (int) pgm_max_tpdu;\n\t\tif (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_MTU, &max_tpdu,\n\t\t sizeof (max_tpdu)))\n\t\t goto err_abort;\n }\n\n if (receiver) {\n const int recv_only = 1,\n rxw_max_tpdu = (int) pgm_max_tpdu,\n rxw_sqns = compute_sqns (rxw_max_tpdu),\n peer_expiry = pgm_secs (300),\n spmr_expiry = pgm_msecs (25),\n nak_bo_ivl = pgm_msecs (50),\n nak_rpt_ivl = pgm_msecs (200),\n nak_rdata_ivl = pgm_msecs (200),\n nak_data_retries = 50,\n nak_ncf_retries = 50;\n\n if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_RECV_ONLY, &recv_only,\n sizeof (recv_only)) ||\n !pgm_setsockopt (sock, IPPROTO_PGM, PGM_RXW_SQNS, &rxw_sqns,\n sizeof (rxw_sqns)) ||\n !pgm_setsockopt (sock, IPPROTO_PGM, PGM_PEER_EXPIRY, &peer_expiry,\n sizeof (peer_expiry)) ||\n !pgm_setsockopt (sock, IPPROTO_PGM, PGM_SPMR_EXPIRY, &spmr_expiry,\n sizeof (spmr_expiry)) ||\n !pgm_setsockopt (sock, IPPROTO_PGM, PGM_NAK_BO_IVL, &nak_bo_ivl,\n sizeof (nak_bo_ivl)) ||\n !pgm_setsockopt (sock, IPPROTO_PGM, PGM_NAK_RPT_IVL, &nak_rpt_ivl,\n sizeof (nak_rpt_ivl)) ||\n !pgm_setsockopt (sock, IPPROTO_PGM, PGM_NAK_RDATA_IVL,\n &nak_rdata_ivl, sizeof (nak_rdata_ivl)) ||\n !pgm_setsockopt (sock, IPPROTO_PGM, PGM_NAK_DATA_RETRIES,\n &nak_data_retries, sizeof (nak_data_retries)) ||\n !pgm_setsockopt (sock, IPPROTO_PGM, PGM_NAK_NCF_RETRIES,\n &nak_ncf_retries, sizeof (nak_ncf_retries)))\n goto err_abort;\n }\n else {\n const int send_only = 1,\n max_rte = (int) ((options.rate * 1000) / 8),\n txw_max_tpdu = (int) pgm_max_tpdu,\n txw_sqns = compute_sqns (txw_max_tpdu),\n ambient_spm = pgm_secs (30),\n heartbeat_spm[] = { pgm_msecs (100),\n pgm_msecs (100),\n pgm_msecs (100),\n pgm_msecs (100),\n pgm_msecs (1300),\n pgm_secs (7),\n pgm_secs (16),\n pgm_secs (25),\n pgm_secs (30) };\n\n if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_SEND_ONLY,\n &send_only, sizeof (send_only)) ||\n !pgm_setsockopt (sock, IPPROTO_PGM, PGM_ODATA_MAX_RTE,\n &max_rte, sizeof (max_rte)) ||\n !pgm_setsockopt (sock, IPPROTO_PGM, PGM_TXW_SQNS,\n &txw_sqns, sizeof (txw_sqns)) ||\n !pgm_setsockopt (sock, IPPROTO_PGM, PGM_AMBIENT_SPM,\n &ambient_spm, sizeof (ambient_spm)) ||\n !pgm_setsockopt (sock, IPPROTO_PGM, PGM_HEARTBEAT_SPM,\n &heartbeat_spm, sizeof (heartbeat_spm)))\n goto err_abort;\n }\n\n // PGM transport GSI.\n struct pgm_sockaddr_t addr;\n\n memset (&addr, 0, sizeof(addr));\n addr.sa_port = port_number;\n addr.sa_addr.sport = DEFAULT_DATA_SOURCE_PORT;\n\n // Create random GSI.\n uint32_t buf [2];\n buf [0] = generate_random ();\n buf [1] = generate_random ();\n if (!pgm_gsi_create_from_data (&addr.sa_addr.gsi, (uint8_t*) buf, 8))\n goto err_abort;\n\n\n // Bind a transport to the specified network devices.\n struct pgm_interface_req_t if_req;\n memset (&if_req, 0, sizeof(if_req));\n if_req.ir_interface = res->ai_recv_addrs[0].gsr_interface;\n if_req.ir_scope_id = 0;\n if (AF_INET6 == sa_family) {\n struct sockaddr_in6 sa6;\n memcpy (&sa6, &res->ai_recv_addrs[0].gsr_group, sizeof (sa6));\n if_req.ir_scope_id = sa6.sin6_scope_id;\n }\n if (!pgm_bind3 (sock, &addr, sizeof (addr), &if_req, sizeof (if_req),\n &if_req, sizeof (if_req), &pgm_error)) {\n\n // Invalid parameters don't set pgm_error_t.\n zmq_assert (pgm_error != NULL);\n if ((pgm_error->domain == PGM_ERROR_DOMAIN_SOCKET ||\n pgm_error->domain == PGM_ERROR_DOMAIN_IF) && (\n pgm_error->code != PGM_ERROR_INVAL &&\n pgm_error->code != PGM_ERROR_BADF &&\n pgm_error->code != PGM_ERROR_FAULT))\n\n // User, host, or network configuration or transient error.\n goto err_abort;\n\n // Fatal OpenPGM internal error.\n zmq_assert (false);\n }\n\n // Join IP multicast groups.\n for (unsigned i = 0; i < res->ai_recv_addrs_len; i++) {\n if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_JOIN_GROUP,\n &res->ai_recv_addrs [i], sizeof (struct group_req)))\n goto err_abort;\n }\n if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_SEND_GROUP,\n &res->ai_send_addrs [0], sizeof (struct group_req)))\n goto err_abort;\n\n pgm_freeaddrinfo (res);\n res = NULL;\n\n // Set IP level parameters.\n {\n\t\t// Multicast loopback disabled by default\n\t\tconst int multicast_loop = 0;\n\t\tif (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_MULTICAST_LOOP,\n\t\t &multicast_loop, sizeof (multicast_loop)))\n\t\t goto err_abort;\n\n\t\tconst int multicast_hops = options.multicast_hops;\n\t\tif (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_MULTICAST_HOPS,\n\t\t &multicast_hops, sizeof (multicast_hops)))\n\t\t goto err_abort;\n\n\t\t// Expedited Forwarding PHB for network elements, no ECN.\n\t\t// Ignore return value due to varied runtime support.\n\t\tconst int dscp = 0x2e << 2;\n\t\tif (AF_INET6 != sa_family)\n\t\t pgm_setsockopt (sock, IPPROTO_PGM, PGM_TOS,\n\t\t &dscp, sizeof (dscp));\n\n\t\tconst int nonblocking = 1;\n\t\tif (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_NOBLOCK,\n\t\t &nonblocking, sizeof (nonblocking)))\n\t\t goto err_abort;\n }\n\n // Connect PGM transport to start state machine.\n if (!pgm_connect (sock, &pgm_error)) {\n\n // Invalid parameters don't set pgm_error_t.\n zmq_assert (pgm_error != NULL);\n goto err_abort;\n }\n\n // For receiver transport preallocate pgm_msgv array.\n if (receiver) {\n zmq_assert (in_batch_size > 0);\n size_t max_tsdu_size = get_max_tsdu_size ();\n pgm_msgv_len = (int) in_batch_size / max_tsdu_size;\n if ((int) in_batch_size % max_tsdu_size)\n pgm_msgv_len++;\n zmq_assert (pgm_msgv_len);\n\n pgm_msgv = (pgm_msgv_t*) malloc (sizeof (pgm_msgv_t) * pgm_msgv_len);\n alloc_assert (pgm_msgv);\n }\n\n return 0;\n\nerr_abort:\n if (sock != NULL) {\n pgm_close (sock, FALSE);\n sock = NULL;\n }\n if (res != NULL) {\n pgm_freeaddrinfo (res);\n res = NULL;\n }\n if (pgm_error != NULL) {\n pgm_error_free (pgm_error);\n pgm_error = NULL;\n }\n errno = EINVAL;\n return -1;\n}\n\nzmq::pgm_socket_t::~pgm_socket_t ()\n{\n if (pgm_msgv)\n free (pgm_msgv);\n if (sock) \n pgm_close (sock, TRUE);\n}\n\n// Get receiver fds. receive_fd_ is signaled for incoming packets,\n// waiting_pipe_fd_ is signaled for state driven events and data.\nvoid zmq::pgm_socket_t::get_receiver_fds (fd_t *receive_fd_, \n fd_t *waiting_pipe_fd_)\n{\n socklen_t socklen;\n bool rc;\n\n zmq_assert (receive_fd_);\n zmq_assert (waiting_pipe_fd_);\n\n socklen = sizeof (*receive_fd_);\n rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_RECV_SOCK, receive_fd_,\n &socklen);\n zmq_assert (rc);\n zmq_assert (socklen == sizeof (*receive_fd_));\n\n socklen = sizeof (*waiting_pipe_fd_);\n rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_PENDING_SOCK, waiting_pipe_fd_,\n &socklen);\n zmq_assert (rc);\n zmq_assert (socklen == sizeof (*waiting_pipe_fd_));\n}\n\n// Get fds and store them into user allocated memory. \n// send_fd is for non-blocking send wire notifications.\n// receive_fd_ is for incoming back-channel protocol packets.\n// rdata_notify_fd_ is raised for waiting repair transmissions.\n// pending_notify_fd_ is for state driven events.\nvoid zmq::pgm_socket_t::get_sender_fds (fd_t *send_fd_, fd_t *receive_fd_, \n fd_t *rdata_notify_fd_, fd_t *pending_notify_fd_)\n{\n socklen_t socklen;\n bool rc;\n\n zmq_assert (send_fd_);\n zmq_assert (receive_fd_);\n zmq_assert (rdata_notify_fd_);\n zmq_assert (pending_notify_fd_);\n\n socklen = sizeof (*send_fd_);\n rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_SEND_SOCK, send_fd_, &socklen);\n zmq_assert (rc);\n zmq_assert (socklen == sizeof (*receive_fd_));\n\n socklen = sizeof (*receive_fd_);\n rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_RECV_SOCK, receive_fd_,\n &socklen);\n zmq_assert (rc);\n zmq_assert (socklen == sizeof (*receive_fd_));\n\n socklen = sizeof (*rdata_notify_fd_);\n rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_REPAIR_SOCK, rdata_notify_fd_,\n &socklen);\n zmq_assert (rc);\n zmq_assert (socklen == sizeof (*rdata_notify_fd_));\n\n socklen = sizeof (*pending_notify_fd_);\n rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_PENDING_SOCK,\n pending_notify_fd_, &socklen);\n zmq_assert (rc);\n zmq_assert (socklen == sizeof (*pending_notify_fd_));\n}\n\n// Send one APDU, transmit window owned memory.\n// data_len_ must be less than one TPDU.\nsize_t zmq::pgm_socket_t::send (unsigned char *data_, size_t data_len_)\n{\n size_t nbytes = 0;\n \n const int status = pgm_send (sock, data_, data_len_, &nbytes);\n\n // We have to write all data as one packet.\n if (nbytes > 0) {\n zmq_assert (status == PGM_IO_STATUS_NORMAL);\n zmq_assert (nbytes == data_len_);\n }\n else {\n zmq_assert (status == PGM_IO_STATUS_RATE_LIMITED ||\n status == PGM_IO_STATUS_WOULD_BLOCK);\n\n if (status == PGM_IO_STATUS_RATE_LIMITED)\n errno = ENOMEM;\n else\n errno = EBUSY;\n }\n\n // Save return value.\n last_tx_status = status;\n\n return nbytes;\n}\n\nlong zmq::pgm_socket_t::get_rx_timeout ()\n{\n if (last_rx_status != PGM_IO_STATUS_RATE_LIMITED &&\n last_rx_status != PGM_IO_STATUS_TIMER_PENDING)\n return -1;\n\n struct timeval tv;\n socklen_t optlen = sizeof (tv);\n const bool rc = pgm_getsockopt (sock, IPPROTO_PGM,\n last_rx_status == PGM_IO_STATUS_RATE_LIMITED ? PGM_RATE_REMAIN :\n PGM_TIME_REMAIN, &tv, &optlen);\n zmq_assert (rc);\n\n const long timeout = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);\n\n return timeout;\n}\n\nlong zmq::pgm_socket_t::get_tx_timeout ()\n{\n if (last_tx_status != PGM_IO_STATUS_RATE_LIMITED)\n return -1;\n\n struct timeval tv;\n socklen_t optlen = sizeof (tv);\n const bool rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_RATE_REMAIN, &tv,\n &optlen);\n zmq_assert (rc);\n\n const long timeout = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);\n\n return timeout;\n}\n\n// Return max TSDU size without fragmentation from current PGM transport.\nsize_t zmq::pgm_socket_t::get_max_tsdu_size ()\n{\n int max_tsdu = 0;\n socklen_t optlen = sizeof (max_tsdu);\n\n bool rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_MSS, &max_tsdu, &optlen);\n zmq_assert (rc);\n zmq_assert (optlen == sizeof (max_tsdu));\n return (size_t) max_tsdu;\n}\n\n// pgm_recvmsgv is called to fill the pgm_msgv array up to pgm_msgv_len.\n// In subsequent calls data from pgm_msgv structure are returned.\nssize_t zmq::pgm_socket_t::receive (void **raw_data_, const pgm_tsi_t **tsi_)\n{\n size_t raw_data_len = 0;\n\n // We just sent all data from pgm_transport_recvmsgv up \n // and have to return 0 that another engine in this thread is scheduled.\n if (nbytes_rec == nbytes_processed && nbytes_rec > 0) {\n\n // Reset all the counters.\n nbytes_rec = 0;\n nbytes_processed = 0;\n pgm_msgv_processed = 0;\n errno = EAGAIN;\n return 0;\n }\n\n // If we have are going first time or if we have processed all pgm_msgv_t\n // structure previously read from the pgm socket.\n if (nbytes_rec == nbytes_processed) {\n\n // Check program flow.\n zmq_assert (pgm_msgv_processed == 0);\n zmq_assert (nbytes_processed == 0);\n zmq_assert (nbytes_rec == 0);\n\n // Receive a vector of Application Protocol Domain Unit's (APDUs) \n // from the transport.\n pgm_error_t *pgm_error = NULL;\n\n const int status = pgm_recvmsgv (sock, pgm_msgv,\n pgm_msgv_len, MSG_ERRQUEUE, &nbytes_rec, &pgm_error);\n\n // Invalid parameters.\n zmq_assert (status != PGM_IO_STATUS_ERROR);\n\n last_rx_status = status;\n\n // In a case when no ODATA/RDATA fired POLLIN event (SPM...)\n // pgm_recvmsg returns PGM_IO_STATUS_TIMER_PENDING.\n if (status == PGM_IO_STATUS_TIMER_PENDING) {\n\n zmq_assert (nbytes_rec == 0);\n\n // In case if no RDATA/ODATA caused POLLIN 0 is \n // returned.\n nbytes_rec = 0;\n errno = EBUSY;\n return 0;\n }\n\n // Send SPMR, NAK, ACK is rate limited.\n if (status == PGM_IO_STATUS_RATE_LIMITED) {\n\n zmq_assert (nbytes_rec == 0);\n\n // In case if no RDATA/ODATA caused POLLIN 0 is returned.\n nbytes_rec = 0;\n errno = ENOMEM;\n return 0;\n }\n\n // No peers and hence no incoming packets.\n if (status == PGM_IO_STATUS_WOULD_BLOCK) {\n\n zmq_assert (nbytes_rec == 0);\n\n // In case if no RDATA/ODATA caused POLLIN 0 is returned.\n nbytes_rec = 0;\n errno = EAGAIN;\n return 0;\n }\n\n // Data loss.\n if (status == PGM_IO_STATUS_RESET) {\n\n struct pgm_sk_buff_t* skb = pgm_msgv [0].msgv_skb [0];\n\n // Save lost data TSI.\n *tsi_ = &skb->tsi;\n nbytes_rec = 0;\n\n // In case of dala loss -1 is returned.\n errno = EINVAL;\n pgm_free_skb (skb);\n return -1;\n }\n\n zmq_assert (status == PGM_IO_STATUS_NORMAL);\n }\n else\n {\n zmq_assert (pgm_msgv_processed <= pgm_msgv_len);\n }\n\n // Zero byte payloads are valid in PGM, but not 0MQ protocol.\n zmq_assert (nbytes_rec > 0);\n\n // Only one APDU per pgm_msgv_t structure is allowed.\n zmq_assert (pgm_msgv [pgm_msgv_processed].msgv_len == 1);\n \n struct pgm_sk_buff_t* skb = \n pgm_msgv [pgm_msgv_processed].msgv_skb [0];\n\n // Take pointers from pgm_msgv_t structure.\n *raw_data_ = skb->data;\n raw_data_len = skb->len;\n\n // Save current TSI.\n *tsi_ = &skb->tsi;\n\n // Move the the next pgm_msgv_t structure.\n pgm_msgv_processed++;\n zmq_assert (pgm_msgv_processed <= pgm_msgv_len);\n nbytes_processed +=raw_data_len;\n\n return raw_data_len;\n}\n\nvoid zmq::pgm_socket_t::process_upstream ()\n{\n pgm_msgv_t dummy_msg;\n\n size_t dummy_bytes = 0;\n pgm_error_t *pgm_error = NULL;\n\n const int status = pgm_recvmsgv (sock, &dummy_msg,\n 1, MSG_ERRQUEUE, &dummy_bytes, &pgm_error);\n\n // Invalid parameters.\n zmq_assert (status != PGM_IO_STATUS_ERROR);\n\n // No data should be returned.\n zmq_assert (dummy_bytes == 0 && (status == PGM_IO_STATUS_TIMER_PENDING || \n status == PGM_IO_STATUS_RATE_LIMITED ||\n status == PGM_IO_STATUS_WOULD_BLOCK));\n\n last_rx_status = status;\n\n if (status == PGM_IO_STATUS_TIMER_PENDING)\n errno = EBUSY;\n else\n if (status == PGM_IO_STATUS_RATE_LIMITED)\n errno = ENOMEM;\n else\n errno = EAGAIN;\n}\n\nint zmq::pgm_socket_t::compute_sqns (int tpdu_)\n{\n // Convert rate into B/ms.\n uint64_t rate = uint64_t (options.rate) / 8;\n \n // Compute the size of the buffer in bytes.\n uint64_t size = uint64_t (options.recovery_ivl) * rate;\n\n // Translate the size into number of packets.\n uint64_t sqns = size / tpdu_;\n\n // Buffer should be able to hold at least one packet.\n if (sqns == 0)\n sqns = 1;\n\n return (int) sqns;\n}\n\n#endif\n\n", "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _react = require('react');\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _pure = require('recompose/pure');\n\nvar _pure2 = _interopRequireDefault(_pure);\n\nvar _SvgIcon = require('material-ui/SvgIcon');\n\nvar _SvgIcon2 = _interopRequireDefault(_SvgIcon);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar SvgIconCustom = global.__MUI_SvgIcon__ || _SvgIcon2.default;\n\nvar _ref = _react2.default.createElement('path', { d: 'M0 7.72V9.4l3-1V18h2V6h-.25L0 7.72zm23.78 6.65c-.14-.28-.35-.53-.63-.74-.28-.21-.61-.39-1.01-.53s-.85-.27-1.35-.38c-.35-.07-.64-.15-.87-.23-.23-.08-.41-.16-.55-.25-.14-.09-.23-.19-.28-.3-.05-.11-.08-.24-.08-.39 0-.14.03-.28.09-.41.06-.13.15-.25.27-.34.12-.1.27-.18.45-.24s.4-.09.64-.09c.25 0 .PI:FP:47.04.66.11END_PI.19.07.35.17.48.29.13.12.22.26.29.PI:FP:42.06.16.1END_PI.32.1.49h1.95c0-.39-.08-.75-.24-1.09-.16-.34-.39-.63-.69-.88-.3-.25-.66-.44-1.09-.59C21.49 9.07 21 9 20.46 9c-.51 0-.98.07-1.39.21-.41.14-.77.33-1.06.57-.29.24-.51.52-.67.84-.16.32-.23.65-.23 1.01s.08.69.23.96c.15.28.36.52.64.PI:FP:73.27.21.6END_PI.38.PI:FP:98.53.38.14END_PI.81.26 PI:FP:1.27.36.39END_PI.08.71.17.95.26s.43.19.57.29c.PI:FP:13.1.22.22END_PI.27.34.05.12.07.25.07.39 0 .32-.13.57-.4.77-.27.2-.66.29-1.17.29-.22 0-.43-.02-.64-.08-.21-.05-.4-.13-.56-.24-.17-.11-.3-.26-.41-.44-.11-.18-.17-.41-.18-.67h-1.89c0 .36.08.71.24 1.05.16.34.39.65.PI:FP:7.93.31.27END_PI.69.49 PI:FP:1.15.66.46END_PI.17.98.25 PI:FP:1.58.25.53END_PI 0 1.01-.06 1.44-.19.43-.13.8-.31 1.11-.54.31-.23.54-.51.71-.83.17-.32.25-.67.25-1.06-.02-.4-.09-.74-.24-1.02zm-9.96-7.32c-.34-.4-.75-.7-1.23-.88-.47-.18-1.01-.27-1.59-.27-.58 0-1.11.09-1.59.27-.48.18-.89.47-1.23.88-.34.41-.6.93-.79 1.59-.18.65-.28 1.45-.28 2.39v1.92c0 .94.09 1.74.28 PI:FP:2.39.19.66END_PI.45 1.19.8 PI:FP:1.6.34.41END_PI.75.71 PI:FP:1.23.89.48END_PI.18 1.01.28 PI:FP:1.59.28.59END_PI 0 1.12-.09 1.59-.28.48-.18.88-.48 1.22-.89.34-.41.6-.94.78-1.6.18-.65.28-1.45.28-2.39v-1.92c0-.94-.09-1.74-.28-2.39-.18-.66-.44-1.19-.78-1.59zm-.92 6.17c0 .6-.04 1.11-.12 1.53-.08.42-.2.76-.36 1.02-.16.26-.36.45-.59.57-.23.12-.51.18-.82.18-.3 0-.58-.06-.82-.18s-.44-.31-.6-.57c-.16-.26-.29-.6-.38-1.02-.09-.42-.13-.93-.13-1.53v-2.5c0-.6.04-1.11.13-1.52.09-.41.21-.74.38-1 .16-.25.36-.43.6-.55.24-.11.51-.17.81-.17.31 0 .PI:FP:58.06.81.17END_PI.24.PI:FP:11.44.29.6END_PI.55.16.25.29.58.37.PI:FP:99.08.41.13END_PI.92.13 1.52v2.51z' });\n\nvar Timer10 = function Timer10(props) {\n return _react2.default.createElement(\n SvgIconCustom,\n props,\n _ref\n );\n};\n\nTimer10 = (0, _pure2.default)(Timer10);\nTimer10.muiName = 'SvgIcon';\n\nexports.default = Timer10;"]