Browse Source

Add interface selection for NetJack components

* Multicast interface selection to UnixSocket - added methods
   Bind and JoinMCastGroup with <char *if_name> argument
 * Interface handling to NetInterface class tree - new field and
   its initialization/usage in Slave branch.
 * Multicast interface selection to NetSlaves (Adapter/Driver)
   and NetMaster, where master can now listen all interfaces.
pull/27/head
Ruslan N. Marchenko 13 years ago
parent
commit
2f22923e1a
9 changed files with 126 additions and 17 deletions
  1. +14
    -6
      common/JackNetAdapter.cpp
  2. +16
    -3
      common/JackNetDriver.cpp
  3. +1
    -1
      common/JackNetDriver.h
  4. +8
    -2
      common/JackNetInterface.cpp
  5. +2
    -0
      common/JackNetInterface.h
  6. +22
    -3
      common/JackNetManager.cpp
  7. +1
    -0
      common/JackNetManager.h
  8. +59
    -2
      posix/JackNetUnixSocket.cpp
  9. +3
    -0
      posix/JackNetUnixSocket.h

+ 14
- 6
common/JackNetAdapter.cpp View File

@@ -35,7 +35,7 @@ namespace Jack
because we don't have full parametering right now, parameters will be parsed from the param list,
and then JackNetSlaveInterface will be filled with proper values.
*/
char multicast_ip[32];
char multicast_ip[32],multicast_if[32];
uint udp_port;
GetHostName(fParams.fName, JACK_CLIENT_NAME_SIZE);
fSocket.GetName(fParams.fSlaveNetName);
@@ -58,11 +58,10 @@ namespace Jack
udp_port = (default_udp_port) ? atoi(default_udp_port) : DEFAULT_PORT;

const char* default_multicast_ip = getenv("JACK_NETJACK_MULTICAST");
if (default_multicast_ip) {
strcpy(multicast_ip, default_multicast_ip);
} else {
strcpy(multicast_ip, DEFAULT_MULTICAST_IP);
}
strcpy(multicast_ip, (default_multicast_ip) ? default_multicast_ip : DEFAULT_MULTICAST_IP);

const char* default_multicast_if = getenv("JACK_NETJACK_INTERFACE");
strcpy(multicast_if, (default_multicast_if) ? default_multicast_if : DEFAULT_MULTICAST_IF);

//options parsing
const JSList* node;
@@ -76,6 +75,10 @@ namespace Jack
assert(strlen(param->value.str) < 32);
strcpy(multicast_ip, param->value.str);
break;
case 'f' :
assert(strlen(param->value.str) < 32);
strcpy(multicast_if, param->value.str);
break;
case 'p' :
udp_port = param->value.ui;
break;
@@ -128,6 +131,8 @@ namespace Jack
}

strcpy(fMulticastIP, multicast_ip);
if(strcmp(multicast_if,DEFAULT_MULTICAST_IF))
strcpy(fMulticastIF, multicast_if);

// Set the socket parameters
fSocket.SetPort(udp_port);
@@ -424,6 +429,9 @@ extern "C"
strcpy(value.str, DEFAULT_MULTICAST_IP);
jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast address, or explicit IP of the master", NULL);

strcpy(value.str, DEFAULT_MULTICAST_IF);
jack_driver_descriptor_add_parameter(desc, &filler, "multicast-if", 'f', JackDriverParamString, &value, NULL, "Multicast interface name, any or all", "Multicast interface to send probes from (any - kernel chosen (default), all - all available, if_name - explicit bind)");

