added 2 changesets to branch 'refs/remotes/axeld-github/network-preferences' old head: 3c89e7f782bcf786adc08dc9ebd974ece0364182 new head: 557c74fbfc685880a6657774fff7e9ec2822248e overview: https://github.com/axeld/haiku/compare/3c89e7f782bc...557c74fbfc68 ---------------------------------------------------------------------------- 9ae216885e29: 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. 557c74fbfc68: Network: broadcast updates, remove apply button. * Network now monitors all network, and network settings changes, and will notify all add-ons about those changes. * Removed the global apply button. Instead, the static IP configuration now got that button. All other changes will be instant. [ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ] ---------------------------------------------------------------------------- 13 files changed, 823 insertions(+), 425 deletions(-) .../add-ons/network_settings/NetworkSettings.h | 107 +++++ .../network_settings/NetworkSettingsAddOn.h | 8 +- .../network_settings/ipv4/IPv4InterfaceAddOn.cpp | 18 +- .../ipv4/InterfaceAddressView.cpp | 84 +++- .../network_settings/ipv4/InterfaceAddressView.h | 6 + src/kits/network/libnetapi/NetworkSettings.cpp | 466 ++++++++++++++++++- src/preferences/network/NetworkSettingsAddOn.cpp | 12 + src/preferences/network/NetworkWindow.cpp | 52 ++- src/preferences/network/NetworkWindow.h | 4 +- src/servers/net/NetServer.cpp | 149 +----- src/servers/net/NetServer.h | 25 - src/servers/net/Services.cpp | 311 ++++--------- src/servers/net/Services.h | 6 +- ############################################################################ Commit: 9ae216885e297e6f36ee58d16ada49b3f064d9c0 Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Thu Feb 26 12:05:21 2015 UTC 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. ---------------------------------------------------------------------------- diff --git a/headers/os/add-ons/network_settings/NetworkSettings.h b/headers/os/add-ons/network_settings/NetworkSettings.h index 6f68393..7105241 100644 --- a/headers/os/add-ons/network_settings/NetworkSettings.h +++ b/headers/os/add-ons/network_settings/NetworkSettings.h @@ -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 diff --git a/src/kits/network/libnetapi/NetworkSettings.cpp b/src/kits/network/libnetapi/NetworkSettings.cpp index fc5fd05..87eed54 100644 --- a/src/kits/network/libnetapi/NetworkSettings.cpp +++ b/src/kits/network/libnetapi/NetworkSettings.cpp @@ -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]; +} diff --git a/src/servers/net/NetServer.cpp b/src/servers/net/NetServer.cpp index f7bf6e5..06ed2ad 100644 --- a/src/servers/net/NetServer.cpp +++ b/src/servers/net/NetServer.cpp @@ -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; - } - - // 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); - } + BNetworkInterfaceAddressSettings addressSettings(addressMessage); - 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) { diff --git a/src/servers/net/NetServer.h b/src/servers/net/NetServer.h deleted file mode 100644 index 44282fd..0000000 --- a/src/servers/net/NetServer.h +++ /dev/null @@ -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@xxxxxxxxxxxxxxxx - */ -#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 diff --git a/src/servers/net/Services.cpp b/src/servers/net/Services.cpp index 1ccc956..db1f18b 100644 --- a/src/servers/net/Services.cpp +++ b/src/servers/net/Services.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2015, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -8,47 +8,51 @@ #include "Services.h" -#include "NetServer.h" -#include "Settings.h" -#include <Autolock.h> -#include <NetworkAddress.h> +#include <new> +//#include <vector> #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> + +#include <Autolock.h> +#include <NetworkAddress.h> +#include <NetworkSettings.h> + 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 +60,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 +76,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 +97,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 +234,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; - - 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) { + ConnectionList::iterator iterator = service.connections.begin(); + for (; iterator != service.connections.end(); iterator++) { + service_connection& connection = *iterator; + + 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 +265,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 +293,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 +321,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! - - // 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); - } - - 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); + // Copy launch arguments + for (int32 i = 0; i < settings.CountArguments(); i++) + service->arguments.push_back(settings.ArgumentAt(i)); - serviceAddress.socket = -1; + // 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; - serviceAddress.owner = service; - service->addresses.push_back(serviceAddress); + service->connections.push_back(connection); } return B_OK; @@ -614,16 +485,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 +502,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; diff --git a/src/servers/net/Services.h b/src/servers/net/Services.h index 7e399a0..4a1c6c1 100644 --- a/src/servers/net/Services.h +++ b/src/servers/net/Services.h @@ -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 { ############################################################################ Commit: 557c74fbfc685880a6657774fff7e9ec2822248e Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Thu Feb 26 23:08:45 2015 UTC Network: broadcast updates, remove apply button. * Network now monitors all network, and network settings changes, and will notify all add-ons about those changes. * Removed the global apply button. Instead, the static IP configuration now got that button. All other changes will be instant. ---------------------------------------------------------------------------- diff --git a/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h b/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h index 34cbc54..3bd9d42 100644 --- a/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h +++ b/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h @@ -23,6 +23,10 @@ enum BNetworkSettingsType { B_NETWORK_SETTINGS_TYPE_OTHER = 'othr' }; +enum { + kMsgSettingsItemUpdated = 'SIup' +}; + class BNetworkProfile; class BNetworkSettings; @@ -42,10 +46,12 @@ public: const BNetworkProfile* Profile() const; - virtual status_t Apply() = 0; virtual status_t Revert() = 0; virtual bool IsRevertable() = 0; + virtual void SettingsUpdated(uint32 type); + virtual void ConfigurationUpdated(const BMessage& message); + private: const BNetworkProfile* fProfile; diff --git a/src/add-ons/network_settings/ipv4/IPv4InterfaceAddOn.cpp b/src/add-ons/network_settings/ipv4/IPv4InterfaceAddOn.cpp index 038b0a3..f4856ac 100644 --- a/src/add-ons/network_settings/ipv4/IPv4InterfaceAddOn.cpp +++ b/src/add-ons/network_settings/ipv4/IPv4InterfaceAddOn.cpp @@ -42,10 +42,11 @@ public: virtual BListItem* ListItem(); virtual BView* View(); - virtual status_t Apply(); virtual status_t Revert(); virtual bool IsRevertable(); + virtual void ConfigurationUpdated(const BMessage& message); + private: BNetworkSettings& fSettings; BStringItem* fItem; @@ -95,13 +96,6 @@ IPv4InterfaceItem::View() status_t -IPv4InterfaceItem::Apply() -{ - return B_OK; -} - - -status_t IPv4InterfaceItem::Revert() { return B_OK; @@ -115,6 +109,14 @@ IPv4InterfaceItem::IsRevertable() } +void +IPv4InterfaceItem::ConfigurationUpdated(const BMessage& message) +{ + if (fView != NULL) + fView->ConfigurationUpdated(message); +} + + // #pragma mark - diff --git a/src/add-ons/network_settings/ipv4/InterfaceAddressView.cpp b/src/add-ons/network_settings/ipv4/InterfaceAddressView.cpp index 2b7961c..1f41cc7 100644 --- a/src/add-ons/network_settings/ipv4/InterfaceAddressView.cpp +++ b/src/add-ons/network_settings/ipv4/InterfaceAddressView.cpp @@ -12,6 +12,7 @@ #include <stdio.h> +#include <Button.h> #include <Catalog.h> #include <ControlLook.h> #include <LayoutBuilder.h> @@ -31,6 +32,7 @@ const uint32 kModeAuto = 'iato'; const uint32 kModeStatic = 'istc'; const uint32 kModeDisabled = 'ioff'; +const uint32 kMsgApply = 'aply'; // #pragma mark - InterfaceAddressView @@ -82,6 +84,11 @@ InterfaceAddressView::InterfaceAddressView(int family, fGatewayField->SetToolTip(B_TRANSLATE("Your gateway to the internet")); fGatewayField->TextView()->SetExplicitMinSize(BSize(minimumWidth, B_SIZE_UNSET)); + fApplyButton = new BButton("apply", B_TRANSLATE("Apply"), + new BMessage(kMsgApply)); + fApplyButton->SetExplicitAlignment( + BAlignment(B_ALIGN_RIGHT, B_ALIGN_VERTICAL_UNSET)); + fSettings.GetInterface(interface, fOriginalInterface); fInterfaceSettings = fOriginalInterface; _UpdateFields(); @@ -93,6 +100,7 @@ InterfaceAddressView::InterfaceAddressView(int family, .AddTextControl(fNetmaskField, 0, 2, B_ALIGN_RIGHT) .AddTextControl(fGatewayField, 0, 3, B_ALIGN_RIGHT) .End() + .Add(fApplyButton) .AddGlue(); } @@ -120,6 +128,11 @@ InterfaceAddressView::MessageReceived(BMessage* message) case kModeStatic: case kModeDisabled: _SetModeField(message->what); + if (message->what != kModeStatic) + _UpdateSettings(); + break; + + case kMsgApply: _UpdateSettings(); break; @@ -129,18 +142,6 @@ InterfaceAddressView::MessageReceived(BMessage* message) } -// #pragma mark - InterfaceAddressView private methods - - -void -InterfaceAddressView::_EnableFields(bool enable) -{ - fAddressField->SetEnabled(enable); - fNetmaskField->SetEnabled(enable); - fGatewayField->SetEnabled(enable); -} - - // #pragma mark - InterfaceAddressView public methods @@ -177,23 +178,51 @@ InterfaceAddressView::Revert() } -status_t -InterfaceAddressView::Save() +void +InterfaceAddressView::ConfigurationUpdated(const BMessage& message) +{ + const char* device = message.GetString("device", NULL); + if (strcmp(device, fInterface.Name()) != 0) + return; + + _UpdateFields(); +} + + +// #pragma mark - InterfaceAddressView private methods + + +void +InterfaceAddressView::_Apply() { BMenuItem* item = fModePopUpMenu->FindMarked(); if (item == NULL) - return B_ERROR; + return; /* fSettings->SetIP(fFamily, fAddressField->Text()); fSettings->SetNetmask(fFamily, fNetmaskField->Text()); fSettings->SetGateway(fFamily, fGatewayField->Text()); fSettings->SetAutoConfigure(fFamily, item->Command() == kModeAuto); */ - return B_OK; } void +InterfaceAddressView::_EnableFields(bool enable) +{ + fAddressField->SetEnabled(enable); + fNetmaskField->SetEnabled(enable); + fGatewayField->SetEnabled(enable); +} + + +/*! Updates the UI to match the current interface configuration. + + The interface settings may be consulted to determine if the + automatic configuration has been specified, if there was no + configuration yet. +*/ +void InterfaceAddressView::_UpdateFields() { bool autoConfigure = (fInterface.Flags() @@ -257,4 +286,27 @@ InterfaceAddressView::_SetModeField(uint32 mode) void InterfaceAddressView::_UpdateSettings() { + BMessage interface; + fSettings.GetInterface(fInterface.Name(), interface); + + interface.SetString("device", fInterface.Name()); + + uint32 mode = kModeAuto; + BMenuItem* item = fModePopUpMenu->FindMarked(); + if (item != NULL) + mode = item->Message()->what; + + // Remove previous address for family + + switch (mode) { + case kModeAuto: + default: + break; + case kModeDisabled: + break; + case kModeStatic: + break; + } + + fSettings.AddInterface(interface); } diff --git a/src/add-ons/network_settings/ipv4/InterfaceAddressView.h b/src/add-ons/network_settings/ipv4/InterfaceAddressView.h index 54db382..e6ed57b 100644 --- a/src/add-ons/network_settings/ipv4/InterfaceAddressView.h +++ b/src/add-ons/network_settings/ipv4/InterfaceAddressView.h @@ -15,6 +15,7 @@ #include <NetworkSettings.h> +class BButton; class BMenuField; class BMessage; class BPopUpMenu; @@ -38,7 +39,11 @@ public: status_t Revert(); status_t Save(); + void ConfigurationUpdated(const BMessage& message); + + private: + void _Apply(); void _EnableFields(bool enable); void _UpdateFields(); void _SetModeField(uint32 mode); @@ -57,6 +62,7 @@ private: BTextControl* fAddressField; BTextControl* fNetmaskField; BTextControl* fGatewayField; + BButton* fApplyButton; }; diff --git a/src/preferences/network/NetworkSettingsAddOn.cpp b/src/preferences/network/NetworkSettingsAddOn.cpp index 13992a7..b1ee4a6 100644 --- a/src/preferences/network/NetworkSettingsAddOn.cpp +++ b/src/preferences/network/NetworkSettingsAddOn.cpp @@ -40,6 +40,18 @@ BNetworkSettingsItem::Profile() const } +void +BNetworkSettingsItem::SettingsUpdated(uint32 type) +{ +} + + +void +BNetworkSettingsItem::ConfigurationUpdated(const BMessage& message) +{ +} + + // #pragma mark - diff --git a/src/preferences/network/NetworkWindow.cpp b/src/preferences/network/NetworkWindow.cpp index 62b65d7..1b5deca 100644 --- a/src/preferences/network/NetworkWindow.cpp +++ b/src/preferences/network/NetworkWindow.cpp @@ -26,6 +26,7 @@ #include <Directory.h> #include <LayoutBuilder.h> #include <NetworkInterface.h> +#include <NetworkNotifications.h> #include <NetworkRoster.h> #include <OutlineListView.h> #include <Path.h> @@ -49,7 +50,6 @@ const char* kNetworkStatusSignature = "application/x-vnd.Haiku-NetworkStatus"; static const uint32 kMsgProfileSelected = 'prof'; static const uint32 kMsgProfileManage = 'mngp'; static const uint32 kMsgProfileNew = 'newp'; -static const uint32 kMsgApply = 'aply'; static const uint32 kMsgRevert = 'rvrt'; static const uint32 kMsgToggleReplicant = 'trep'; static const uint32 kMsgItemSelected = 'ItSl'; @@ -78,10 +78,6 @@ NetworkWindow::NetworkWindow() // Settings section - fApplyButton = new BButton("apply", B_TRANSLATE("Apply"), - new BMessage(kMsgApply)); - SetDefaultButton(fApplyButton); - fRevertButton = new BButton("revert", B_TRANSLATE("Revert"), new BMessage(kMsgRevert)); // fRevertButton->SetEnabled(false); @@ -124,7 +120,6 @@ NetworkWindow::NetworkWindow() .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) .Add(fRevertButton) .AddGlue() - .Add(fApplyButton) .End(); _ScanInterfaces(); @@ -141,11 +136,15 @@ NetworkWindow::NetworkWindow() CenterOnScreen(); fSettings.StartMonitoring(this); + start_watching_network(B_WATCH_NETWORK_INTERFACE_CHANGES + | B_WATCH_NETWORK_LINK_CHANGES | B_WATCH_NETWORK_WLAN_CHANGES, this); } NetworkWindow::~NetworkWindow() { + stop_watching_network(this); + fSettings.StopMonitoring(this); } @@ -170,10 +169,7 @@ NetworkWindow::MessageReceived(BMessage* message) if (message->FindString("path", &path) != B_OK) break; - BPath name(path); - bool isCurrent = strcmp(name.Leaf(), "current") == 0; - - fApplyButton->SetEnabled(!isCurrent); + // TODO! break; } @@ -196,14 +192,6 @@ NetworkWindow::MessageReceived(BMessage* message) break; } - case kMsgApply: - { - SettingsMap::const_iterator iterator = fSettingsMap.begin(); - for (; iterator != fSettingsMap.end(); iterator++) - iterator->second->Apply(); - break; - } - case kMsgToggleReplicant: { _ShowReplicant( @@ -217,6 +205,16 @@ NetworkWindow::MessageReceived(BMessage* message) break; } + case B_NETWORK_MONITOR: + _BroadcastConfigurationUpdate(*message); + break; + + case BNetworkSettings::kMsgInterfaceSettingsUpdated: + case BNetworkSettings::kMsgNetworkSettingsUpdated: + case BNetworkSettings::kMsgServiceSettingsUpdated: + _BroadcastSettingsUpdate(message->what); + break; + default: inherited::MessageReceived(message); } @@ -453,6 +451,24 @@ NetworkWindow::_SelectItem(BListItem* listItem) void +NetworkWindow::_BroadcastSettingsUpdate(uint32 type) +{ + SettingsMap::const_iterator iterator = fSettingsMap.begin(); + for (; iterator != fSettingsMap.end(); iterator++) + iterator->second->SettingsUpdated(type); +} + + +void +NetworkWindow::_BroadcastConfigurationUpdate(const BMessage& message) +{ + SettingsMap::const_iterator iterator = fSettingsMap.begin(); + for (; iterator != fSettingsMap.end(); iterator++) + iterator->second->ConfigurationUpdated(message); +} + + +void NetworkWindow::_ShowReplicant(bool show) { if (show) { diff --git a/src/preferences/network/NetworkWindow.h b/src/preferences/network/NetworkWindow.h index 8731f07..75ab6ec 100644 --- a/src/preferences/network/NetworkWindow.h +++ b/src/preferences/network/NetworkWindow.h @@ -44,6 +44,9 @@ private: _SettingsItemFor(BListItem* item); BListItem* _ListItemFor(BNetworkSettingsType type); void _SelectItem(BListItem* listItem); + void _BroadcastSettingsUpdate(uint32 type); + void _BroadcastConfigurationUpdate( + const BMessage& message); bool _IsReplicantInstalled(); void _ShowReplicant(bool show); @@ -69,7 +72,6 @@ private: BView* fAddOnShellView; BButton* fRevertButton; - BButton* fApplyButton; };