Skip to content
Merged
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
dab8260
Add Windows support for pcm-sensor-server - platform abstraction layer
Copilot Oct 29, 2025
320ada6
Add Windows documentation for pcm-sensor-server
Copilot Oct 29, 2025
d7448eb
Address code review feedback - improve documentation clarity
Copilot Oct 29, 2025
d62fa93
Final verification and security summary
Copilot Oct 29, 2025
80d9847
Clean up CodeQL build artifacts
Copilot Oct 29, 2025
1ea5a9b
Fix Windows compilation error and improve macro safety
Copilot Oct 29, 2025
36c943a
Fix Windows build - define WIN32_LEAN_AND_MEAN before all includes
Copilot Oct 29, 2025
650f275
Fix JSONPrinter ambiguous symbol error on Windows
Copilot Oct 29, 2025
d4a0c1e
Fix DELETE macro conflict on Windows
Copilot Oct 29, 2025
f845a42
Rename DELETE enum to HTTP_DELETE to avoid Windows macro conflict
Copilot Oct 29, 2025
761f7bc
Rename URL struct to HTTPUrl to avoid Windows SDK conflict
Copilot Oct 29, 2025
8d9ba07
compile fixes
rdementi Oct 29, 2025
72394f1
Revert "Rename URL struct to HTTPUrl to avoid Windows SDK conflict"
rdementi Oct 29, 2025
4f33dfe
Fix gethostname linker error on Windows
Copilot Oct 29, 2025
244e562
Fix missing main function linker error on Windows
Copilot Oct 29, 2025
c9f0a2f
Add tchar.h include to utils.h for Windows _T macro support
Copilot Oct 29, 2025
10826a1
simplify src/CMakeLists.txt
rdementi Oct 29, 2025
9f6f751
fix compilation/linking on Windows
rdementi Oct 29, 2025
8049ed0
Revert "Fix missing main function linker error on Windows"
rdementi Oct 29, 2025
a895e64
Revert "Add tchar.h include to utils.h for Windows _T macro support"
rdementi Oct 29, 2025
39de009
improve error message
rdementi Oct 30, 2025
f63bb6d
Fix Winsock initialization - verify version 2.2 is available
Copilot Oct 30, 2025
16e28dc
Add IPv4 fallback for Windows socket creation
Copilot Oct 30, 2025
e5e5f19
Fix socket creation by explicitly specifying IPPROTO_TCP on Windows
Copilot Oct 30, 2025
d55c371
do not delete env var SystemRoot because it is required for winsock
rdementi Oct 30, 2025
f8d0193
Co-authored-by: rdementi <25432609+rdementi@users.noreply.github.com>
Copilot Oct 30, 2025
7eb7c2c
Make IPv4 default on Windows instead of IPv6
Copilot Oct 30, 2025
9048214
clean up PMU before the server is stopped on windows because the proc…
rdementi Oct 31, 2025
e2aabcd
Add --listen option to specify listening IP address for pcm-sensor-se…
Copilot Nov 11, 2025
5f41871
Update documentation with --listen option usage examples
Copilot Nov 11, 2025
62d6b93
Add IP address validation in command-line parsing
Copilot Nov 11, 2025
cd0d604
Add IPv4 command line option for pcm-sensor-server on non-Windows OS
Copilot Nov 12, 2025
e1a3e3d
improve messages
rdementi Nov 12, 2025
6b3485b
Merge remote-tracking branch 'opcm-github/master'
rdementi Nov 13, 2025
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
56 changes: 39 additions & 17 deletions src/pcm-sensor-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1388,7 +1388,7 @@ typedef basic_socketstream<wchar_t> wsocketstream;
class Server {
public:
Server() = delete;
Server( const std::string & listenIP, uint16_t port ) noexcept( false ) : listenIP_(listenIP), wq_( WorkQueue::getInstance() ), port_( port ) {
Server( const std::string & listenIP, uint16_t port, bool useIPv4 = false ) noexcept( false ) : listenIP_(listenIP), wq_( WorkQueue::getInstance() ), port_( port ), useIPv4_( useIPv4 ) {
DBG( 3, "Initializing Server" );
#ifdef _WIN32
// Initialize Winsock on Windows
Expand Down Expand Up @@ -1446,10 +1446,21 @@ class Server {
}
useIPv4 = true;
#else
socket_t sockfd = ::socket( AF_INET6, SOCK_STREAM, 0 );
if ( INVALID_SOCKET == sockfd )
{
throw std::runtime_error( "Server Constructor: Can't create socket" );
// On non-Windows systems, use IPv6 by default unless IPv4 is explicitly requested
useIPv4 = useIPv4_;
socket_t sockfd;
if ( useIPv4 ) {
sockfd = ::socket( AF_INET, SOCK_STREAM, 0 );
if ( INVALID_SOCKET == sockfd )
{
throw std::runtime_error( "Server Constructor: Can't create IPv4 socket" );
}
} else {
sockfd = ::socket( AF_INET6, SOCK_STREAM, 0 );
if ( INVALID_SOCKET == sockfd )
{
throw std::runtime_error( "Server Constructor: Can't create IPv6 socket" );
}
}
#endif

Expand All @@ -1469,7 +1480,7 @@ class Server {
{
DBG( 3, "close clientsocketFD" );
::close(sockfd);
throw std::runtime_error( "Server Constructor: Cannot convert IP string" );
throw std::runtime_error(std::string("Server Constructor: Cannot convert IP string ") + listenIP_ + " to IPv4 address");
}
}
socklen_t len = sizeof( struct sockaddr_in );
Expand All @@ -1491,7 +1502,7 @@ class Server {
#else
::close(sockfd);
#endif
throw std::runtime_error( "Server Constructor: Cannot convert IP string" );
throw std::runtime_error( std::string("Server Constructor: Cannot convert IP string ") + listenIP_ + " to IPv6 address" );
}
}
socklen_t len = sizeof( struct sockaddr_in6 );
Expand Down Expand Up @@ -1526,6 +1537,7 @@ class Server {
WorkQueue* wq_;
socket_t serverSocket_;
uint16_t port_;
bool useIPv4_;
};

enum HTTPRequestMethod {
Expand Down Expand Up @@ -3200,7 +3212,7 @@ class HTTPServer : public Server {
SignalHandler::getInstance()->setHTTPServer( this );
}

HTTPServer( std::string const & ip, uint16_t port ) : Server( ip, port ), stopped_( false ) {
HTTPServer( std::string const & ip, uint16_t port, bool useIPv4 = false ) : Server( ip, port, useIPv4 ), stopped_( false ) {
DBG( 3, "HTTPServer::HTTPServer( ip=", ip, ", port=", port, " )" );
callbackList_.resize( 256 );
createPeriodicCounterFetcher();
Expand Down Expand Up @@ -3455,7 +3467,7 @@ void HTTPServer::run() {
class HTTPSServer : public HTTPServer {
public:
HTTPSServer() : HTTPServer( "", 443 ) {}
HTTPSServer( std::string const & ip, uint16_t port ) : HTTPServer( ip, port ), sslCTX_( nullptr ) {}
HTTPSServer( std::string const & ip, uint16_t port, bool useIPv4 = false ) : HTTPServer( ip, port, useIPv4 ), sslCTX_( nullptr ) {}
HTTPSServer( HTTPSServer const & ) = delete;
HTTPSServer & operator = ( HTTPSServer const & ) = delete;
virtual ~HTTPSServer() {
Expand Down Expand Up @@ -3889,8 +3901,8 @@ void my_get_callback( HTTPServer* hs, HTTPRequest const & req, HTTPResponse & re
}
}

int startHTTPServer( const std::string& listenAddr, unsigned short port ) {
HTTPServer server( listenAddr, port );
int startHTTPServer( const std::string& listenAddr, unsigned short port, bool useIPv4 = false ) {
HTTPServer server( listenAddr, port, useIPv4 );
try {
// HEAD is GET without body, we will remove the body in execute()
server.registerCallback( HTTPRequestMethod::GET, my_get_callback );
Expand All @@ -3904,8 +3916,8 @@ int startHTTPServer( const std::string& listenAddr, unsigned short port ) {
}

#if defined (USE_SSL)
int startHTTPSServer( const std::string& listenAddr, unsigned short port, std::string const & cFile, std::string const & pkFile) {
HTTPSServer server( listenAddr, port );
int startHTTPSServer( const std::string& listenAddr, unsigned short port, std::string const & cFile, std::string const & pkFile, bool useIPv4 = false ) {
HTTPSServer server( listenAddr, port, useIPv4 );
try {
server.setPrivateKeyFile ( pkFile );
server.setCertificateFile( cFile );
Expand Down Expand Up @@ -3954,6 +3966,9 @@ void printHelpText( std::string const & programName ) {
#endif
std::cout << " -p portnumber : Run on port <portnumber> (default port is " << DEFAULT_HTTP_PORT << ")\n";
std::cout << " -l|--listen address : Listen on IP address <address> (default: all interfaces)\n";
#ifndef _WIN32
std::cout << " -4|--ipv4 : Use IPv4 instead of IPv6 (non-Windows only)\n";
#endif
std::cout << " -r|--reset : Reset programming of the performance counters.\n";
std::cout << " -D|--debug level : level = 0: no debug info, > 0 increase verbosity.\n";
#if !defined(__APPLE__) && !defined(_WIN32)
Expand Down Expand Up @@ -3992,6 +4007,7 @@ int mainThrows(int argc, char * argv[]) {
#endif
bool forceRTMAbortMode = false;
bool printTopology = false;
bool useIPv4 = false;
unsigned short port = 0;
unsigned short debug_level = 0;
std::string listenAddress = ""; // Empty string means listen on all interfaces
Expand Down Expand Up @@ -4044,6 +4060,12 @@ int mainThrows(int argc, char * argv[]) {
throw std::runtime_error( "main: Error no listen address argument given" );
}
}
#ifndef _WIN32
else if ( check_argument_equals( argv[i], {"-4", "--ipv4"} ) )
{
useIPv4 = true;
}
#endif
#if defined (USE_SSL)
else if ( check_argument_equals( argv[i], {"-s"} ) )
{
Expand Down Expand Up @@ -4328,17 +4350,17 @@ int mainThrows(int argc, char * argv[]) {
if ( useSSL ) {
if ( port == 0 )
port = DEFAULT_HTTPS_PORT;
std::string displayAddr = listenAddress.empty() ? "all interfaces" : listenAddress;
std::string displayAddr = listenAddress.empty() ? "localhost" : listenAddress;
std::cerr << "Starting SSL enabled server on https://" << displayAddr << ":" << port << "/\n";
startHTTPSServer( listenAddress, port, certificateFile, privateKeyFile );
startHTTPSServer( listenAddress, port, certificateFile, privateKeyFile, useIPv4 );
} else
#endif
{
if ( port == 0 )
port = DEFAULT_HTTP_PORT;
std::string displayAddr = listenAddress.empty() ? "all interfaces" : listenAddress;
std::string displayAddr = listenAddress.empty() ? "localhost" : listenAddress;
std::cerr << "Starting plain HTTP server on http://" << displayAddr << ":" << port << "/\n";
startHTTPServer( listenAddress, port );
startHTTPServer( listenAddress, port, useIPv4 );
}
delete pcmInstance;
} else if ( pid > 0 ) {
Expand Down
Loading