Commit 4e7be102 authored by Pieter Hintjens's avatar Pieter Hintjens

Merge pull request #354 from steve-o/issue-320

Return error on invalid PGM url instead of raising assertion.
parents 32befeb0 13976a3d
...@@ -23,6 +23,11 @@ ...@@ -23,6 +23,11 @@
#include <string.h> #include <string.h>
#include <limits> #include <limits>
#include "platform.hpp"
#if defined ZMQ_HAVE_WINDOWS
#include "windows.hpp"
#endif
#include "decoder.hpp" #include "decoder.hpp"
#include "session_base.hpp" #include "session_base.hpp"
#include "likely.hpp" #include "likely.hpp"
......
...@@ -59,16 +59,14 @@ zmq::pgm_socket_t::pgm_socket_t (bool receiver_, const options_t &options_) : ...@@ -59,16 +59,14 @@ zmq::pgm_socket_t::pgm_socket_t (bool receiver_, const options_t &options_) :
{ {
} }
// Create, bind and connect PGM socket. // Resolve PGM socket address.
// network_ of the form <interface & multicast group decls>:<IP port> // network_ of the form <interface & multicast group decls>:<IP port>
// e.g. eth0;239.192.0.1:7500 // e.g. eth0;239.192.0.1:7500
// link-local;224.250.0.1,224.250.0.2;224.250.0.3:8000 // link-local;224.250.0.1,224.250.0.2;224.250.0.3:8000
// ;[fe80::1%en0]:7500 // ;[fe80::1%en0]:7500
int zmq::pgm_socket_t::init (bool udp_encapsulation_, const char *network_) int zmq::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.
zmq_assert (sock == NULL);
// Parse port number, start from end for IPv6 // Parse port number, start from end for IPv6
const char *port_delim = strrchr (network_, ':'); const char *port_delim = strrchr (network_, ':');
if (!port_delim) { if (!port_delim) {
...@@ -76,7 +74,7 @@ int zmq::pgm_socket_t::init (bool udp_encapsulation_, const char *network_) ...@@ -76,7 +74,7 @@ int zmq::pgm_socket_t::init (bool udp_encapsulation_, const char *network_)
return -1; return -1;
} }
uint16_t port_number = atoi (port_delim + 1); *port_number = atoi (port_delim + 1);
char network [256]; char network [256];
if (port_delim - network_ >= (int) sizeof (network) - 1) { if (port_delim - network_ >= (int) sizeof (network) - 1) {
...@@ -86,13 +84,6 @@ int zmq::pgm_socket_t::init (bool udp_encapsulation_, const char *network_) ...@@ -86,13 +84,6 @@ int zmq::pgm_socket_t::init (bool udp_encapsulation_, const char *network_)
memset (network, '\0', sizeof (network)); memset (network, '\0', sizeof (network));
memcpy (network, network_, port_delim - network_); memcpy (network, network_, port_delim - network_);
zmq_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; pgm_error_t *pgm_error = NULL;
struct pgm_addrinfo_t hints, *res = NULL; struct pgm_addrinfo_t hints, *res = NULL;
sa_family_t sa_family; sa_family_t sa_family;
...@@ -103,18 +94,45 @@ int zmq::pgm_socket_t::init (bool udp_encapsulation_, const char *network_) ...@@ -103,18 +94,45 @@ int zmq::pgm_socket_t::init (bool udp_encapsulation_, const char *network_)
// Invalid parameters don't set pgm_error_t. // Invalid parameters don't set pgm_error_t.
zmq_assert (pgm_error != NULL); zmq_assert (pgm_error != NULL);
if (pgm_error->domain == PGM_ERROR_DOMAIN_IF && ( if (pgm_error->domain == PGM_ERROR_DOMAIN_IF &&
// NB: cannot catch EAI_BADFLAGS. // NB: cannot catch EAI_BADFLAGS.
pgm_error->code != PGM_ERROR_SERVICE && ( pgm_error->code != PGM_ERROR_SERVICE &&
pgm_error->code != PGM_ERROR_SOCKTNOSUPPORT)) pgm_error->code != PGM_ERROR_SOCKTNOSUPPORT)) {
// User, host, or network configuration or transient error. // User, host, or network configuration or transient error.
goto err_abort; pgm_error_free (pgm_error);
errno = EINVAL;
return -1;
}
// Fatal OpenPGM internal error. // Fatal OpenPGM internal error.
zmq_assert (false); zmq_assert (false);
} }
return 0;
}
// Create, bind and connect PGM socket.
int zmq::pgm_socket_t::init (bool udp_encapsulation_, const char *network_)
{
// Can not open transport before destroying old one.
zmq_assert (sock == NULL);
zmq_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;
}
zmq_assert (res != NULL); zmq_assert (res != NULL);
......
...@@ -57,6 +57,9 @@ namespace zmq ...@@ -57,6 +57,9 @@ namespace zmq
// Initialize PGM network structures (GSI, GSRs). // Initialize PGM network structures (GSI, GSRs).
int init (bool udp_encapsulation_, const char *network_); int init (bool udp_encapsulation_, const char *network_);
// Resolve PGM socket address.
static int init_address(const char *network_, struct pgm_addrinfo_t **addr, uint16_t *port_number);
// Get receiver fds and store them into user allocated memory. // Get receiver fds and store them into user allocated memory.
void get_receiver_fds (fd_t *receive_fd_, fd_t *waiting_pipe_fd_); void get_receiver_fds (fd_t *receive_fd_, fd_t *waiting_pipe_fd_);
......
...@@ -55,6 +55,9 @@ ...@@ -55,6 +55,9 @@
#include "address.hpp" #include "address.hpp"
#include "ipc_address.hpp" #include "ipc_address.hpp"
#include "tcp_address.hpp" #include "tcp_address.hpp"
#ifdef ZMQ_HAVE_OPENPGM
#include "pgm_socket.hpp"
#endif
#include "pair.hpp" #include "pair.hpp"
#include "pub.hpp" #include "pub.hpp"
...@@ -510,6 +513,17 @@ int zmq::socket_base_t::connect (const char *addr_) ...@@ -510,6 +513,17 @@ int zmq::socket_base_t::connect (const char *addr_)
return -1; return -1;
} }
} }
#endif
#ifdef ZMQ_HAVE_OPENPGM
if (protocol == "pgm" || protocol == "epgm") {
struct pgm_addrinfo_t *res = NULL;
uint16_t port_number = 0;
int rc = pgm_socket_t::init_address(address.c_str(), &res, &port_number);
if (res != NULL)
pgm_freeaddrinfo (res);
if (rc != 0 || port_number == 0)
return -1;
}
#endif #endif
// Create session. // Create session.
session_base_t *session = session_base_t::create (io_thread, true, this, session_base_t *session = session_base_t::create (io_thread, true, this,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment