Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Build

on: [push]

jobs:
linux:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1

- name: Run tests
run: make clean check

windows:

runs-on: windows-latest

steps:
- uses: actions/checkout@v1

- name: Add cl.exe to PATH
# uses: microsoft/setup-msbuild@v1
uses: seanmiddleditch/gha-setup-vsdevenv@v1

- name: Run tests
# run: msbuild -p:WindowsTargetPlatformVersion=10 test/UnitTests.vcxproj
run: make CXX="cl.exe" CXXFLAGS="-W4" LDLIBS="ws2_32.lib iphlpapi.lib qwave.lib" clean check

macos:

runs-on: macos-latest

steps:
- uses: actions/checkout@v1

- name: Run tests
run: make CXX="clang++ -std=c++11" LDLIBS=-ldl clean check
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ Debug
*.VC.*db
.vs

# Makefile files
# Makefile created files
obj
UnitTests
*.a
*.exe

*.log
13 changes: 9 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@

# Required variables
PROJECT_NAME :=smbb
COMPILE_ARGS :=-D_FILE_OFFSET_BITS=64 -D_LARGE_FILES=1
LINK_ARGS :=-lrt -ldl
DEFINE_ARGS :=-D_FILE_OFFSET_BITS=64 -D_LARGE_FILES=1 -D_WIN32_WINNT=0x0600
LDLIBS :=-lrt -ldl
DIR :=.

# Optional variables
CPPFLAGS +=$(DEFINE_ARGS)
CXXFLAGS :=-Wall -pedantic -O2