value.i = DEFAULT_PORT;
jack_driver_descriptor_add_parameter(desc, &filler, "udp-net-port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL);



+ 16
- 3
common/JackNetDriver.cpp View File

@@ -28,7 +28,7 @@ using namespace std;
namespace Jack
{
JackNetDriver::JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table,
const char* ip, int udp_port, int mtu, int midi_input_ports, int midi_output_ports,
const char* ip, int udp_port, const char* mcif, int mtu, int midi_input_ports, int midi_output_ports,
char* net_name, uint transport_sync, int network_latency,
int celt_encoding, int opus_encoding, bool auto_save)
: JackWaiterDriver(name, alias, engine, table), JackNetSlaveInterface(ip, udp_port)
@@ -39,6 +39,8 @@ namespace Jack
if (strcmp(net_name, "") == 0) {
GetHostName(net_name, JACK_CLIENT_NAME_SIZE);
}
if(strcmp(mcif,DEFAULT_MULTICAST_IF))
strcpy(fMulticastIF,mcif);

fParams.fMtu = mtu;
@@ -676,6 +678,9 @@ namespace Jack
strcpy(value.str, DEFAULT_MULTICAST_IP);
jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast address, or explicit IP of the master", NULL);

strcpy(value.str, DEFAULT_MULTICAST_IF);
jack_driver_descriptor_add_parameter(desc, &filler, "multicast-if", 'f', JackDriverParamString, &value, NULL, "Multicast interface name, any or all", "Multicast interface to send probes from (any - kernel chosen (default), all - all available, if_name - explicit bind)");

value.i = DEFAULT_PORT;
jack_driver_descriptor_add_parameter(desc, &filler, "udp-net-port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL);

@@ -719,8 +724,9 @@ Deactivated for now..

SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params)
{
char multicast_if[32];
char multicast_ip[32];
char net_name[JACK_CLIENT_NAME_SIZE+1] = {0};
char net_name[JACK_CLIENT_NAME_SIZE + 1] = {0};
int udp_port;
int mtu = DEFAULT_MTU;
// Desactivated for now...
@@ -747,6 +753,9 @@ Deactivated for now..
const char* default_multicast_ip = getenv("JACK_NETJACK_MULTICAST");
strcpy(multicast_ip, (default_multicast_ip) ? default_multicast_ip : DEFAULT_MULTICAST_IP);
const char* default_multicast_if = getenv("JACK_NETJACK_INTERFACE");
strcpy(multicast_if, (default_multicast_if) ? default_multicast_if : DEFAULT_MULTICAST_IF);

for (node = params; node; node = jack_slist_next(node)) {
param = (const jack_driver_param_t*) node->data;
switch (param->character)
@@ -755,6 +764,10 @@ Deactivated for now..
assert(strlen(param->value.str) < 32);
strcpy(multicast_ip, param->value.str);
break;
case 'f' :
assert(strlen(param->value.str) < 32);
strcpy(multicast_if, param->value.str);
break;
case 'p':
udp_port = param->value.ui;
break;
@@ -808,7 +821,7 @@ Deactivated for now..
try {

Jack::JackDriverClientInterface* driver = new Jack::JackWaitThreadedDriver(
new Jack::JackNetDriver("system", "net_pcm", engine, table, multicast_ip, udp_port, mtu,
new Jack::JackNetDriver("system", "net_pcm", engine, table, multicast_ip, udp_port, multicast_if, mtu,
midi_input_ports, midi_output_ports,
net_name, transport_sync,
network_latency, celt_encoding, opus_encoding, auto_save));


+ 1
- 1
common/JackNetDriver.h View File

@@ -79,7 +79,7 @@ namespace Jack
public:

JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table,
const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports,
const char* ip, int port, const char* mcif, int mtu, int midi_input_ports, int midi_output_ports,
char* net_name, uint transport_sync, int network_latency, int celt_encoding,
int opus_encoding, bool auto_save);
virtual ~JackNetDriver();


+ 8
- 2
common/JackNetInterface.cpp View File

@@ -57,6 +57,7 @@ namespace Jack
fSetTimeOut = false;
fTxBuffer = NULL;
fRxBuffer = NULL;
fMulticastIF[0]=0;
fNetAudioCaptureBuffer = NULL;
fNetAudioPlaybackBuffer = NULL;
fNetMidiCaptureBuffer = NULL;
@@ -700,6 +701,12 @@ namespace Jack

if (fSocket.IsLocal(fMulticastIP)) {
jack_info("Local IP is used...");
} else if (fMulticastIF[0]) {
// bind the socket & interface
if (fSocket.Bind(fMulticastIF) == SOCKET_ERROR) {
jack_error("Can't bind the socket : %s", StrError(NET_ERROR_CODE));
return NET_SOCKET_ERROR;
}
} else {
// bind the socket
if (fSocket.Bind() == SOCKET_ERROR) {
@@ -719,8 +726,7 @@ namespace Jack
}

// send 'AVAILABLE' until 'SLAVE_SETUP' received
jack_info("Waiting for a master...");
jack_info("Waiting for a master on %s...",(fMulticastIF[0])?fMulticastIF:"default");
do {
// send 'available'
session_params_t net_params;


+ 2
- 0
common/JackNetInterface.h View File

@@ -27,6 +27,7 @@ namespace Jack
{

#define DEFAULT_MULTICAST_IP "225.3.19.154"
#define DEFAULT_MULTICAST_IF "any"
#define DEFAULT_PORT 19000
#define DEFAULT_MTU 1500
#define MAX_MTU 9000
@@ -60,6 +61,7 @@ namespace Jack
session_params_t fParams;
JackNetSocket fSocket;
char fMulticastIP[32];
char fMulticastIF[32];

// headers
packet_header_t fTxHeader;


+ 22
- 3
common/JackNetManager.cpp View File

@@ -505,7 +505,7 @@ namespace Jack
if (out) {
memset(out, 0, sizeof(float) * fParams.fPeriodSize);
}
fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, out)));
fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, out);
#endif
}

@@ -660,6 +660,13 @@ namespace Jack
strcpy(fMulticastIP, DEFAULT_MULTICAST_IP);
}

const char* default_multicast_if = getenv("JACK_NETJACK_INTERFACE");
if (default_multicast_if) {
strcpy(fMulticastIF, default_multicast_if);
} else {
strcpy(fMulticastIF, DEFAULT_MULTICAST_IF);
}

for (node = params; node; node = jack_slist_next(node)) {

param = (const jack_driver_param_t*) node->data;
@@ -672,6 +679,14 @@ namespace Jack
}
break;

case 'f' :
if (strlen(param->value.str) < 32) {
strcpy(fMulticastIF, param->value.str);
} else {
jack_error("Can't use multicast interface %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IF);
}
break;

case 'p':
fSocket.SetPort(param->value.ui);
break;
@@ -761,7 +776,7 @@ namespace Jack
{
JackNetMasterManager* master_manager = static_cast<JackNetMasterManager*>(arg);
jack_info("Starting Jack NetManager");
jack_info("Listening on '%s:%d'", master_manager->fMulticastIP, master_manager->fSocket.GetPort());
jack_info("Listening on '%s:%d%%%s'", master_manager->fMulticastIP, master_manager->fSocket.GetPort(),master_manager->fMulticastIF);
master_manager->Run();
return NULL;
}
@@ -797,7 +812,7 @@ namespace Jack
}

//join multicast group
if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) {
if (fSocket.JoinMCastGroup(fMulticastIP,fMulticastIF) == SOCKET_ERROR) {
jack_error("Can't join multicast group : %s", StrError(NET_ERROR_CODE));
}

@@ -843,6 +858,7 @@ namespace Jack
}
break;
default:
jack_log("JackNetMasterManager::Run: read: %d; type: %d; peer: %s",rx_bytes,host_params.fPacketID,host_params.fName);
break;
}
}
@@ -949,6 +965,9 @@ extern "C"
strcpy(value.str, DEFAULT_MULTICAST_IP);
jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast address", NULL);

