Moved more functionality from net_server to NetworkSettings.
* Added (still incomplete) helper classes for the settings messages. * The net_server now uses these classes for its interfaces, and services. * Renamed service_address to service_connection, as that better matches what it is used for.
This commit is contained in:
parent
7a9c00732a
commit
f16f9ee4ee
@ -9,9 +9,13 @@
|
||||
#define SETTINGS_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <Message.h>
|
||||
#include <Messenger.h>
|
||||
#include <NetworkAddress.h>
|
||||
#include <Path.h>
|
||||
#include <StringList.h>
|
||||
|
||||
|
||||
namespace BNetworkKit {
|
||||
@ -20,6 +24,7 @@ namespace BNetworkKit {
|
||||
class BNetworkSettings {
|
||||
public:
|
||||
static const uint32 kMsgInterfaceSettingsUpdated = 'SUif';
|
||||
static const uint32 kMsgNetworkSettingsUpdated = 'SUnw';
|
||||
static const uint32 kMsgServiceSettingsUpdated = 'SUsv';
|
||||
|
||||
public:
|
||||
@ -88,7 +93,109 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class BNetworkInterfaceAddressSettings {
|
||||
public:
|
||||
BNetworkInterfaceAddressSettings(
|
||||
const BMessage& data);
|
||||
~BNetworkInterfaceAddressSettings();
|
||||
|
||||
int Family() const;
|
||||
bool AutoConfigure() const;
|
||||
|
||||
const BNetworkAddress&
|
||||
Address() const;
|
||||
const BNetworkAddress&
|
||||
Mask() const;
|
||||
const BNetworkAddress&
|
||||
Peer() const;
|
||||
const BNetworkAddress&
|
||||
Broadcast() const;
|
||||
const BNetworkAddress&
|
||||
Gateway() const;
|
||||
|
||||
private:
|
||||
int32 fFamily;
|
||||
bool fAutoConfigure;
|
||||
BNetworkAddress fAddress;
|
||||
BNetworkAddress fMask;
|
||||
BNetworkAddress fPeer;
|
||||
BNetworkAddress fBroadcast;
|
||||
BNetworkAddress fGateway;
|
||||
};
|
||||
|
||||
|
||||
class BNetworkInterfaceSettings {
|
||||
public:
|
||||
BNetworkInterfaceSettings(
|
||||
const BMessage& message);
|
||||
~BNetworkInterfaceSettings();
|
||||
|
||||
const char* Name() const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace BNetworkKit
|
||||
|
||||
|
||||
class BNetworkServiceAddressSettings {
|
||||
public:
|
||||
BNetworkServiceAddressSettings();
|
||||
BNetworkServiceAddressSettings(
|
||||
const BMessage& data, int family = -1,
|
||||
int type = -1, int protocol = -1,
|
||||
int port = -1);
|
||||
~BNetworkServiceAddressSettings();
|
||||
|
||||
int Family() const;
|
||||
void SetFamily(int family);
|
||||
int Protocol() const;
|
||||
void SetProtocol(int protocol);
|
||||
int Type() const;
|
||||
void SetType(int type);
|
||||
|
||||
const BNetworkAddress&
|
||||
Address() const;
|
||||
BNetworkAddress& Address();
|
||||
|
||||
status_t GetMessage(BMessage& data);
|
||||
|
||||
bool operator==(
|
||||
const BNetworkServiceAddressSettings& other)
|
||||
const;
|
||||
|
||||
private:
|
||||
int32 fFamily;
|
||||
int fProtocol;
|
||||
int fType;
|
||||
BNetworkAddress fAddress;
|
||||
};
|
||||
|
||||
|
||||
class BNetworkServiceSettings {
|
||||
public:
|
||||
BNetworkServiceSettings(
|
||||
const BMessage& message);
|
||||
~BNetworkServiceSettings();
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
const char* Name() const;
|
||||
bool IsStandAlone() const;
|
||||
|
||||
int32 CountArguments() const;
|
||||
const char* ArgumentAt(int32 index) const;
|
||||
|
||||
int32 CountAddresses() const;
|
||||
const BNetworkServiceAddressSettings&
|
||||
AddressAt(int32 index) const;
|
||||
|
||||
private:
|
||||
const BMessage& fData;
|
||||
BStringList fArguments;
|
||||
std::vector<BNetworkServiceAddressSettings>
|
||||
fAddresses;
|
||||
};
|
||||
|
||||
|
||||
#endif // SETTINGS_H
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <NetworkSettings.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -115,6 +116,119 @@ const static settings_template kServicesTemplate[] = {
|
||||
};
|
||||
|
||||
|
||||
struct address_family {
|
||||
int family;
|
||||
const char* name;
|
||||
const char* identifiers[4];
|
||||
};
|
||||
|
||||
|
||||
static const address_family kFamilies[] = {
|
||||
{
|
||||
AF_INET,
|
||||
"inet",
|
||||
{"AF_INET", "inet", "ipv4", NULL},
|
||||
},
|
||||
{
|
||||
AF_INET6,
|
||||
"inet6",
|
||||
{"AF_INET6", "inet6", "ipv6", NULL},
|
||||
},
|
||||
{ -1, NULL, {NULL} }
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
get_address_family(const char* argument)
|
||||
{
|
||||
for (int32 i = 0; kFamilies[i].family >= 0; i++) {
|
||||
for (int32 j = 0; kFamilies[i].identifiers[j]; j++) {
|
||||
if (!strcmp(argument, kFamilies[i].identifiers[j])) {
|
||||
// found a match
|
||||
return kFamilies[i].family;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AF_UNSPEC;
|
||||
}
|
||||
|
||||
|
||||
/*! Parses the \a argument as network \a address for the specified \a family.
|
||||
If \a family is \c AF_UNSPEC, \a family will be overwritten with the family
|
||||
of the successfully parsed address.
|
||||
*/
|
||||
static bool
|
||||
parse_address(int32& family, const char* argument, BNetworkAddress& address)
|
||||
{
|
||||
if (argument == NULL)
|
||||
return false;
|
||||
|
||||
status_t status = address.SetTo(family, argument, (uint16)0,
|
||||
B_NO_ADDRESS_RESOLUTION);
|
||||
if (status != B_OK)
|
||||
return false;
|
||||
|
||||
if (family == AF_UNSPEC) {
|
||||
// Test if we support the resulting address family
|
||||
bool supported = false;
|
||||
|
||||
for (int32 i = 0; kFamilies[i].family >= 0; i++) {
|
||||
if (kFamilies[i].family == address.Family()) {
|
||||
supported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!supported)
|
||||
return false;
|
||||
|
||||
// Take over family from address
|
||||
family = address.Family();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
parse_type(const char* string)
|
||||
{
|
||||
if (!strcasecmp(string, "stream"))
|
||||
return SOCK_STREAM;
|
||||
|
||||
return SOCK_DGRAM;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
parse_protocol(const char* string)
|
||||
{
|
||||
struct protoent* proto = getprotobyname(string);
|
||||
if (proto == NULL)
|
||||
return IPPROTO_TCP;
|
||||
|
||||
return proto->p_proto;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
type_for_protocol(int protocol)
|
||||
{
|
||||
// default determined by protocol
|
||||
switch (protocol) {
|
||||
case IPPROTO_TCP:
|
||||
return SOCK_STREAM;
|
||||
|
||||
case IPPROTO_UDP:
|
||||
default:
|
||||
return SOCK_DGRAM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
BNetworkSettings::BNetworkSettings()
|
||||
{
|
||||
_Load();
|
||||
@ -384,7 +498,7 @@ BNetworkSettings::_Load(const char* name, uint32* _type)
|
||||
}
|
||||
|
||||
if (_type != NULL)
|
||||
*_type = kMsgInterfaceSettingsUpdated;
|
||||
*_type = kMsgNetworkSettingsUpdated;
|
||||
}
|
||||
}
|
||||
if (name == NULL || strcmp(name, kServicesSettingsName) == 0) {
|
||||
@ -672,3 +786,353 @@ BNetworkSettings::_RemoveItem(BMessage& container, const char* itemField,
|
||||
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - BNetworkInterfaceAddressSettings
|
||||
|
||||
|
||||
BNetworkInterfaceAddressSettings::BNetworkInterfaceAddressSettings(
|
||||
const BMessage& data)
|
||||
{
|
||||
if (data.FindInt32("family", &fFamily) != B_OK) {
|
||||
const char* familyString;
|
||||
if (data.FindString("family", &familyString) == B_OK) {
|
||||
fFamily = get_address_family(familyString);
|
||||
if (fFamily == AF_UNSPEC) {
|
||||
// we don't support this family
|
||||
fprintf(stderr, "Ignore unknown family: %s\n",
|
||||
familyString);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
fFamily = AF_UNSPEC;
|
||||
}
|
||||
|
||||
fAutoConfigure = data.GetBool("auto_config", false);
|
||||
|
||||
if (!fAutoConfigure) {
|
||||
if (parse_address(fFamily, data.GetString("address", NULL), fAddress))
|
||||
parse_address(fFamily, data.GetString("mask", NULL), fMask);
|
||||
|
||||
parse_address(fFamily, data.GetString("peer", NULL), fPeer);
|
||||
parse_address(fFamily, data.GetString("broadcast", NULL), fBroadcast);
|
||||
parse_address(fFamily, data.GetString("gateway", NULL), fGateway);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BNetworkInterfaceAddressSettings::~BNetworkInterfaceAddressSettings()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
BNetworkInterfaceAddressSettings::Family() const
|
||||
{
|
||||
return fFamily;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BNetworkInterfaceAddressSettings::AutoConfigure() const
|
||||
{
|
||||
return fAutoConfigure;
|
||||
}
|
||||
|
||||
|
||||
const BNetworkAddress&
|
||||
BNetworkInterfaceAddressSettings::Address() const
|
||||
{
|
||||
return fAddress;
|
||||
}
|
||||
|
||||
|
||||
const BNetworkAddress&
|
||||
BNetworkInterfaceAddressSettings::Mask() const
|
||||
{
|
||||
return fMask;
|
||||
}
|
||||
|
||||
|
||||
const BNetworkAddress&
|
||||
BNetworkInterfaceAddressSettings::Peer() const
|
||||
{
|
||||
return fPeer;
|
||||
}
|
||||
|
||||
|
||||
const BNetworkAddress&
|
||||
BNetworkInterfaceAddressSettings::Broadcast() const
|
||||
{
|
||||
return fBroadcast;
|
||||
}
|
||||
|
||||
|
||||
const BNetworkAddress&
|
||||
BNetworkInterfaceAddressSettings::Gateway() const
|
||||
{
|
||||
return fGateway;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - BNetworkServiceAddress
|
||||
|
||||
|
||||
BNetworkServiceAddressSettings::BNetworkServiceAddressSettings()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BNetworkServiceAddressSettings::BNetworkServiceAddressSettings(
|
||||
const BMessage& data, int serviceFamily, int serviceType,
|
||||
int serviceProtocol, int servicePort)
|
||||
{
|
||||
// TODO: dump problems in the settings to syslog
|
||||
if (data.FindInt32("family", &fFamily) != B_OK) {
|
||||
const char* familyString;
|
||||
if (data.FindString("family", &familyString) == B_OK) {
|
||||
fFamily = get_address_family(familyString);
|
||||
if (fFamily == AF_UNSPEC) {
|
||||
// we don't support this family
|
||||
fprintf(stderr, "Ignore unknown family: %s\n",
|
||||
familyString);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
fFamily = serviceFamily;
|
||||
}
|
||||
|
||||
if (!parse_address(fFamily, data.GetString("address"), fAddress))
|
||||
fAddress.SetToWildcard(fFamily);
|
||||
|
||||
const char* string;
|
||||
if (data.FindString("protocol", &string) == B_OK)
|
||||
fProtocol = parse_protocol(string);
|
||||
else
|
||||
fProtocol = serviceProtocol;
|
||||
|
||||
if (data.FindString("type", &string) == B_OK)
|
||||
fType = parse_type(string);
|
||||
else if (fProtocol != serviceProtocol)
|
||||
fType = type_for_protocol(fProtocol);
|
||||
else
|
||||
fType = serviceType;
|
||||
|
||||
fAddress.SetPort(data.GetInt32("port", servicePort));
|
||||
}
|
||||
|
||||
|
||||
BNetworkServiceAddressSettings::~BNetworkServiceAddressSettings()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
BNetworkServiceAddressSettings::Family() const
|
||||
{
|
||||
return fFamily;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BNetworkServiceAddressSettings::SetFamily(int family)
|
||||
{
|
||||
fFamily = family;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
BNetworkServiceAddressSettings::Protocol() const
|
||||
{
|
||||
return fProtocol;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BNetworkServiceAddressSettings::SetProtocol(int protocol)
|
||||
{
|
||||
fProtocol = protocol;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
BNetworkServiceAddressSettings::Type() const
|
||||
{
|
||||
return fType;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BNetworkServiceAddressSettings::SetType(int type)
|
||||
{
|
||||
fType = type;
|
||||
}
|
||||
|
||||
|
||||
const BNetworkAddress&
|
||||
BNetworkServiceAddressSettings::Address() const
|
||||
{
|
||||
return fAddress;
|
||||
}
|
||||
|
||||
|
||||
BNetworkAddress&
|
||||
BNetworkServiceAddressSettings::Address()
|
||||
{
|
||||
return fAddress;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkServiceAddressSettings::GetMessage(BMessage& data)
|
||||
{
|
||||
// TODO!
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BNetworkServiceAddressSettings::operator==(
|
||||
const BNetworkServiceAddressSettings& other) const
|
||||
{
|
||||
return Family() == other.Family()
|
||||
&& Type() == other.Type()
|
||||
&& Protocol() == other.Protocol()
|
||||
&& Address() == other.Address();
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - BNetworkServiceSettings
|
||||
|
||||
|
||||
BNetworkServiceSettings::BNetworkServiceSettings(const BMessage& message)
|
||||
:
|
||||
fData(message)
|
||||
{
|
||||
// TODO: user/group is currently ignored!
|
||||
|
||||
// Default family/port/protocol/type for all addresses
|
||||
|
||||
// we default to inet/tcp/port-from-service-name if nothing is specified
|
||||
const char* string;
|
||||
if (message.FindString("family", &string) != B_OK)
|
||||
string = "inet";
|
||||
|
||||
int32 serviceFamily = get_address_family(string);
|
||||
if (serviceFamily == AF_UNSPEC)
|
||||
serviceFamily = AF_INET;
|
||||
|
||||
int32 serviceProtocol;
|
||||
if (message.FindString("protocol", &string) == B_OK)
|
||||
serviceProtocol = parse_protocol(string);
|
||||
else {
|
||||
string = "tcp";
|
||||
// we set 'string' here for an eventual call to getservbyname()
|
||||
// below
|
||||
serviceProtocol = IPPROTO_TCP;
|
||||
}
|
||||
|
||||
int32 servicePort;
|
||||
if (message.FindInt32("port", &servicePort) != B_OK) {
|
||||
struct servent* servent = getservbyname(Name(), string);
|
||||
if (servent != NULL)
|
||||
servicePort = ntohs(servent->s_port);
|
||||
else
|
||||
servicePort = -1;
|
||||
}
|
||||
|
||||
int32 serviceType = -1;
|
||||
if (message.FindString("type", &string) == B_OK) {
|
||||
serviceType = parse_type(string);
|
||||
} else {
|
||||
serviceType = type_for_protocol(serviceProtocol);
|
||||
}
|
||||
|
||||
const char* argument;
|
||||
for (int i = 0; message.FindString("launch", i, &argument) == B_OK; i++) {
|
||||
fArguments.Add(argument);
|
||||
}
|
||||
|
||||
BMessage addressData;
|
||||
int32 i = 0;
|
||||
for (; message.FindMessage("address", i, &addressData) == B_OK; i++) {
|
||||
BNetworkServiceAddressSettings address(addressData, serviceFamily,
|
||||
serviceType, serviceProtocol, servicePort);
|
||||
fAddresses.push_back(address);
|
||||
}
|
||||
|
||||
if (i == 0 && (serviceFamily < 0 || servicePort < 0)) {
|
||||
// no address specified
|
||||
printf("service %s has no address specified\n", Name());
|
||||
return;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
// no address specified, but family/port were given; add empty address
|
||||
BNetworkServiceAddressSettings address;
|
||||
address.SetFamily(serviceFamily);
|
||||
address.SetType(serviceType);
|
||||
address.SetProtocol(serviceProtocol);
|
||||
address.Address().SetToWildcard(serviceFamily, servicePort);
|
||||
|
||||
fAddresses.push_back(address);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BNetworkServiceSettings::~BNetworkServiceSettings()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkServiceSettings::InitCheck() const
|
||||
{
|
||||
if (fData.HasString("name") && fData.HasString("launch")
|
||||
&& CountAddresses() > 0)
|
||||
return B_OK;
|
||||
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
BNetworkServiceSettings::Name() const
|
||||
{
|
||||
return fData.GetString("name");
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BNetworkServiceSettings::IsStandAlone() const
|
||||
{
|
||||
return fData.GetBool("stand_alone");
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BNetworkServiceSettings::CountArguments() const
|
||||
{
|
||||
return fArguments.CountStrings();
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
BNetworkServiceSettings::ArgumentAt(int32 index) const
|
||||
{
|
||||
return fArguments.StringAt(index);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BNetworkServiceSettings::CountAddresses() const
|
||||
{
|
||||
return fAddresses.size();
|
||||
}
|
||||
|
||||
|
||||
const BNetworkServiceAddressSettings&
|
||||
BNetworkServiceSettings::AddressAt(int32 index) const
|
||||
{
|
||||
return fAddresses[index];
|
||||
}
|
||||
|
@ -107,28 +107,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
struct address_family {
|
||||
int family;
|
||||
const char* name;
|
||||
const char* identifiers[4];
|
||||
};
|
||||
|
||||
|
||||
static const address_family kFamilies[] = {
|
||||
{
|
||||
AF_INET,
|
||||
"inet",
|
||||
{"AF_INET", "inet", "ipv4", NULL},
|
||||
},
|
||||
{
|
||||
AF_INET6,
|
||||
"inet6",
|
||||
{"AF_INET6", "inet6", "ipv6", NULL},
|
||||
},
|
||||
{ -1, NULL, {NULL} }
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - private functions
|
||||
|
||||
|
||||
@ -156,61 +134,6 @@ set_80211(const char* name, int32 type, void* data,
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - exported functions
|
||||
|
||||
|
||||
int
|
||||
get_address_family(const char* argument)
|
||||
{
|
||||
for (int32 i = 0; kFamilies[i].family >= 0; i++) {
|
||||
for (int32 j = 0; kFamilies[i].identifiers[j]; j++) {
|
||||
if (!strcmp(argument, kFamilies[i].identifiers[j])) {
|
||||
// found a match
|
||||
return kFamilies[i].family;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AF_UNSPEC;
|
||||
}
|
||||
|
||||
|
||||
/*! Parses the \a argument as network \a address for the specified \a family.
|
||||
If \a family is \c AF_UNSPEC, \a family will be overwritten with the family
|
||||
of the successfully parsed address.
|
||||
*/
|
||||
bool
|
||||
parse_address(int32& family, const char* argument, BNetworkAddress& address)
|
||||
{
|
||||
if (argument == NULL)
|
||||
return false;
|
||||
|
||||
status_t status = address.SetTo(family, argument, (uint16)0,
|
||||
B_NO_ADDRESS_RESOLUTION);
|
||||
if (status != B_OK)
|
||||
return false;
|
||||
|
||||
if (family == AF_UNSPEC) {
|
||||
// Test if we support the resulting address family
|
||||
bool supported = false;
|
||||
|
||||
for (int32 i = 0; kFamilies[i].family >= 0; i++) {
|
||||
if (kFamilies[i].family == address.Family()) {
|
||||
supported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!supported)
|
||||
return false;
|
||||
|
||||
// Take over family from address
|
||||
family = address.Family();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
@ -254,7 +177,7 @@ NetServer::ReadyToRun()
|
||||
_BringUpInterfaces();
|
||||
_StartServices();
|
||||
|
||||
BPrivate::BPathMonitor::StartWatching("/dev/net",
|
||||
BPrivate::BPathMonitor::StartWatching("/dev/net",
|
||||
B_WATCH_FILES_ONLY | B_WATCH_RECURSIVELY, this);
|
||||
}
|
||||
|
||||
@ -548,60 +471,19 @@ NetServer::_ConfigureInterface(BMessage& message)
|
||||
BMessage addressMessage;
|
||||
for (int32 index = 0; message.FindMessage("address", index,
|
||||
&addressMessage) == B_OK; index++) {
|
||||
int32 family;
|
||||
if (addressMessage.FindInt32("family", &family) != B_OK) {
|
||||
const char* familyString;
|
||||
if (addressMessage.FindString("family", &familyString) == B_OK) {
|
||||
if (get_address_family(familyString) == AF_UNSPEC) {
|
||||
// we don't support this family
|
||||
fprintf(stderr, "%s: Ignore unknown family: %s\n", Name(),
|
||||
familyString);
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
family = AF_UNSPEC;
|
||||
}
|
||||
BNetworkInterfaceAddressSettings addressSettings(addressMessage);
|
||||
|
||||
// retrieve addresses
|
||||
|
||||
bool autoConfig;
|
||||
if (addressMessage.FindBool("auto_config", &autoConfig) != B_OK)
|
||||
autoConfig = false;
|
||||
|
||||
BNetworkAddress address;
|
||||
BNetworkAddress mask;
|
||||
BNetworkAddress broadcast;
|
||||
BNetworkAddress peer;
|
||||
BNetworkAddress gateway;
|
||||
|
||||
const char* string;
|
||||
|
||||
if (!autoConfig) {
|
||||
if (addressMessage.FindString("address", &string) == B_OK) {
|
||||
parse_address(family, string, address);
|
||||
|
||||
if (addressMessage.FindString("mask", &string) == B_OK)
|
||||
parse_address(family, string, mask);
|
||||
}
|
||||
|
||||
if (addressMessage.FindString("peer", &string) == B_OK)
|
||||
parse_address(family, string, peer);
|
||||
|
||||
if (addressMessage.FindString("broadcast", &string) == B_OK)
|
||||
parse_address(family, string, broadcast);
|
||||
}
|
||||
|
||||
if (autoConfig) {
|
||||
if (addressSettings.AutoConfigure()) {
|
||||
_QuitLooperForDevice(name);
|
||||
startAutoConfig = true;
|
||||
} else if (addressMessage.FindString("gateway", &string) == B_OK
|
||||
&& parse_address(family, string, gateway)) {
|
||||
} else if (!addressSettings.Gateway().IsEmpty()) {
|
||||
// add gateway route, if we're asked for it
|
||||
interface.RemoveDefaultRoute(family);
|
||||
interface.RemoveDefaultRoute(addressSettings.Family());
|
||||
// Try to remove a previous default route, doesn't matter
|
||||
// if it fails.
|
||||
|
||||
status_t status = interface.AddDefaultRoute(gateway);
|
||||
status_t status = interface.AddDefaultRoute(
|
||||
addressSettings.Gateway());
|
||||
if (status != B_OK) {
|
||||
fprintf(stderr, "%s: Could not add route for %s: %s\n",
|
||||
Name(), name, strerror(errno));
|
||||
@ -610,14 +492,17 @@ NetServer::_ConfigureInterface(BMessage& message)
|
||||
|
||||
// set address/mask/broadcast/peer
|
||||
|
||||
if (!address.IsEmpty() || !mask.IsEmpty() || !broadcast.IsEmpty()) {
|
||||
if (!addressSettings.Address().IsEmpty()
|
||||
|| !addressSettings.Mask().IsEmpty()
|
||||
|| !addressSettings.Broadcast().IsEmpty()
|
||||
|| !addressSettings.Peer().IsEmpty()) {
|
||||
BNetworkInterfaceAddress interfaceAddress;
|
||||
interfaceAddress.SetAddress(address);
|
||||
interfaceAddress.SetMask(mask);
|
||||
if (!broadcast.IsEmpty())
|
||||
interfaceAddress.SetBroadcast(broadcast);
|
||||
else if (!peer.IsEmpty())
|
||||
interfaceAddress.SetDestination(peer);
|
||||
interfaceAddress.SetAddress(addressSettings.Address());
|
||||
interfaceAddress.SetMask(addressSettings.Mask());
|
||||
if (!addressSettings.Broadcast().IsEmpty())
|
||||
interfaceAddress.SetBroadcast(addressSettings.Broadcast());
|
||||
else if (!addressSettings.Peer().IsEmpty())
|
||||
interfaceAddress.SetDestination(addressSettings.Peer());
|
||||
|
||||
status_t status = interface.SetAddress(interfaceAddress);
|
||||
if (status != B_OK) {
|
||||
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
#ifndef NET_SERVER_H
|
||||
#define NET_SERVER_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <NetServer.h>
|
||||
|
||||
|
||||
class BNetworkAddress;
|
||||
|
||||
|
||||
int get_address_family(const char* argument);
|
||||
bool parse_address(int32& family, const char* argument,
|
||||
BNetworkAddress& address);
|
||||
|
||||
|
||||
#endif // NET_SERVER_H
|
@ -8,47 +8,50 @@
|
||||
|
||||
|
||||
#include "Services.h"
|
||||
#include "NetServer.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <NetworkAddress.h>
|
||||
#include <NetworkSettings.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct service_address {
|
||||
struct service_connection {
|
||||
struct service* owner;
|
||||
int socket;
|
||||
int family;
|
||||
int type;
|
||||
int protocol;
|
||||
BNetworkAddress address;
|
||||
BNetworkServiceAddressSettings address;
|
||||
|
||||
bool operator==(const struct service_address& other) const;
|
||||
//service_connection() : owner(NULL), socket(-1) {}
|
||||
|
||||
int Family() const { return address.Family(); }
|
||||
int Protocol() const { return address.Protocol(); }
|
||||
int Type() const { return address.Type(); }
|
||||
const BNetworkAddress& Address() const { return address.Address(); }
|
||||
|
||||
bool operator==(const struct service_connection& other) const;
|
||||
};
|
||||
|
||||
typedef std::vector<service_address> AddressList;
|
||||
typedef std::vector<service_connection> ConnectionList;
|
||||
typedef std::vector<std::string> StringList;
|
||||
|
||||
struct service {
|
||||
std::string name;
|
||||
StringList arguments;
|
||||
uid_t user;
|
||||
gid_t group;
|
||||
AddressList addresses;
|
||||
uint32 update;
|
||||
bool stand_alone;
|
||||
pid_t process;
|
||||
std::string name;
|
||||
StringList arguments;
|
||||
uid_t user;
|
||||
gid_t group;
|
||||
ConnectionList connections;
|
||||
uint32 update;
|
||||
bool stand_alone;
|
||||
pid_t process;
|
||||
|
||||
~service();
|
||||
bool operator!=(const struct service& other) const;
|
||||
@ -56,52 +59,13 @@ struct service {
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
parse_type(const char* string)
|
||||
{
|
||||
if (!strcasecmp(string, "stream"))
|
||||
return SOCK_STREAM;
|
||||
|
||||
return SOCK_DGRAM;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
parse_protocol(const char* string)
|
||||
{
|
||||
struct protoent* proto = getprotobyname(string);
|
||||
if (proto == NULL)
|
||||
return IPPROTO_TCP;
|
||||
|
||||
return proto->p_proto;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
type_for_protocol(int protocol)
|
||||
{
|
||||
// default determined by protocol
|
||||
switch (protocol) {
|
||||
case IPPROTO_TCP:
|
||||
return SOCK_STREAM;
|
||||
|
||||
case IPPROTO_UDP:
|
||||
default:
|
||||
return SOCK_DGRAM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
bool
|
||||
service_address::operator==(const struct service_address& other) const
|
||||
service_connection::operator==(const struct service_connection& other) const
|
||||
{
|
||||
return family == other.family
|
||||
&& type == other.type
|
||||
&& protocol == other.protocol
|
||||
&& address == other.address;
|
||||
return address == other.address;
|
||||
}
|
||||
|
||||
|
||||
@ -111,11 +75,11 @@ service_address::operator==(const struct service_address& other) const
|
||||
service::~service()
|
||||
{
|
||||
// close all open sockets
|
||||
AddressList::const_iterator iterator = addresses.begin();
|
||||
for (; iterator != addresses.end(); iterator++) {
|
||||
const service_address& address = *iterator;
|
||||
ConnectionList::const_iterator iterator = connections.begin();
|
||||
for (; iterator != connections.end(); iterator++) {
|
||||
const service_connection& connection = *iterator;
|
||||
|
||||
close(address.socket);
|
||||
close(connection.socket);
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,32 +96,33 @@ service::operator==(const struct service& other) const
|
||||
{
|
||||
if (name != other.name
|
||||
|| arguments.size() != other.arguments.size()
|
||||
|| addresses.size() != other.addresses.size()
|
||||
|| connections.size() != other.connections.size()
|
||||
|| stand_alone != other.stand_alone)
|
||||
return false;
|
||||
|
||||
// compare arguments
|
||||
// Compare arguments
|
||||
|
||||
for(size_t i = 0; i < arguments.size(); i++) {
|
||||
if (arguments[i] != other.arguments[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
// compare addresses
|
||||
// Compare connections
|
||||
|
||||
AddressList::const_iterator iterator = addresses.begin();
|
||||
for (; iterator != addresses.end(); iterator++) {
|
||||
const service_address& address = *iterator;
|
||||
ConnectionList::const_iterator iterator = connections.begin();
|
||||
for (; iterator != connections.end(); iterator++) {
|
||||
const service_connection& connection = *iterator;
|
||||
|
||||
// find address in other addresses
|
||||
// Find address in other addresses
|
||||
|
||||
AddressList::const_iterator otherIterator = other.addresses.begin();
|
||||
for (; otherIterator != other.addresses.end(); otherIterator++) {
|
||||
if (address == *otherIterator)
|
||||
ConnectionList::const_iterator otherIterator
|
||||
= other.connections.begin();
|
||||
for (; otherIterator != other.connections.end(); otherIterator++) {
|
||||
if (connection == *otherIterator)
|
||||
break;
|
||||
}
|
||||
|
||||
if (otherIterator == other.addresses.end())
|
||||
if (otherIterator == other.connections.end())
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -268,20 +233,22 @@ Services::_StartService(struct service& service)
|
||||
// create socket
|
||||
|
||||
bool failed = false;
|
||||
AddressList::iterator iterator = service.addresses.begin();
|
||||
for (; iterator != service.addresses.end(); iterator++) {
|
||||
service_address& address = *iterator;
|
||||
ConnectionList::iterator iterator = service.connections.begin();
|
||||
for (; iterator != service.connections.end(); iterator++) {
|
||||
service_connection& connection = *iterator;
|
||||
|
||||
address.socket = socket(address.family, address.type, address.protocol);
|
||||
if (address.socket < 0
|
||||
|| bind(address.socket, address.address, address.address.Length())
|
||||
< 0
|
||||
|| fcntl(address.socket, F_SETFD, FD_CLOEXEC) < 0) {
|
||||
connection.socket = socket(connection.Family(),
|
||||
connection.Type(), connection.Protocol());
|
||||
if (connection.socket < 0
|
||||
|| bind(connection.socket, connection.Address(),
|
||||
connection.Address().Length()) < 0
|
||||
|| fcntl(connection.socket, F_SETFD, FD_CLOEXEC) < 0) {
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (address.type == SOCK_STREAM && listen(address.socket, 50) < 0) {
|
||||
if (connection.Type() == SOCK_STREAM
|
||||
&& listen(connection.socket, 50) < 0) {
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
@ -297,13 +264,13 @@ Services::_StartService(struct service& service)
|
||||
fNameMap[service.name] = &service;
|
||||
service.update = fUpdate;
|
||||
|
||||
iterator = service.addresses.begin();
|
||||
for (; iterator != service.addresses.end(); iterator++) {
|
||||
service_address& address = *iterator;
|
||||
iterator = service.connections.begin();
|
||||
for (; iterator != service.connections.end(); iterator++) {
|
||||
service_connection& connection = *iterator;
|
||||
|
||||
fSocketMap[address.socket] = &address;
|
||||
_UpdateMinMaxSocket(address.socket);
|
||||
FD_SET(address.socket, &fSet);
|
||||
fSocketMap[connection.socket] = &connection;
|
||||
_UpdateMinMaxSocket(connection.socket);
|
||||
FD_SET(connection.socket, &fSet);
|
||||
}
|
||||
|
||||
_NotifyListener();
|
||||
@ -325,17 +292,17 @@ Services::_StopService(struct service& service)
|
||||
}
|
||||
|
||||
if (!service.stand_alone) {
|
||||
AddressList::const_iterator iterator = service.addresses.begin();
|
||||
for (; iterator != service.addresses.end(); iterator++) {
|
||||
const service_address& address = *iterator;
|
||||
ConnectionList::const_iterator iterator = service.connections.begin();
|
||||
for (; iterator != service.connections.end(); iterator++) {
|
||||
const service_connection& connection = *iterator;
|
||||
|
||||
ServiceSocketMap::iterator socketIterator
|
||||
= fSocketMap.find(address.socket);
|
||||
= fSocketMap.find(connection.socket);
|
||||
if (socketIterator != fSocketMap.end())
|
||||
fSocketMap.erase(socketIterator);
|
||||
|
||||
close(address.socket);
|
||||
FD_CLR(address.socket, &fSet);
|
||||
close(connection.socket);
|
||||
FD_CLR(connection.socket, &fSet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -353,129 +320,32 @@ Services::_StopService(struct service& service)
|
||||
status_t
|
||||
Services::_ToService(const BMessage& message, struct service*& service)
|
||||
{
|
||||
// get mandatory fields
|
||||
const char* name;
|
||||
if (message.FindString("name", &name) != B_OK
|
||||
|| !message.HasString("launch"))
|
||||
return B_BAD_VALUE;
|
||||
BNetworkServiceSettings settings(message);
|
||||
status_t status = settings.InitCheck();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
service = new (std::nothrow) ::service;
|
||||
if (service == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
service->name = name;
|
||||
|
||||
const char* argument;
|
||||
for (int i = 0; message.FindString("launch", i, &argument) == B_OK; i++) {
|
||||
service->arguments.push_back(argument);
|
||||
}
|
||||
|
||||
service->stand_alone = false;
|
||||
service->name = settings.Name();
|
||||
service->stand_alone = settings.IsStandAlone();
|
||||
service->process = -1;
|
||||
|
||||
// TODO: user/group is currently ignored!
|
||||
// Copy launch arguments
|
||||
for (int32 i = 0; i < settings.CountArguments(); i++)
|
||||
service->arguments.push_back(settings.ArgumentAt(i));
|
||||
|
||||
// Default family/port/protocol/type for all addresses
|
||||
// Copy addresses to listen to
|
||||
for (int32 i = 0; i < settings.CountAddresses(); i++) {
|
||||
const BNetworkServiceAddressSettings& address = settings.AddressAt(i);
|
||||
service_connection connection;
|
||||
connection.owner = service;
|
||||
connection.socket = -1;
|
||||
connection.address = address;
|
||||
|
||||
// we default to inet/tcp/port-from-service-name if nothing is specified
|
||||
const char* string;
|
||||
if (message.FindString("family", &string) != B_OK)
|
||||
string = "inet";
|
||||
|
||||
int32 serviceFamily = get_address_family(string);
|
||||
if (serviceFamily == AF_UNSPEC)
|
||||
serviceFamily = AF_INET;
|
||||
|
||||
int32 serviceProtocol;
|
||||
if (message.FindString("protocol", &string) == B_OK)
|
||||
serviceProtocol = parse_protocol(string);
|
||||
else {
|
||||
string = "tcp";
|
||||
// we set 'string' here for an eventual call to getservbyname()
|
||||
// below
|
||||
serviceProtocol = IPPROTO_TCP;
|
||||
}
|
||||
|
||||
int32 servicePort;
|
||||
if (message.FindInt32("port", &servicePort) != B_OK) {
|
||||
struct servent* servent = getservbyname(name, string);
|
||||
if (servent != NULL)
|
||||
servicePort = ntohs(servent->s_port);
|
||||
else
|
||||
servicePort = -1;
|
||||
}
|
||||
|
||||
int32 serviceType = -1;
|
||||
if (message.FindString("type", &string) == B_OK) {
|
||||
serviceType = parse_type(string);
|
||||
} else {
|
||||
serviceType = type_for_protocol(serviceProtocol);
|
||||
}
|
||||
|
||||
bool standAlone = false;
|
||||
if (message.FindBool("stand_alone", &standAlone) == B_OK)
|
||||
service->stand_alone = standAlone;
|
||||
|
||||
BMessage address;
|
||||
int32 i = 0;
|
||||
for (; message.FindMessage("address", i, &address) == B_OK; i++) {
|
||||
// TODO: dump problems in the settings to syslog
|
||||
service_address serviceAddress;
|
||||
if (address.FindString("family", &string) != B_OK)
|
||||
continue;
|
||||
|
||||
serviceAddress.family = get_address_family(string);
|
||||
if (serviceAddress.family == AF_UNSPEC)
|
||||
continue;
|
||||
|
||||
if (address.FindString("protocol", &string) == B_OK)
|
||||
serviceAddress.protocol = parse_protocol(string);
|
||||
else
|
||||
serviceAddress.protocol = serviceProtocol;
|
||||
|
||||
if (message.FindString("type", &string) == B_OK)
|
||||
serviceAddress.type = parse_type(string);
|
||||
else if (serviceAddress.protocol != serviceProtocol)
|
||||
serviceAddress.type = type_for_protocol(serviceAddress.protocol);
|
||||
else
|
||||
serviceAddress.type = serviceType;
|
||||
|
||||
if (address.FindString("address", &string) == B_OK) {
|
||||
if (!parse_address(serviceFamily, string, serviceAddress.address))
|
||||
continue;
|
||||
} else
|
||||
serviceAddress.address.SetToWildcard(serviceFamily);
|
||||
|
||||
int32 port;
|
||||
if (address.FindInt32("port", &port) != B_OK)
|
||||
port = servicePort;
|
||||
|
||||
serviceAddress.address.SetPort(port);
|
||||
serviceAddress.socket = -1;
|
||||
|
||||
serviceAddress.owner = service;
|
||||
service->addresses.push_back(serviceAddress);
|
||||
}
|
||||
|
||||
if (i == 0 && (serviceFamily < 0 || servicePort < 0)) {
|
||||
// no address specified
|
||||
printf("service %s has no address specified\n", name);
|
||||
delete service;
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
// no address specified, but family/port were given; add empty address
|
||||
service_address serviceAddress;
|
||||
serviceAddress.family = serviceFamily;
|
||||
serviceAddress.type = serviceType;
|
||||
serviceAddress.protocol = serviceProtocol;
|
||||
serviceAddress.address.SetToWildcard(serviceFamily, servicePort);
|
||||
|
||||
serviceAddress.socket = -1;
|
||||
|
||||
serviceAddress.owner = service;
|
||||
service->addresses.push_back(serviceAddress);
|
||||
service->connections.push_back(connection);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
@ -614,16 +484,16 @@ Services::_Listener()
|
||||
if (iterator == fSocketMap.end())
|
||||
continue;
|
||||
|
||||
struct service_address& address = *iterator->second;
|
||||
struct service_connection& connection = *iterator->second;
|
||||
int socket;
|
||||
|
||||
if (address.type == SOCK_STREAM) {
|
||||
if (connection.Type() == SOCK_STREAM) {
|
||||
// accept incoming connection
|
||||
int value = 1;
|
||||
ioctl(i, FIONBIO, &value);
|
||||
// make sure we don't wait for the connection
|
||||
|
||||
socket = accept(address.socket, NULL, NULL);
|
||||
socket = accept(connection.socket, NULL, NULL);
|
||||
|
||||
value = 0;
|
||||
ioctl(i, FIONBIO, &value);
|
||||
@ -631,11 +501,11 @@ Services::_Listener()
|
||||
if (socket < 0)
|
||||
continue;
|
||||
} else
|
||||
socket = address.socket;
|
||||
socket = connection.socket;
|
||||
|
||||
// launch this service's handler
|
||||
|
||||
_LaunchService(*address.owner, socket);
|
||||
_LaunchService(*connection.owner, socket);
|
||||
}
|
||||
}
|
||||
return B_OK;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2006-2015, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@ -18,9 +18,9 @@
|
||||
|
||||
|
||||
struct service;
|
||||
struct service_address;
|
||||
struct service_connection;
|
||||
typedef std::map<std::string, service*> ServiceNameMap;
|
||||
typedef std::map<int, service_address*> ServiceSocketMap;
|
||||
typedef std::map<int, service_connection*> ServiceSocketMap;
|
||||
|
||||
|
||||
class Services : public BHandler {
|
||||
|
Loading…
Reference in New Issue
Block a user