Skip to content

Commit

Permalink
v6.36 release
Browse files Browse the repository at this point in the history
  • Loading branch information
jfriesne committed Jun 24, 2016
1 parent cf0a535 commit 7fa0f0f
Show file tree
Hide file tree
Showing 13 changed files with 123 additions and 26 deletions.
10 changes: 10 additions & 0 deletions HISTORY.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ key: - new feature
* bug fixed
o other

6.36 Released 6/24/2016
- The NetworkInterfaceInfo class now has a GetMACAddress()
method that will return the 48-bit MAC address associated
with the interface.
- udpproxy will now join a UDP socket to its multicast group
if the provided IP address is a multicast IP address.
- Added a new function Crash() which does just what it says.
The MCRASH macro now calls Crash() after it prints a
stack trace.

6.35 Released 5/25/2016
o Revised MessageIOGateway::DoInputImplementation() so that if
a subclass's override of UnflattenHeaderAndMessage() has retained
Expand Down
2 changes: 1 addition & 1 deletion README.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<H2>
MUSCLE: Crossbar Server, Portable Messaging and Support Classes<p>
5/25/2016 v6.35 jaf@meyersound.com<p>
6/24/2016 v6.36 jaf@meyersound.com<p>
Jeremy Friesner / Meyer Sound Laboratories Inc.<p>
Win32 compatibility contributions by Vitaliy Mikitchenko<p>
C# client code by Wilson Yeung<p>
Expand Down
2 changes: 1 addition & 1 deletion html/Beginners Guide.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<HTML>
<HEAD>
<H1>MUSCLE Overview and Beginner's Guide</H1>
<H4>v6.35 / Jeremy Friesner / Meyer Sound Laboratories Inc (jaf@meyersound.com) 5/25/2016</H4>
<H4>v6.36 / Jeremy Friesner / Meyer Sound Laboratories Inc (jaf@meyersound.com) 6/24/2016</H4>
<A HREF="http://www.lcscanada.com/muscle/html/index.html">Click here for DOxygen class API documentation</A>
</HEAD>

Expand Down
2 changes: 1 addition & 1 deletion html/Custom Servers.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<HTML>
<HEAD>
<H1>Implementing a Custom Server with MUSCLE</H1>
<H4>v6.35 / Jeremy Friesner / Meyer Sound Laboratories Inc / jaf@meyersound.com 5/25/2016</H4>
<H4>v6.36 / Jeremy Friesner / Meyer Sound Laboratories Inc / jaf@meyersound.com 6/24/2016</H4>
</HEAD>
<BODY bgcolor=#ffffff>
<H2>Introduction</H2>
Expand Down
15 changes: 7 additions & 8 deletions support/MuscleSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#ifndef MuscleSupport_h
#define MuscleSupport_h

#define MUSCLE_VERSION_STRING "6.35"
#define MUSCLE_VERSION 63500 // Format is decimal Mmmbb, where (M) is the number before the decimal point, (mm) is the number after the decimal point, and (bb) is reserved
#define MUSCLE_VERSION_STRING "6.36"
#define MUSCLE_VERSION 63600 // Format is decimal Mmmbb, where (M) is the number before the decimal point, (mm) is the number after the decimal point, and (bb) is reserved

