diff options
Diffstat (limited to 'src/pgm_socket.cpp')
-rw-r--r-- | src/pgm_socket.cpp | 63 |
1 files changed, 39 insertions, 24 deletions
diff --git a/src/pgm_socket.cpp b/src/pgm_socket.cpp index 7747fe0..bc2c0e4 100644 --- a/src/pgm_socket.cpp +++ b/src/pgm_socket.cpp @@ -67,16 +67,13 @@ xs::pgm_socket_t::pgm_socket_t (bool receiver_, const options_t &options_) : { } -// Create, bind and connect PGM socket. // network_ of the form <interface & multicast group decls>:<IP port> // e.g. eth0;239.192.0.1:7500 // link-local;224.250.0.1,224.250.0.2;224.250.0.3:8000 // ;[fe80::1%en0]:7500 -int xs::pgm_socket_t::init (bool udp_encapsulation_, const char *network_) +int xs::pgm_socket_t::init_address(const char *network_, + struct pgm_addrinfo_t **addr, uint16_t *port_number) { - // Can not open transport before destroying old one. - xs_assert (sock == NULL); - // Parse port number, start from end for IPv6 const char *port_delim = strrchr (network_, ':'); if (!port_delim) { @@ -84,8 +81,8 @@ int xs::pgm_socket_t::init (bool udp_encapsulation_, const char *network_) return -1; } - uint16_t port_number = atoi (port_delim + 1); - + *port_number = atoi (port_delim + 1); + char network [256]; if (port_delim - network_ >= (int) sizeof (network) - 1) { errno = EINVAL; @@ -93,36 +90,54 @@ int xs::pgm_socket_t::init (bool udp_encapsulation_, const char *network_) } memset (network, '\0', sizeof (network)); memcpy (network, network_, port_delim - network_); - - xs_assert (options.rate > 0); - - // Zero counter used in msgrecv. - nbytes_rec = 0; - nbytes_processed = 0; - pgm_msgv_processed = 0; - pgm_error_t *pgm_error = NULL; - struct pgm_addrinfo_t hints, *res = NULL; - sa_family_t sa_family; + struct pgm_addrinfo_t hints; memset (&hints, 0, sizeof (hints)); hints.ai_family = AF_UNSPEC; - if (!pgm_getaddrinfo (network, NULL, &res, &pgm_error)) { + + if (!pgm_getaddrinfo (network, NULL, addr, &pgm_error)) { // Invalid parameters don't set pgm_error_t. xs_assert (pgm_error != NULL); - if (pgm_error->domain == PGM_ERROR_DOMAIN_IF && ( - - // NB: cannot catch EAI_BADFLAGS. - pgm_error->code != PGM_ERROR_SERVICE && - pgm_error->code != PGM_ERROR_SOCKTNOSUPPORT)) + if (pgm_error->domain == PGM_ERROR_DOMAIN_IF && + // NB: cannot catch EAI_BADFLAGS. + ( pgm_error->code != PGM_ERROR_SERVICE && + pgm_error->code != PGM_ERROR_SOCKTNOSUPPORT)) { // User, host, or network configuration or transient error. - goto err_abort; + pgm_error_free (pgm_error); + errno = EINVAL; + return -1; + } // Fatal OpenPGM internal error. xs_assert (false); } + return 0; +} + +// Create, bind and connect PGM socket. +int xs::pgm_socket_t::init (bool udp_encapsulation_, const char *network_) +{ + // Can not open transport before destroying old one. + xs_assert (sock == NULL); + xs_assert (options.rate > 0); + + // Zero counter used in msgrecv. + nbytes_rec = 0; + nbytes_processed = 0; + pgm_msgv_processed = 0; + + uint16_t port_number; + struct pgm_addrinfo_t *res = NULL; + sa_family_t sa_family; + + pgm_error_t *pgm_error = NULL; + + if (init_address(network_, &res, &port_number) < 0) { + goto err_abort; + } xs_assert (res != NULL); |