summaryrefslogtreecommitdiff
path: root/src/pgm_socket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pgm_socket.cpp')
-rw-r--r--src/pgm_socket.cpp63
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);