/*! \mainpage MUSCLE Documentation Page
*
Expand Down Expand Up @@ -168,12 +168,7 @@ using std::set_new_handler;
# define MASSERT(x,msg) {if(!(x)) MCRASH(msg)}
#endif

#ifdef WIN32
# define MCRASH(msg) {muscle::LogTime(muscle::MUSCLE_LOG_CRITICALERROR, "ASSERTION FAILED: (%s:%i) %s\n", __FILE__,__LINE__,msg); muscle::LogStackTrace(muscle::MUSCLE_LOG_CRITICALERROR); RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL);}
#else
# define MCRASH(msg) {muscle::LogTime(muscle::MUSCLE_LOG_CRITICALERROR, "ASSERTION FAILED: (%s:%i) %s\n", __FILE__,__LINE__,msg); muscle::LogStackTrace(muscle::MUSCLE_LOG_CRITICALERROR); abort();}
#endif

#define MCRASH(msg) {muscle::LogTime(muscle::MUSCLE_LOG_CRITICALERROR, "ASSERTION FAILED: (%s:%i) %s\n", __FILE__,__LINE__,msg); muscle::LogStackTrace(muscle::MUSCLE_LOG_CRITICALERROR); Crash();}
#define MEXIT(retVal,msg) {muscle::LogTime(muscle::MUSCLE_LOG_CRITICALERROR, "ASSERTION FAILED: (%s:%i) %s\n", __FILE__,__LINE__,msg); muscle::LogStackTrace(MUSCLE_LOG_CRITICALERROR); ExitWithoutCleanup(retVal);}
#define WARN_OUT_OF_MEMORY muscle::WarnOutOfMemory(__FILE__, __LINE__)
#define MCHECKPOINT muscle::LogTime(muscle::MUSCLE_LOG_WARNING, "Reached checkpoint at %s:%i\n", __FILE__, __LINE__)
Expand Down Expand Up @@ -975,6 +970,10 @@ static inline int32 ConvertReturnValueToMuscleSemantics(int origRet, uint32 maxS
namespace muscle {
#endif

// forward declarations
extern void Crash();
extern void ExitWithoutCleanup(int);

#if MUSCLE_TRACE_CHECKPOINTS > 0

/** Exposed as an implementation detail. Please ignore! */
Expand Down
9 changes: 9 additions & 0 deletions system/SetupSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ void ExitWithoutCleanup(int exitCode)
_exit(exitCode);
}

void Crash()
{
#ifdef WIN32
RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL);
#else
abort();
#endif
}

static void GoInsane(const char * why, const char * why2 = NULL)
{
printf("SanitySetupSystem: MUSCLE COMPILATION RUNTIME SANITY CHECK FAILED!\n");
Expand Down
2 changes: 1 addition & 1 deletion test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ testnetutil: $(STDOBJS) $(SSLOBJS) SysLog.o ByteBuffer.o Message.o QueryFilter.
deadlockfinder : $(STDOBJS) deadlockfinder.o SysLog.o String.o SetupSystem.o
$(CXX) $(LFLAGS) -o $@ $^ $(LIBS)

deadlock: $(STDOBJS) deadlock.o SysLog.o String.o SetupSystem.o Thread.o SocketMultiplexer.o NetworkUtilityFunctions.o
deadlock: $(STDOBJS) deadlock.o SysLog.o String.o SetupSystem.o Thread.o SocketMultiplexer.o NetworkUtilityFunctions.o Message.o ByteBuffer.o
$(CXX) $(LFLAGS) -o $@ $^ $(LIBS)

svncopy : $(STDOBJS) svncopy.o String.o SetupSystem.o SysLog.o
Expand Down
5 changes: 1 addition & 4 deletions test/testnetutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ int main(int, char **)
for (uint32 i=0; i<ifs.GetNumItems(); i++)
{
const NetworkInterfaceInfo & nii = ifs[i];
char addrStr[64]; Inet_NtoA(nii.GetLocalAddress(), addrStr);
char maskStr[64]; Inet_NtoA(nii.GetNetmask(), maskStr);
char remtStr[64]; Inet_NtoA(nii.GetBroadcastAddress(), remtStr);
printf(" #" UINT32_FORMAT_SPEC ": name=[%s] address=[%s] netmask=[%s] broadcastAddress=[%s]\n", i+1, nii.GetName()(), addrStr, maskStr, remtStr);
printf(" #" UINT32_FORMAT_SPEC ": %s\n", i+1, nii.ToString()());
}
}
else printf("GetNetworkInterfaceInfos() returned an error!\n");
Expand Down
21 changes: 20 additions & 1 deletion test/udpproxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,30 @@ int main(int argc, char ** argv)
LogTime(MUSCLE_LOG_ERROR, "Creating UDP socket failed!\n");
return 10;
}
if (BindUDPSocket(udpSock, listenPorts[i], &listenPorts[i]) != B_NO_ERROR)
if (BindUDPSocket(udpSock, listenPorts[i], &listenPorts[i], invalidIP, true) != B_NO_ERROR)
{
LogTime(MUSCLE_LOG_ERROR, "Failed to bind UDP socket to port %u!\n", listenPorts[i]);
return 10;
}

#ifndef MUSCLE_AVOID_MULTICAST_API
const ip_address & ip = targets[i].GetIPAddress();