SRC :=$(wildcard $(DIR)/src/smbb/*.cxx $(DIR)/src/smbb/*/*.cxx)
OBJ :=$(patsubst $(DIR)/src/smbb/%.cxx,obj/%.o,$(SRC))
TESTS :=$(patsubst $(DIR)/test/%.cxx,%.exe,$(wildcard $(DIR)/test/*.cxx))
Expand All @@ -27,11 +32,11 @@ lib$(PROJECT_NAME).a: $(OBJ)

obj/%.o: $(DIR)/src/smbb/%.cxx
mkdir -p $(@D)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(COMPILE_ARGS) -Wall -pedantic -c $< -o $@
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@

# Tests
%.exe: $(DIR)/test/%.cxx
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(COMPILE_ARGS) -I$(DIR)/test/catch2 -I$(DIR)/src -Wall -pedantic -o $@ $^ $(LINK_ARGS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -I$(DIR)/test/catch2 -I$(DIR)/src -o $@ $^ $(LDLIBS)

%.exe.run: %.exe
./$<
4 changes: 2 additions & 2 deletions src/smbb/IPAddress.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ int smbb::IPAddress::Parse(IPAddress results[], int resultsSize, const char *add
addrinfo *result = NULL;
int i = 0;

if (!address && !service)
service = "";
if (!address && (!service || !service[0]))
service = "0";

info.ai_flags = (bindable ? AI_PASSIVE : 0) | AI_V4MAPPED;
info.ai_family = family;
Expand Down
21 changes: 15 additions & 6 deletions src/smbb/IPSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ SOFTWARE.
#define GET_OPTION_TYPE(NORMAL_TYPE, WINDOWS_TYPE) NORMAL_TYPE, NORMAL_TYPE
#endif

// BSD IPv6
#if !defined(IPV6_ADD_MEMBERSHIP) && defined(IPV6_JOIN_GROUP)
#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
#endif

#include "utilities/Inline.h"
#include "utilities/StaticCast.h"

Expand Down Expand Up @@ -404,8 +410,8 @@ class IPSocket {
}
else
#endif
if ((checkResult & SELECT_CAN_WRITE) != 0 && FD_ISSET(socket._handle, &_writeSet) == 0)
checkResult = static_cast<SelectValue>(checkResult & ~SELECT_CAN_WRITE);
if ((checkResult & SELECT_CAN_WRITE) != 0 && FD_ISSET(socket._handle, &_writeSet) == 0)
checkResult = static_cast<SelectValue>(checkResult & ~SELECT_CAN_WRITE);

if ((checkResult & SELECT_CAN_READ) != 0 && FD_ISSET(socket._handle, &_readSet) == 0)
checkResult = static_cast<SelectValue>(checkResult & ~SELECT_CAN_READ);
Expand Down Expand Up @@ -511,6 +517,9 @@ class IPSocket {
}
#endif // SMBB_NO_POLL

// TODO: kqueue on BSD/mac os
// TODO: epoll on Linux

private:
#if !defined(SMBB_NO_SOCKET_MSG)
// Helpers to get the recvmmsg and sendmmsg functions
Expand Down Expand Up @@ -1248,7 +1257,7 @@ class IPSocket {
}
#endif // SMBB_NO_SOCKET_MSG

// Gets the number of hops value for outgoing multicast packets
// Gets the number of hops value (TTL) for outgoing multicast packets
int GetMulticastHops() const {
int hops = -1;

Expand All @@ -1258,15 +1267,15 @@ class IPSocket {
return GetOptionInternalDefault<GET_OPTION_TYPE(int, DWORD)>(IPPROTO_IPV6, IPV6_MULTICAST_HOPS, hops);
}

// Sets the TTL value of the socket for outgoing unicast packets
// Sets the number of hops value (TTL) for outgoing multicast packets
Chainable<bool> SetMulticastHops(int value) {
if (SetOptionInternal<GET_OPTION_TYPE(int, DWORD)>(IPPROTO_IP, IP_MULTICAST_TTL, value))
return Chainable<bool>(this, true);

return Chainable<bool>(this, SetOptionInternal<GET_OPTION_TYPE(int, DWORD)>(IPPROTO_IPV6, IPV6_MULTICAST_HOPS, value));
}

// Gets the number of hops value for outgoing multicast packets
// Gets whether or not loopback is enabled for outgoing multicast packets
bool GetMulticastLoopback() const {
int loopback = 0;

Expand All @@ -1276,7 +1285,7 @@ class IPSocket {
return GetOptionInternalDefault<GET_OPTION_TYPE(int, DWORD)>(IPPROTO_IPV6, IPV6_MULTICAST_LOOP, loopback) != 0;
}

// Sets the TTL value of the socket for outgoing unicast packets
// Sets whether or not loopback is enabled for outgoing multicast packets
Chainable<bool> SetMulticastLoopback(bool value = true) {
if (SetOptionInternal<GET_OPTION_TYPE(int, DWORD)>(IPPROTO_IP, IP_MULTICAST_LOOP, value ? 1 : 0))
return Chainable<bool>(this, true);
Expand Down
10 changes: 6 additions & 4 deletions test/UnitTests.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,8 @@ static void TestTCP(const char *address, const char *port, IPAddressFamily famil

static bool TestMulticastUDP(const char *receiveAddress, const char *multicastAddress, const char *sendAddress, IPAddressFamily family = FAMILY_UNSPECIFIED) {
IPAddress ipAddress;
REQUIRE(IPAddress::Parse(&ipAddress, 1, receiveAddress, NULL, true, family) > 0);
int lastError = IPAddress::Parse(&ipAddress, 1, receiveAddress, NULL, true, family) > 0 ? 0 : IPSocket::LastError();
REQUIRE(lastError == 0);

// Setup the read socket
AutoCloseIPSocket readSocket(ipAddress, UDP, IPSocket::OPEN_AND_BIND);
Expand All @@ -284,7 +285,8 @@ static bool TestMulticastUDP(const char *receiveAddress, const char *multicastAd
DumpAddress(readSocket.GetAddress());

IPAddress multicast;
REQUIRE(IPAddress::Parse(&multicast, 1, multicastAddress, NULL, false, family) > 0);
lastError = IPAddress::Parse(&multicast, 1, multicastAddress, NULL, false, family) > 0 ? 0 : IPSocket::LastError();
REQUIRE(lastError == 0);
REQUIRE(multicast.IsMulticast());
std::cout << "Subscribing to ";
DumpAddress(multicast);
Expand Down Expand Up @@ -514,7 +516,7 @@ SCENARIO ("Select Test", "[IPSocket]") {
REQUIRE(connectToIPv6.SetNonblocking()->Connect(localIPv6Socket.GetAddress()) != IPSocket::CONNECT_SUCCESS);

sets.AddSocket(connectToIPv4, IPSocket::SELECT_IS_CONNECTED | IPSocket::SELECT_CONNECT_FAILED);
REQUIRE(sets.Wait(10000000) == 1); // Wait up to 10 seconds
REQUIRE(sets.Wait(100000000) == 1); // Wait up to 100 seconds
REQUIRE(sets.TestSocket(connectToIPv4, IPSocket::SELECT_IS_CONNECTED | IPSocket::SELECT_CONNECT_FAILED) == IPSocket::SELECT_CONNECT_FAILED);
sets.RemoveSocket(connectToIPv4, IPSocket::SELECT_CONNECT_FAILED);

Expand Down Expand Up @@ -644,7 +646,7 @@ SCENARIO ("Poll Test", "[IPSocket]") {

pollSet[0] = IPSocket::PollItem::Make(connectToIPv4, IPSocket::POLL_IS_CONNECTED);
REQUIRE(pollSet[0].GetMonitor() == IPSocket::POLL_IS_CONNECTED);
REQUIRE(IPSocket::Poll(pollSet, 1, 2000) >= 0); // Wait up to 3 seconds
REQUIRE(IPSocket::Poll(pollSet, 1, 200000) >= 0); // Wait up to 200 seconds
REQUIRE(pollSet[0].HasFailedConnectionResult());

pollSet[0].Disable();
Expand Down