Next: , Previous: , Up: GNU Serveez   [Contents][Index]


6 Porting issues

Serveez was always designed with an eye on maximum portability. Autoconf and Automake have done a great job at this. A lot of #define’s help to work around some of the different Unix’ oddities. Have a look at config.h for a complete list of all these conditionals.

Most doubtful might be the Win32 port. There are two different ways of compiling Serveez on Win32: Cygwin and MinGW. The Cygwin version of Serveez depends on the Unix emulation layer DLL cygwin1.dll. Both versions work but it is preferable to use MinGW for performance reasons. The Cygwin version is slow and limited to a very low number (some 64) of open files/network connections.2

There are major differences between the Win32 and Unix implementations due to the completely different API those systems provide.

Processes and Threads

Because process communication is usually done by a pair of unidirectional pipes we chose that method in order to implement the coservers in Unix. The Win32 implementation are threads which are still part of the main process.

Sockets and Handles

On Win32 systems there is a difference in network sockets and file descriptors. Thus we had to implement quite a complex main socket loop.

Named Pipes

Both systems Unix and Win32 do provide this functionality (Windows NT 4.0 and above). The main differences here are the completely different APIs. On a common Unix you create a named pipe within the filesystem via mkfifo. On Win32 you have to CreateNamedPipe which will create some special network device. A further difference is what you can do with these pipes. On Win32 systems this ‘network device’ is valid on remote machines. Named pipes on Unix are unidirectional, on Win32 they are bidirectional and instantiatable.

Winsock Versions

There are some difference between the original Winsock 1.1 API and the new version 2.2.x. In a nutshell, WinSock 2 is WinSock 1.1 on steroids, it’s a superset of 1.1’s APIs and architecture. In addition to its new features, it also clarifies existing ambiguities in the 1.1 WinSock specification and adds new extensions that take advantage of operating system features and enhance application performance and efficiency. Finally, WinSock 2 includes a number of new protocol-specific extensions. These extensions –such as multicast socket options– are relegated to a separate annex, since the main WinSock 2 protocol specification is protocol-independent.

The Winsock DLL and import library for version 1.1 are wsock32.dll and wsock32.lib and for version 2.2 it is ws2_32.dll and ws2_32.lib. Serveez is currently using version 2.2.

The Winsock API is still a bit buggy. Connected datagram behaviors are not pertinent to any WinSock 2 features, but to generic WinSock. On Win95 it is possible to use recvfrom/WSARecvFrom on a “connected” UDP socket, but on NT4 recvfrom/WSARecvFrom fail with 10056 (WSAEISCONN). NOTE: sendto/WSASendTo fail with WSAEISCONN on both (which I do not see any reason for, but anyway ...).

Raw sockets on Windows systems

Raw sockets require Winsock 2. To use them under Windows NT/2000, you must be logged in as an Administrator. On any other Microsoft’s we were trying to use the ICMP.DLL (an idiotic and almost useless API) without success. Microsoft says they will replace it as soon as something better comes along. (Microsoft’s been saying this since the Windows 95 days, however, yet this functionality still exists in Windows 2000.) It seems like you cannot send ICMP or even raw packets from the userspace of Windows (except via the ICMP.DLL which is limited to echo requests). We also noticed that you cannot receive any packets previously sent. The only thing which works on all Windows systems (9x/ME/NT/2000/XP) is receiving packets the “kernel” itself generated (like echo replies). One good thing we noticed about Windows 2000 is that the checksums of fragmented ICMP packets get correctly recalculated. That is not the case in the current Linux kernels.

Miscellaneous

To use the Win32 Winsock in the Cygwin port, you just need to #define Win32_Winsock and #include "windows.h" at the top of your source file(s). You will also want to add -lwsock32 to the compiler’s command line so you link against libwsock32.a.

What preprocessor macros do I need to know about ? We use _WIN32 to signify access to the Win32 API and __CYGWIN__ for access to the Cygwin environment provided by the dll. We chose _WIN32 because this is what Microsoft defines in VC++ and we thought it would be a good idea for compatibility with VC++ code to follow their example. We use _MFC_VER to indicate code that should be compiled with VC++.

Why we do not use pipes for coservers ? Windows differentiates between sockets and file descriptors, that is why you can not select file descriptors. Please close the pipe’s descriptors via CloseHandle and not closesocket, because this will fail.

The C run-time libraries have a preset limit for the number of files that can be open at any one time. The limit for applications that link with the single-thread static library (LIBC.LIB) is 64 file handles or 20 file streams. Applications that link with either the static or dynamic multithread library (LIBCMT.LIB or MSVCRT.LIB and MSVCRT.DLL), have a limit of 256 file handles or 40 file streams. Attempting to open more than the maximum number of file handles or file streams causes program failure.

As far as I know, one of the big limitations of Winsock is that the SOCKET type is *not* equivalent to file descriptor. It is however with BSD and POSIX sockets. That is one of the major reasons for using a separate data type, SOCKET, not an int, a typical type for a file descriptor. This implies that you cannot mix SOCKETs and stdio, sorry. This is the case when you use -mno-cygwin.

Actually they are regular file handles, just like any other. There is a bug in all 9x/kernel32 libc/msv/crtdll interface implementations GetFileType returns TYPE_UNKNOWN for socket handles. Since this is AFAIK the only unknown type there is, you know you have a socket handle. There is a fix in the more recent perl distributions that you can use as a general solution. -loldnames -lperlcrt -lmsvcrt will get you TYPE_CHAR for socket handles.

Now follows the list on which operating systems and architectures Serveez has been build and tested successfully.


Footnotes

(2)

This was written circa 2003—maybe the situation is now improved.


Next: Bibliography, Previous: Embedding, Up: GNU Serveez   [Contents][Index]