strcpy(value.str, DEFAULT_MULTICAST_IF);
jack_driver_descriptor_add_parameter(desc, &filler, "multicast-if", 'f', JackDriverParamString, &value, NULL, "Multicast interface", "Multicast interface to bind to. ('all' - all ip ifs; 'any' (default) kernel chosen; ifname i.e. eth0)");

value.i = DEFAULT_PORT;
jack_driver_descriptor_add_parameter(desc, &filler, "udp-net-port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL);



+ 1
- 0
common/JackNetManager.h View File

@@ -112,6 +112,7 @@ namespace Jack
jack_client_t* fClient;
const char* fName;
char fMulticastIP[32];
char fMulticastIF[32];
JackNetSocket fSocket;
jack_native_thread_t fThread;
master_list_t fMasterList;


+ 59
- 2
posix/JackNetUnixSocket.cpp View File

@@ -20,6 +20,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackNetUnixSocket.h"
#include "JackError.h"

#include <arpa/inet.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <unistd.h>
#include <fcntl.h>

@@ -171,6 +175,16 @@ namespace Jack
{
return bind(fSockfd, reinterpret_cast<socket_address_t*>(&fRecvAddr), sizeof(socket_address_t));
}
int JackNetUnixSocket::Bind(const char *if_name)
{
struct ip_mreq multicast_req;
int ret = Bind();
if(!ret && strcmp(if_name,"any")) {
multicast_req.imr_multiaddr.s_addr = fSendAddr.sin_addr.s_addr;
ret = BindMCastIface(if_name, IP_MULTICAST_IF, &multicast_req);
}
return ret;
}

int JackNetUnixSocket::BindWith(const char* ip)
{
@@ -267,11 +281,53 @@ namespace Jack
}

int JackNetUnixSocket::JoinMCastGroup(const char* ip)
{
return JoinMCastGroup(ip,"any");
}
int JackNetUnixSocket::JoinMCastGroup(const char* ip, const char *if_name)
{
struct ip_mreq multicast_req;
inet_aton(ip, &multicast_req.imr_multiaddr);
multicast_req.imr_interface.s_addr = htonl(INADDR_ANY);
return SetOption(IPPROTO_IP, IP_ADD_MEMBERSHIP, &multicast_req, sizeof(multicast_req));
if(!strcmp(if_name,"any")) {
multicast_req.imr_interface.s_addr = htonl(INADDR_ANY);
return SetOption(IPPROTO_IP, IP_ADD_MEMBERSHIP, &multicast_req, sizeof(multicast_req));
} else {
return BindMCastIface(if_name, IP_ADD_MEMBERSHIP, &multicast_req);
}
}
int JackNetUnixSocket::BindMCastIface(const char *if_name, const int option, struct ip_mreq *mreq)
{
struct ifaddrs *ifas, *ifa;
int specific = strcmp("all",if_name);
int ret=-1;
char *if_last="any";

if (getifaddrs(&ifas) == -1) {
jack_error("JackNetUnixSocket::BindMCastIface error in getifaddrs");
return -1;
}
for (ifa = ifas; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL)
continue; // Address is mandatory
if(!ifa->ifa_name || !strcmp(if_last,ifa->ifa_name))
continue; // Name as well, also skip already enabled interface
if(!(ifa->ifa_flags & IFF_MULTICAST) || !(ifa->ifa_flags & IFF_RUNNING))
continue; // And non multicast or down interface
if(ifa->ifa_addr->sa_family != AF_INET)
continue; // And for the moment we're dealing with IPv4 only
if(!specific || !strcmp(ifa->ifa_name,if_name)) {
mreq->imr_interface.s_addr = ((struct sockaddr_in *)(ifa->ifa_addr))->sin_addr.s_addr;
ret = SetOption(IPPROTO_IP, option, mreq, sizeof(struct ip_mreq));
if(ret)
break;
if_last = ifa->ifa_name;
jack_log("JackNetUnixSocket::BindMCastIface attaching to %s", if_last);
}
}
freeifaddrs(ifas);
if(!strcmp(if_last,"any"))
jack_error("JackNetUnixSocket::BindMCastIface cannot find valid interface");
return ret;
}

//options************************************************************************************************************
@@ -468,6 +524,7 @@ namespace Jack

int JackNetUnixSocket::CatchHost(void* buffer, size_t nbytes, int flags)
{
jack_log("JackNetUnixSocket::CatchHost");
socklen_t addr_len = sizeof(socket_address_t);
#if defined(__sun__) || defined(sun)
if (WaitRead() < 0) {


+ 3
- 0
posix/JackNetUnixSocket.h View File

@@ -64,6 +64,7 @@ namespace Jack
//socket management
int NewSocket();
int Bind();
int Bind(const char *if_name);
int BindWith(const char* ip);
int BindWith(int port);
int Connect();
@@ -84,6 +85,8 @@ namespace Jack
//utility
int GetName(char* name);
int JoinMCastGroup(const char* mcast_ip);
int JoinMCastGroup(const char* mcast_ip, const char* if_name);
int BindMCastIface(const char *if_name, const int option, struct ip_mreq *mreq);

//options management
int SetOption(int level, int optname, const void* optval, socklen_t optlen);


Loading…
Cancel
Save