// If it's a multicast address, we need to add ourselves to the multicast group
// in order to get packets from the group.
if (IsMulticastIPAddress(ip))
{
if (AddSocketToMulticastGroup(udpSock, ip) == B_NO_ERROR)
{
LogTime(MUSCLE_LOG_INFO, "Added UDP socket to multicast group %s!\n", Inet_NtoA(ip)());
#ifdef DISALLOW_MULTICAST_TO_SELF
if (SetSocketMulticastToSelf(udpSock, false) != B_NO_ERROR) LogTime(MUSCLE_LOG_ERROR, "Error disabling multicast-to-self on socket\n");
#endif
}
else LogTime(MUSCLE_LOG_ERROR, "Error adding UDP socket to multicast group %s!\n", Inet_NtoA(ip)());
}
#endif

UDPSocketDataIO * dio = newnothrow UDPSocketDataIO(udpSock, false);
if (dio == NULL)
{
Expand Down
7 changes: 7 additions & 0 deletions util/MiscUtilityFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,13 @@ void HandleStandardDaemonArgs(const Message & args);
*/
void ExitWithoutCleanup(int exitCode);

/** Causes this process to terminate abnormally (i.e. with a crash).
* Under Windows, this is implemented by calling RaiseException(EXCEPTION_BREAKPOINT).
* Under all other OS's, this is implemented by calling abort().
* @note this function will not return!
*/
void Crash();

/** Calls fork(), setsid(), chdir(), umask(), etc, to fork an independent daemon process.
* Also closes all open file descriptors.
* Note that this function will call ExitWithoutCleanup() on the parent process if successful,
Expand Down
57 changes: 51 additions & 6 deletions util/NetworkUtilityFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ typedef void sockopt_arg; // Whereas sane operating systems use void pointers
# define USE_GETIFADDRS 1
# define USE_SOCKETPAIR 1
# include <ifaddrs.h>
# if defined(__linux__)
# include <linux/if_packet.h> // for sockaddr_ll
#else
# include <net/if_dl.h> // for the LLADDR macro
# endif
# endif
#endif

Expand Down Expand Up @@ -1035,24 +1040,39 @@ static int32 GetSocketBufferSizeAux(const ConstSocketRef & sock, int optionName)
int32 GetSocketSendBufferSize( const ConstSocketRef & sock) {return GetSocketBufferSizeAux(sock, SO_SNDBUF);}
int32 GetSocketReceiveBufferSize(const ConstSocketRef & sock) {return GetSocketBufferSizeAux(sock, SO_RCVBUF);}

NetworkInterfaceInfo :: NetworkInterfaceInfo() : _ip(invalidIP), _netmask(invalidIP), _broadcastIP(invalidIP), _enabled(false), _copper(false)
NetworkInterfaceInfo :: NetworkInterfaceInfo() : _ip(invalidIP), _netmask(invalidIP), _broadcastIP(invalidIP), _enabled(false), _copper(false), _macAddress(0)
{
// empty
}

NetworkInterfaceInfo :: NetworkInterfaceInfo(const String &name, const String & desc, const ip_address & ip, const ip_address & netmask, const ip_address & broadcastIP, bool enabled, bool copper) : _name(name), _desc(desc), _ip(ip), _netmask(netmask), _broadcastIP(broadcastIP), _enabled(enabled), _copper(copper)
NetworkInterfaceInfo :: NetworkInterfaceInfo(const String &name, const String & desc, const ip_address & ip, const ip_address & netmask, const ip_address & broadcastIP, bool enabled, bool copper, uint64 macAddress) : _name(name), _desc(desc), _ip(ip), _netmask(netmask), _broadcastIP(broadcastIP), _enabled(enabled), _copper(copper), _macAddress(macAddress)
{
// empty
}

static String MACAddressToString(uint64 mac)
{
if (mac == 0) return "None";

char buf[128];
muscleSprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned) ((mac>>(5*8))&0xFF),
(unsigned) ((mac>>(4*8))&0xFF),
(unsigned) ((mac>>(3*8))&0xFF),
(unsigned) ((mac>>(2*8))&0xFF),
(unsigned) ((mac>>(1*8))&0xFF),
(unsigned) ((mac>>(0*8))&0xFF));
return buf;
}

String NetworkInterfaceInfo :: ToString() const
{
return String("Name=[%1] Description=[%2] IP=[%3] Netmask=[%4] Broadcast=[%5] Enabled=%6 Copper=%7").Arg(_name).Arg(_desc).Arg(Inet_NtoA(_ip)).Arg(Inet_NtoA(_netmask)).Arg(Inet_NtoA(_broadcastIP)).Arg(_enabled).Arg(_copper);
return String("Name=[%1] Description=[%2] IP=[%3] Netmask=[%4] Broadcast=[%5] MAC=[%6] Enabled=%7 Copper=%8").Arg(_name).Arg(_desc).Arg(Inet_NtoA(_ip)).Arg(Inet_NtoA(_netmask)).Arg(Inet_NtoA(_broadcastIP)).Arg(MACAddressToString(_macAddress)).Arg(_enabled).Arg(_copper);
}

uint32 NetworkInterfaceInfo :: HashCode() const
{
return _name.HashCode() + _desc.HashCode() + GetHashCodeForIPAddress(_ip) + GetHashCodeForIPAddress(_netmask) + GetHashCodeForIPAddress(_broadcastIP) + _enabled + _copper;
return _name.HashCode() + _desc.HashCode() + GetHashCodeForIPAddress(_ip) + GetHashCodeForIPAddress(_netmask) + GetHashCodeForIPAddress(_broadcastIP) + CalculateHashCode(_macAddress) +_enabled + _copper;
}

#if defined(USE_GETIFADDRS) || defined(WIN32)
Expand Down Expand Up @@ -1175,11 +1195,31 @@ status_t GetNetworkInterfaceInfos(Queue<NetworkInterfaceInfo> & results, uint32

if (getifaddrs(&ifap) == 0)
{
Hashtable<String, uint64> inameToMAC;
ret = B_NO_ERROR;
{
struct ifaddrs * p = ifap;
while(p)
{
if (p->ifa_addr)
{
#if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__)
if (p->ifa_addr->sa_family == AF_LINK)
{
const unsigned char * ptr = (const unsigned char *)LLADDR((struct sockaddr_dl *)p->ifa_addr);
uint64 mac = 0; for (uint32 i=0; i<6; i++) mac |= (((uint64)ptr[i])<<(8*(5-i)));
inameToMAC.Put(p->ifa_name, mac);
}
#elif defined(__linux__)
if (p->ifa_addr->sa_family == AF_PACKET)
{
const struct sockaddr_ll * s = (const struct sockaddr_ll *) p->ifa_addr;
uint64 mac = 0; for (uint32 i=0; i<6; i++) mac |= (((uint64)s->sll_addr[i])<<(8*(5-i)));
inameToMAC.Put(p->ifa_name, mac);
}
#endif
}

ip_address unicastIP = SockAddrToIPAddr(p->ifa_addr);
ip_address netmask = SockAddrToIPAddr(p->ifa_netmask);
ip_address broadcastIP = SockAddrToIPAddr(p->ifa_broadaddr);
Expand All @@ -1191,7 +1231,7 @@ status_t GetNetworkInterfaceInfos(Queue<NetworkInterfaceInfo> & results, uint32
// FogBugz #10519: I'm not setting the interface index for ::1 because trying to send UDP packets to ::1@1 causes ENOROUTE errors under MacOS/X
if (unicastIP != localhostIP) unicastIP.SetInterfaceIndex(if_nametoindex(p->ifa_name)); // so the user can find out; it will be ignore by the TCP stack
#endif
if (results.AddTail(NetworkInterfaceInfo(p->ifa_name, "", unicastIP, netmask, broadcastIP, isEnabled, hasCopper)) == B_NO_ERROR)
if (results.AddTail(NetworkInterfaceInfo(p->ifa_name, "", unicastIP, netmask, broadcastIP, isEnabled, hasCopper, 0)) == B_NO_ERROR) // MAC address will be set later
{
if (_cachedLocalhostAddress == invalidIP) _cachedLocalhostAddress = unicastIP;
}
Expand All @@ -1205,6 +1245,8 @@ status_t GetNetworkInterfaceInfos(Queue<NetworkInterfaceInfo> & results, uint32
}
}
freeifaddrs(ifap);

if (inameToMAC.HasItems()) for (uint32 i=0; i<results.GetNumItems(); i++) results[i]._macAddress = inameToMAC.GetWithDefault(results[i].GetName());
}
#elif defined(WIN32)
// IPv6 implementation, adapted from
Expand Down Expand Up @@ -1276,7 +1318,10 @@ status_t GetNetworkInterfaceInfos(Queue<NetworkInterfaceInfo> & results, uint32
char outBuf[512];
if (WideCharToMultiByte(CP_UTF8, 0, pCurrAddresses->Description, -1, outBuf, sizeof(outBuf), NULL, NULL) <= 0) outBuf[0] = '\0';

if (results.AddTail(NetworkInterfaceInfo(pCurrAddresses->AdapterName, outBuf, unicastIP, netmask, broadcastIP, isEnabled, false)) == B_NO_ERROR)
uint64 mac = 0;
if (pCurrAddresses->PhysicalAddressLength == 6) for (uint32 i=0; i<6; i++) mac |= (((uint64)(pCurrAddresses->PhysicalAddress[i]))<<(8*(5-i)));

if (results.AddTail(NetworkInterfaceInfo(pCurrAddresses->AdapterName, outBuf, unicastIP, netmask, broadcastIP, isEnabled, false, mac)) == B_NO_ERROR)
{
if (_cachedLocalhostAddress == invalidIP) _cachedLocalhostAddress = unicastIP;
}
Expand Down
13 changes: 12 additions & 1 deletion util/NetworkUtilityFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -865,8 +865,9 @@ class NetworkInterfaceInfo MUSCLE_FINAL_CLASS
* @param broadcastIP The broadcast IP address associated with this interface.
* @param enabled True iff the interface is currently enabled; false if it is not.
* @param copper True iff the interface currently has an ethernet cable plugged into it.
* @param macAddress 48-bit MAC address value, or 0 if MAC address is unknown.
*/
NetworkInterfaceInfo(const String & name, const String & desc, const ip_address & ip, const ip_address & netmask, const ip_address & broadcastIP, bool enabled, bool copper);
NetworkInterfaceInfo(const String & name, const String & desc, const ip_address & ip, const ip_address & netmask, const ip_address & broadcastIP, bool enabled, bool copper, uint64 macAddress);

/** Returns the name of this interface, or "" if the name is not known. */
const String & GetName() const {return _name;}
Expand All @@ -886,6 +887,13 @@ class NetworkInterfaceInfo MUSCLE_FINAL_CLASS
*/
const ip_address & GetBroadcastAddress() const {return _broadcastIP;}

/** Returns the MAC address of this network interface, or 0 if the MAC address isn't known.
* Note that only the lower 48 bits of the returned 64-bit word are valid; the upper 16 bits will always be zero.
* @note This functionality is currently implemented under BSD/MacOSX, Linux, and Windows. Under other OS's where
* this information isn't implemented, this method will return 0.
*/
uint64 GetMACAddress() const {return _macAddress;}

/** Returns true iff this interface is currently enabled ("up"). */
bool IsEnabled() const {return _enabled;}

Expand All @@ -903,13 +911,16 @@ class NetworkInterfaceInfo MUSCLE_FINAL_CLASS
uint32 HashCode() const;

private:
friend status_t GetNetworkInterfaceInfos(Queue<NetworkInterfaceInfo> & results, uint32 includeBits); // so it can set the _macAddress field

String _name;
String _desc;
ip_address _ip;
ip_address _netmask;
ip_address _broadcastIP;
bool _enabled;
bool _copper;
uint64 _macAddress;
};

/** Bits that can be passed to GetNetworkInterfaceInfos() or GetNetworkInterfaceAddresses(). */
Expand Down
4 changes: 2 additions & 2 deletions vc++15/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ To compile muscle, do the following:

3. Click Build->Build Solution

3. Sit back and relax. The muscle build should complete in a minute or two.
4. Sit back and relax. The muscle build should complete in a minute or two.

4. Open the correct architecture directory and build type directory that are created inside vc++15. You should see three files there: admin.exe, muscled.exe, and muscle.lib. You can run your server with muscled.exe, and maintain it with admin.exe. You can build your own apps and link them against muscle.lib.
5. Open the correct architecture directory and build type directory that are created inside vc++15. You should see three files there: admin.exe, muscled.exe, and muscle.lib. You can run your server with muscled.exe, and maintain it with admin.exe. You can build your own apps and link them against muscle.lib.

-Mika Lindqvist (aka "Monni")

0 comments on commit 7fa0f0f

Please sign in to comment.