War FTP daemontm

The No.1 FTP server for Windows95, Windows98 and NT

Version 1.70

 

Preliminary documentation

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Copyright © 1996 - 1998 by Jarle Aase, Jgaa’s Internet

http://www.jgaa.com

All rights reserved.

 

 

War FTP Daemon is released as copyrighted freeware. You might use the software free of charge to whatever purposes you wish, private or commercially. Note: This software is not licensed to governmental or military use, and can not be purchased for such use.

 

 

 

 

 

 

 

War FTP Daemon™

This document is published by Jarle Aase, Jgaa’s Internet (http://www.jgaa.com)

Copyright © 1998 by Jarle Aase.

http://www.jgaa.com

Email:jgaa@jgaa.com

 

 

 

 

 

* * *

 

 

 

 

 

Jarle Aase is the author of the War FTP Daemon. He originally wrote 90% of the source code. The last 10-% is modified from public available source code.

Part of the source code is copyright 1989, 1993, 1994 "The Regents of the University of California. All rights reserved.".

Part of the source code is copyright "Sun Microsystems, Inc"

Part of the source code is copyright "1991, 1992, 1993 Free Software Foundation, Inc." after the GNU public licensing policy.

 

 

War FTP daemon™ is a trademark of Jarle Aase.

 

 

Table of contents

 

 

1 Introduction. *

2 Other FTP programs *

3 Disclamer *

4 Getting started *

4.1 Account properties *

4.1.1 Expiry *

4.2 Security properties *

4.2.1 FTP restrictions *

5 Technical overviews *

5.1 The overall design *

5.1.1 The Session Manager *

5.1.1.1 The status flag *

5.1.1.2 The session manager timer *

5.1.1.3 Multithreading *

5.2 The user database *

5.3 The file system *

5.4 ONC RPC notes *

 

1. Introduction

I started writing War FTP daemon back in November 1995, after realizing that there was no decent freeware FTP server for Windows. In fact, at that time there was no freeware FTP server at all, - only a number of crippled shareware servers, that really didn’t impress me too much. When the server was released about half a year later, it became very popular, and got a large number of very impressive reviews. One year later, the War FTP Daemon was generally regarded as the #1 FTP server for Windows. When reviewing other servers, the War FTP daemon is usually used as a reference, and the only scores given to other servers these days are simplicity. War FTP daemon obviously has all imaginable features, and hence, is a bit tricky to use for some users/reviewers. (Well – there is room for improvements, as you will see.)

In October 1996 I started to work on War FTP Daemon version 2. In December the source code for the alpha (pre-release) version was released, - and I continued to work on the code in order to release a beta. One year after I started on version 2, I decided to discontinue the development. The code was growing too complex, and the design had some major drawbacks. I made some research on a new design, and came up with some brilliant ideas for version 3. The time frame for version 3 was at least one year, so I decided to release a version 1.70, partially based on the design of the original server, and partially on the ideas for version 3. As I worked on 1.70, more and more code was written from scratch, or stolen from version 2 (the design had drawbacks, but after 1 year of development, version 2 indeed had some very useful and well debugged source code modules). Version 1.70 is in fact a bright new server, as almost no source code is left from version 1.66.

You might ask, what are the main changes since 1.66? Well – first of all – the server module and the user interface is split into different programs. The server is written using portable code, code that will soon be ported to Linux/Unix. The user interface is built on top of MFC – providing a state of the art Windows95/98 user interface. Most of the problems reported with previous versions have been related to users having problems figuring out how to configure the server correctly. When I designed the new user interface, I tried to meet the requirements of the most sophisticated user needs, while also making the configuration an easy task for novice users. The server code is also more robust, and has intelligent interpreting/error checking of configuration options. The user interface communicate with the server using ONC RPC (former SUN RPC), which is a well-established platform-independent protocol. The use of ONC RPC makes it possible for the server and the user interface to run on different machines, using different operating systems and even different microprocessor families (Intel/Alpha/Motorola). A Web server running on an enterprise Unix server can easily communicate with the War FTP Daemon, running on an NT server – just to mention one big benefit. The imagination of the users (and the skills of their programmers/software development departments) is the only thing that limits the possibilities with this new design.

The specs of 1.70 looks very much like the specs of version 2 – what’s the difference between these versions? The main differences are that 1.70, from the outside, looks more like 1.66 than 2.0. 1.70 also lacks the plugin API interface promised for version 2. On the inside, 1.70 looks very much like version 2.

Ok – the server is very neat, flexible and easy – but to whom is it targeted? The only answer to that question is - to you! The server is scalable, making it the best choice for any FTP server need, no matter if you just want to share files between your work and home PC, or run a large-scale FTP server on Internet. The server is designed to meet any imaginable need’s The only drawback for professional use is that the CPU/memory usage is a bit higher than the simplest competitors, such a MS FTP service or wftpd. But hardware is cheap – and this server takes full advantage of multi-CPU hardware for the largest imaginable FTP servers. While 1.66 was developed on a 10mbit network, and is unable to provide much more than 1 MB/sec throughput, 1.70 is developed on a 100mbit network (using a dual Pentium II motherboard on the development PC), and is only limited by the networking hardware in the machine!

 

When I told my friends that I was going to make a new FTP server, they asked me why? What would I gain? I already made the best FTP server ever written. There was no way I could get better ratings, as version 1.x already had top ratings on all major software sites on the net! To tell you the truth – the only reason for the top-ratings is that the other FTP servers are crap! War FTP daemon 1.x actually sucks, as it have major design drawbacks, poor performance, serious bugs, and even lack the possibility to access the maintenance display when the server runs as a NT service! When I first started my goal was to make the first decent freeware FTP server for Windows. My goal with 1.70, and later on version 3, is perfection. My goal is not just to make the best FTP server (that’s no big deal with today’s competitors), - but making the best Internet server ever. That means writing c++ code that is poetry, taking maximum advantage of the hardware where the server is running, and being compatible with all related software, such as FTP clients, operating systems, and administrative tools.

At last – why did 1.70 take so long? Well – there are several reasons. I changed my mind about the scale of the changes. I also had some periods, lasting from weeks to months, where I was unable to do any coding at all due to personal problems. (I was the victim of a false conviction back in 1994. Sometimes the rage against the society and the so called ‘justice system’ is so strong that all I can focus on is figuring out very painful ways to kill judges and police officers.) I also wanted to introduce some new features in 1.70. After almost two years without any major improvements, I needed to take the time to test and debug as much as possible.

What new features can be expected from the War FTP daemon? There are limitations to the FTP protocol. In 1997 I tried to make some suggestions to the FTP working group in regards of the next version of the FTP protocol. I was however pretty much ignored in that forum; something I found strange, as the War FTP daemon is among the most used FTP servers in the world. Anyway, I decided to work on my own server, rather than challenging the egos of people I’ve never heard about before, and just implement the new FTP specs in the server when (or rather if) they ever reach to a conclusion. War FTP daemon will be 100% compliant with the FTP protocol specification, but I will add my own new features to the protocol, that can be enabled by any FTP clients that support them. Since this server is so widely used, I hope that FTP client writers will take advantage of the extensions I make, such as the interactive chat protocol, enhanced directory listings, asynchronous response messages, encryption, and enhanced file information options. In the end, it’s up to the users do decide what FTP clients, and what features, they want.

 

  1. Other FTP programs

Today it seems like every neewbie socket programmer has to make his own FTP server or client – and that means that there is a huge number of programs available – free as well as commercial. I won’t list them all, as the list would be outdated in just a few weeks. To get kindof an overview of the Windows applications, visit http://www.nonags.com for the free ones, and http://windows95.com or http://www.tucows.com for freeware, shareware, and demoware.

There are however a small number of significant programs, that leads the way. Among FTP servers, you have wu-ftpd for Linux/Unix – probably the mostly used FTP server in the world, and wftpd for Windows. Wftpd was the first Winsock FTP server ever, and the author, Alun Jones, also helped giving birth to other ftp servers, such as serv-u, and has always been very active in the Winsock newsgroups, helping newbie programmers (and also the more experienced ones) out. Alun Jones is btw, the only programmer ever that have received any significant part of the pre 1.70 War-ftpd source code.

Among FTP clients for Unix, you have the original ftp client, which is rather primitive, and ncftp, which is my favorite command line FTP client. Ncftp is also available for 32 bit DOS (DOS running from Windows95 or NT). Among Windows FTP clients there are two very significant (and popular) choices, ws-ftp written by John A. Junod (early versions are available with full source code), and cute-ftp, written by Alex Kunadze (both are crippleware/shareware). Before I wrote my own FTP client (which was really not ready for mass distribution yet), Cute Ftp was my personal choice. Among the more fancy Windows clients, I could mention FTP explorer.

 

 

  1. Disclamer

I take all the usual precautions, and I am not responsible for any damage you might experience using my software.

I do, however take my software seriously. There are no backdoors, traps, bombs, viruses or any other shit put into the software. My computers run anti-virus programs and all versions, released as well as internal, are scanned for viruses. If serious problems regarding the security is reported, I usually post a patch very soon, and broadcast information about the patch in mailing lists and in the alt.comp.jgaa newsgroup.

The quality of the software is at a commercial level, and several large, worldwide corporations, use the software. When you use the War FTP daemon, you can expect bulletproof security, the very best performance, and reliable operation. If you experience problems, there are free as well as commercial support available. No company back the software, but I do, and I don’t have to take commercial considerations. If I need to spend two weeks in order to implement a neat feature that no one ever thought about, and even fewer will need, that’s what I’ll do. My motivation is not money, it’s the satisfaction of making something that is of world class quality, and the satisfaction of being the very best in the world at what I do. I’m not a very skilled programmer, I just use my imagination and take the time I need to get the job done.

 

 

 

 

4. Getting started

The current version lacks the final polishing of a normal application and there are some steps to take in order to make the server work.

First of all, there is no installation program. To install the server, unzip the distribution archive to an empty directory. If you want to upgrade from a previous version if War FTP Daemon, copy FtpDaemon.dat and FtpDaemon.ini from the current War FTPd server directory to the new directory before the server is started for the first time. Then start the server by executing WarFTPdv1.exe. To start to configure the server, start WarDaemonManager.exe.

When the daemon manager is started, the first thing you should do is to configure the internal DNS server variable.

Open the Advanced Server properties dialog and select

Sock_DNSserver. Type in the IP address to your DNS server and press the [SET] button. If you don’t know the IP address to your DNS server, you can use a utility like nslookup.exe to get that. If you use an ISDN or modem dialup connection, you might have to call your ISP to get the DNS server address.

Now, shut down the server by pressing the STOP button .

Exit the WarDaemonManager and restart first the server, and then the manager.

Now it’s time to configure the file permissions.

Press the User Manager button

 

 

and select the Security - File Access settings.

 

If you have upgraded from a previous version, you might have some references to VfSys in the file access list. VfSys is not yet implemented, so you will have to ‘convert’ the VfSys paths to file paths before they will be accessible for users.

Double click on each of the paths you need to convert and select

File as file system.

Make sure that the paths are valid. If you want to change the logical mapping (how the user see the path), you can disable the auto-arrange feature by checking the ‘freeze’ option and type in the mount point you prefer.

 

If you want to add new paths, the fastest way is to drag the paths from Windows Explorer into the file access list and then set the permissions. If you right click on a path or a group of marked paths, you can set common permission flags from a right-click menu.

Go over the user accounts and check that the users you want to give access to the server have FTP login access.

When the server is configured, shut it down, exit the manager, and start it again, - first the server, then the manager.

The performance of the current server has not yet been optimized for speed. I have performance readings from 300 to 6500 kb/s. It seems like system calls are slowing down the performance. If the buffer size is increased from 16 KB to 2 MB, the average transfer speed (on read) is raised from 500 Kb/s to 2100 KB/s. If I use the War FTP Client with 1 MB buffers and high priority, I can get readings up to 1,500,000 kb/s on 1 MB files.

    1. Release notes for 1.69x06

The manager should now be reasonable stable. It will crash if the connection to the server is lost, while a dialog is open. It will also freeze if you click in the manager when the server is shutting down.

All the standard FTP commands are implemented. The only significant features that are missing at this time are:

The new features and the security are not 100% debugged. Please try normal (and odd) FTP operations, and try to break trough the security.

Jarle

 

  1. The Daemon manager
    1. Account properties
      1. Expiry

      The expiry options allows you to set a date or condition on when the user account expires.

      When the account expires, it can be moved to the parent node of the anonymous user (usually the visitor class), disabled (login denied), or deleted.

      Note: If it is moved to the parent of the anonymous user, properties set up for this account (and not for the parent node) will be kept. Therefore – if you plan to move accounts to the anonymous parent when they expire, do not give the account itself special privileges. Give the privileges to the parent node. That way the user will lose his privileges when the account is moved.

      If you use the date, the date expires at 00:00 local time at the given date.

      If you set the properties on a non-user node and check the ‘Set relative to next login’ box, the properties will be activated on each affected user node as the log on. The user node copies the inherited properties, and the settings are used on the user level. If you decide to change the settings, for all the affected users, you will have to go trough the affected user nodes manually and correct the settings.

      Login counts, if you use that method is counted as multisession logins. That means – if a user log on several times simultaneously, or within a short time-interval, that is counted as one login. This gives users of FTP clients like FTP Explorer, or Web browsers the same number of ‘logins’ as other users.

      This option is designed for automatically created user accounts.

    2. Security properties
      1. FTP restrictions

    The idle time is the longest time interval a user can remain online without giving a command, when there is no file transfers going on. Some FTP clients will issue a NOOP command to reset this timer. If so desired, you can configure the server to not reset the idle-time timer in the advanced server property dialog (ftpd_NOOP option). By default the server will reset the timer.

    The max simultaneous sessions setting allow you to restrict the total number of logins from one user account. Be aware that many persons share some user accounts, like the anonymous user and that such accounts therefore should have a larger value than normal single-user accounts.

    The max simultaneous sessions from one machine setting allows you to limit the number of sessions a single machine can open. Be aware that some FTP clients will open 2 connections, one for data transfers, and one for directory browsing. Web browsers also tend to open several connections, even if they only want to get one file. This setting should therefore be 2 or more.

    The max time setting allows you to restrict the maximum time a single connection can last. When this time limit has expired, the server will disconnect the user as soon as the current operation is completed, or immediately if the user is idle.

    The max CPS limit is measured in sampled and total CPS for the connection. The method used to limit the CPS is to check the CPS after all network traffic. If the current CPS reading or the total CPS reading exceeds the limit, the transfer is suspended until the reading is below the limit. If the machine has large network buffers, and the limit is small, this can result in suspension in several seconds. The connections are tested individually, so one or more transfers can be suspended while other transfers are active. A more advanced CPS scheduling - based on the total available bandwidth for the server and group priorities is planned.

     

  2. Implementation notes
    1. RAS/ppp connections and IP numbers
    2. Version 1.70 has special support for RAS/ppp connections. The server will check the current IP numbers assigned to the machine at an interval specified with the sesmgr_IPCHK system variable (default 360 seconds). If there has been a change since last time, the FTP virtual domain server(s) will reinitialize, and new IP number(s) will be handled. If you use a RAS/ppp connection you might lower the interval to maybe a few seconds.

      Most machines will only have one virtual domain (System) and listen to all IP numbers available to the machine (INADDR_ANY). The RAS/ppp IP enumeration will work on all configurations, from one to any numbers of virtual domains.

      Currently you should expect connections from your RAS/ppp lines to occur on the virtual FTP server assigned to INADDR_ANY.

      Note: The server will not do any attempt to re-connect your machine to Internet if a RAS/ppp connection is shut down. I can easily implement this if there is a demand for such an option.

      Technical note: I have not used the callback features in the RAS API or Winsock2 for this feature, as these calls require NT or Windows 98. I might add callback support in the future to detect changes as soon as they take effect. The current design will however work on all machine configurations, and it seems to be pretty efficient.

    3. Winsock

    The server loads the Winsock .dll dynamically, and can therefore use Winsock 2.x features (if the machine uses Winsock 2) from one .exe file. (Normally a program is either compiled to use Winsock 1.1 or 2.x, where the 1.1 build can use Winsock 2, but not native Winsock 2 features).

  3. Technical overviews
  4. The technical overviews are primarily written to help developers use the source code for the war server, and to interface plugins and other programs to the server. This chapter has little general interest for users of the software.

    1. The overall design
    2. The server consists of several more or less independent modules. The most important module to understand is the Server Control. The user database has two independent modules, - the User Database server module that handle all user information, and the session manager that keeps track of the current state of user connections. Both modules communicate with the outside world (and other server modules) trough the WarUserHandle interface.

      The communication between modules is based on message passing. When a module needs some information from another module, a message is sent, and a reply returned. To avoid dead-locking situations where two modules send to each other at the same time, some modules are designed as server-modules and others as client-modules. A module can also ask the server for some modules, and client to others. The User Database is server for all other modules, except for the log module – since it needs to write to the log.

      1. The Session Manager

The session manager keeps track of all activity in the server. It is also responsible for the security. The session manager has 4 important lists to manage:

  1. Hosts
  2. Users
  3. Servers
  4. Sessions

The Hosts list contains all current and recent hosts that has connected or tried to connect to the server. When a connection is established, the session manager looks for the connecting host in the Hosts list. If it is unresolved, a reverse DNS lookup is initiated, and the session denied. When the DNS lookup is complete, the Host entry set a flag that indicate that logins are allowed to proceed. The following scheme illustrate this:

An FTP client connects to the FTP server. The FTP server queries the session manager about the host. A reverse DNS lookup is initiated and the connection refused. The FTP server doesn’t reject the client connection, but keeps re-querying the session manager at a relaxed interval until it get another answer than "Rejected – DNS lookup in progress". Sooner or later the DNS lookup completes, and the FTP server sends the welcome message to the user – and asks for a username. When it has the user-name, the FTP server queries the session manager about a login. If the user has no password, the session manager says yes, and the FTP server pass the good news to the FTP client. If the user has a password, the session manager complains about the missing password, and the FTP server asks the client about the password. The FTP server then re-tries a login with the session manager, and gets a final yes or no.

The user list contains one entry for each user account that is online or was online very recently (up to a few seconds ago). This list is used by the session manager to limit the number of concurrent sessions from one user, and to store information about the user. This ‘cache’ function makes it unnecessary to query the user database about user information all the time.

The Server list contains one entry for each virtual domain that is active. Normally you will have only one virtual domain active, because one domain can listen to all the IP numbers assigned to the machine. But if you are in the business of WWW/FTP hosting, you might have several virtual domains in this list, where each virtual domain handle one IP number and one eventually handle the rest of the IP numbers assigned to the machine. The server list is used by the session manager to control the virtual FTP servers. Do you remember the server/client design mentioned earlier? Since the Session Manager acts as a server module for the FTP server, it can’t contact the FTP server modules to inform about important events, like a system shutdown. Instead, it relays such information in the server list, and waits until the virtual domain’s FTP server module asks about the current states to pass the information on. In the occasion of a system shutdown, the FTP server module will consider the nature of the shutdown (shutdown when ready or immediately) and either throw all users off and resign from the server list, or throw each user off as he complete the current file transfer.

The session list contains unique information about each user, batch and administrator connection to the server. This list is used to control the idle time of each connection, status information for the War Daemon Manager, and counters used by different features like the up/download ratio.

 

        1. The status flag
        2. The session manager has a 32 bit flag variable that contain the current state of the system. Each node in the four lists has a similar flag that contain the status of the connection/connections referenced by that list. When a virtual domain FTP server wants the current state of a connection, it queries the session Manager. The session manager takes the five relevant flags and performs a binary or operation ‘|’, and return the result to the FTP server. The combined bits in the five flags tell the FTP server the state of that particular user connection. This design makes it very easy to set different states on a group of connections, like all connections from a certain host or from a certain user account.

           

           

           

           

        3. The session manager timer
        4. The session manager is the logical core module of the server. Therefore it has to perform some housekeeping at regular intervals. This is implemented in the OnTimer() function, which is called automatically each second, independently of the current load on the server.

          The timer checks the idle time and other timers on each connection, checks the shutdown status if the server is in a state of shutdown, and calls more extensive housekeeping procedures at more relaxed intervals.

           

        5. Multithreading

The user database and session manager is designed to run in one thread. Other modules might share this thread, or run in their own thread. The session manager performs no disk access at all, and the user database performs only occasional disk access, when auto-saving the user database. A multithreading design in these modules would most likely add so much system overhead, compared with the current design; that the total performance could decrease – even on a multi CPU system.

 

      1. The user database

The user database is kept in memory. It is structured as a binary tree, where the actual user properties are linked from a tree-node. The design is inspired from the UNIX file system, and allows several tree nodes to link to the same physical user properties. (This ‘hard link’ design is not 100% finished, and therefore there are no high-level functions to actually link a user to another tree node.) The user database is based on the WarTree, WarTreeNode and WarTreeInode base classes, - originally designed for the virtual file system.

Many user properties can be recursive. When the server needs some information about a node (user, class, group, virtual domain) – special functions are used to search the tree recursively for the information, until a valid value or a default value is found. These functions are called through the WarUserNode class, or, more conveniently, trough the WarUserHandle high-level interface.

 

    1. The file system
    2. The file system in version 1.70 is significantly improved from 1.66, and even improved from the original draft for version 2.

      The basis of the internal file system is the File Access Paths. This is a list of paths with access permissions, assigned to a user or a lower node in the user tree. Each defined path has a logical and a physical name. The server normally assigns the logical name, while the physical name is a path to your physical file system.

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

      Figure 1 File access paths

      The same path can be defined on different levels in the user tree. When the server scans the File Access Paths in response to a user command (i.e. a directory listing), the highest level will take precedence if the path also exist on lower levels. That means that you can deny access to a path for everyone, but a few selected users, or user groups.

      Unlike previous versions, you can have some paths directly pointing to the disk and other mapped trough the enhanced Virtual File System. You can now also map network paths directly, without the need to assign drive letters. Future versions of the server will add new file system types, like NFS and remote FTP, allowing the War FTP daemon to act like a proxy server. All these file systems share a simple, common interface, making maintenance an easy issue. The file system present itself to the user as one integrated UNIX like file system, starting with the ‘root path’ /. If you choose to display directory listing compatible with the DOS "DIR" command, the top-level will be "C:\", no matter where the physical directories exist.

      When you set up the file system, you have full control with what parts of your disks/network you will share with your FTP users. No one will have "unlimited access" to the disks/network – not even you – unless you declare all your drives in the File Access Paths.

    3. Callbacks, events and timers
    4. Normal applications have one thread, a user interface and some processing to do in response to user input or other events. To design a ‘normal application’ is relatively easy. You can use static variables, and you have instant access to all the information the application knows about. War FTP Daemon 1.70 is far from such a delightful reality…

      The server consists of several modules that might or might not run in the same thread. It might or might not run as a NT or Win95 system service, and it is designed to meet all kind of requirements – from the simple home-user, to high demand specialized servers with automated management and thousands of user accounts. The user interface might or might not run, and it might run in several instances on different machines at the same time. In addition, cgi-scripts and custom written management modules might log on to alter the user database or the server status – or to monitor the server.

      There are several ways to design an application to meet all these needs. All possible designs have their good and bad sides. The most fancy design would be one based on callbacks and shared memory, and sockets to provide network-wide broadcasts and callback events. Such a design would however be very vulnerable for deadlocks. The original code for version 2 of the server was based on such a design, and it worked; but it was tied up very much by the Win32 platform and made porting to other operating systems a pain. The design of 1.70 is based on more traditional polling. When a module needs some information, it asks another module about it. And different modules are responsible of maintaining different information. The code is written to be portable and reliable, rather than fancy and fast. Experience has proved to me that it’s better to write reliable code that looks ‘slow’ and then optimize the few real bottlenecks in the program, rather than trying to make each function perform as fast as possible.

      The current design is based partly on polling and partly callbacks. During an FTP session, the FTP session module (that is part of the virtual domain module) updates the session manager when a user gives a command, and at a given interval. The session manager organizes the information in it’s lists, and validates the connections at given intervals. The War Daemon Manager queries the session manager about the current state when it needs to update the user list and spy windows. Each module has their own timers that decide when to contact other modules or perform housekeeping.

      All the timers in the server depend on a master timer maintained by the WarSocket socket engine. The interval in which this timer is triggered depends on the code-module the socket engine is configured use (events, windows messages or the portable select() method) and the state of other modules, like pending file system callback events in NT. Each time the master timer is triggered, it checks the time-out value of itself. If the timeout value is expired, it checks the time-out value for each WarSocket owned by the current thread (FTP virtual domains, FTP user connections, FTP Data connections, DNS lookup sockets, and RPC/Batch connections). Then it checks suspension timeout on suspended sockets (FTP connections with a pending request to a ‘slow’ module like VfSys, or fresh connections waiting for the session manager to complete the reverse DNS lookup). In addition to socket timeouts, it also checks a list of registered external timers. The OnTimer() function in the Session Manager has registered one such timer.

      The timers use the WarTimer class to decide if a timeout has occurred. The timer resolution is measured in milliseconds (1/1000 second), and spawns at least 50 years into the future, as the timer value itself is 64 bits. The advantage of this design is the high resolution and the flexibility – you can set a timer a few ms into the future (socket timeouts), or define an event that occurs years into the future (user account expiration). The disadvantage is the fact that the current INTEL CPU’s use 32 bits and that 64-bit resolution represents an (often) unnecessary overhead. The longest interval I can track in milliseconds using 32 bits is a little more than 1 month. Using 32 bits would be faster, but the timer would have to handle rollovers if the server was running for months without a shutdown. I might change the design of the WarTimer class if it turns out that using 64-bit it takes too much CPU time. But I believe that the overhead will only be measurable on servers with very many simultaneous connections – and they will typically run on 64 or 128 bits CPU’s or multiprocessor systems.

      As you can see – wherever possible, I have chosen to use polling/querying to synchronize information. But since network events are just that – events – and different modules work at different speeds, the client connections are to a large degree also event driven. Let’s have another example:

      The FTP client requests to upload a file, the FTP Connection module asks the session manager about the users permissions to the path, and performs a preliminary access check, then it checks what file system the user will access, the file belongs to VfSys and the user creates a WfSysFile object trough the WarFile::CreateForURL() call. Then it calls VfSysFile::Open(). VfSys doesn’t have the path in it’s cache and decides to scan the path and do some housekeeping before it can process the open call. It queues the request and throws a C++ exception. The FTP session module traps the exception, suspends the connection and continues serving other connections. VfSys, running in it’s own thread(s), scans the disk, checks it’s own permissions against the open parameters, and decides that the user can upload the file. It transfers the result of the request to the FTP session module, release the suspension, and continue serving other requests. Once the suspend state is released, the FTP session module recalls what it was doing before the exception occurred, and calls a function that represent the next step in the process of uploading the file. The session module calls the session manager for the second time and asks for a final decision whether or not to accept the upload request. This time it knows the full physical file name (after links are resolved) and if the file exists on the disk. The session manager compares the path against the paths in the file access list for the user, checks the banned files list for the user, verifies available disk space (as reported by VfSys) and disk quota limit (against summaries reported by VfSys) and gives a final ok. The FTP session module creates an FTP data socket and initiates a connection to the FTP client in the other end of the connection. Then it suspends itself to await the result of the transfer. The server continues to serve other users while the data socket awaits the connection to be established. The data connection gets connected and the transfer starts. After a few milliseconds, the data socket realizes that the CPS limit for the user is expired. The data socket suspends itself and checks the CPS rate on a 500-millisecond timer interval. When the CPS limit is valid, it releases the suspension and continues to pump data. After a few seconds the transfer is complete. The data socket again calls the session manager to confirm the upload. The session manager checks upload processors, and decide to verify the uploaded file with an external program. The data socket is instructed to suspend itself until the upload processor is finished – or times out. After a while the upload processor accepts the file, and the upload processor module releases the suspension of the FTP data socket. The FTP data socket informs the session manager about the upload, and then destroys the VfSys file object. It then releases the suspension for the FTP session module and destroys itself. The FTP Session module goes back into a normal state where it accepts new FTP client requests.

      This example gives a brief overview of a theoretical file transfer. At this time, some of the described modules are unimplemented. This example only had two callback events. In real-life, the connection might experience several callback events, especially if the external file system is a network path (remote VfSsys, NFS, FTP) or a slow/overloaded disk. This means that the FTP connection module must be able to handle both timers (inform the session manager about the progress on long-lasting transfers) and callbacks on all Input/output calls. It must also handle the situation where the connection is broken during a pending callback event.

       

       

    5. Server extension guidelines

It’s too early to write a full set of guidelines for those of you working on server extensions. There will be a well-defined plugin interface, and there will be a well-defined API for external programs. At this time I can say the following:

  1. If you need to access the user database/session manager – use the WarUserHandle class. This class is thread-safe, and will handle communications in an optimal manner, no matter if you use the same thread as the user database or another. Note: All FTP user sessions or WarFile objects owned by an FTP user session has valid WarUserHandle objects you can use in most situations.
  2. Use the SesMgr.GetOption() call to access global variables. This call is faster than WarUserHandle(), but still thread-safe.
  3. Don’t make any assumptions about threads. A client connection might or might not run in it’s own thread. Your code must be thread-safe. Avoid static variables.
  4. Never hold on to the current thread more than a few milliseconds. If you need to perform timely operations, use worker threads and callbacks. If you stall on network traffic, use WarSocket’s and override the On*() callback functions. The WarSocket class will provide the best overall performance on TCP/IP connections. If you need to test time-out values or perform housekeeping, install your own external timers.

 

    1. Dynamically linked .dll’s
    2. Version 1.70 does not only require the basic system dll’s in order to run. All special dll’s, like Winsock, RAS etc. are loaded dynamically if they exist, and the server will detect if a dll has different features implemented. That means that the same binary can be used for Winsock 1.1 and 2.x, and for the NT and Windows 95 versions of RAS.

      If you modify the server code, you can easily check if a dll function is available:

      if (__CallnName)

      {

      // The call exists. Now, use it..

      int Rval = CallName(params);

      ..

      }

      See "WarWin32Support.cpp" for implementation details.

    3. ONC RPC notes

RPC (Remote Procedure Call) is used to communicate with the server. In order to make communications independent of vendors (like Intel or Microsoft), ONC RPC (former Sun RPC) is used. One major benefit from this choice is that servers running under Win95 can have full RPC server capabilities (Microsoft has only implemented the MS RPC server interface for NT).

The RPC interface is defined in resource files, ending on .x. A special program, wrpcgen, reads these files, and translate the interface into c code. Then the interface can be compiled with a c/c++ compiler and used by programs.

Wrpcgen is based on Sun’s original rpcgen utility. Changes have been made to interface the RPC source modules with the War server, and to make client calls thread-safe. The header files and source files used for the ONC RPC interface in the war server and other programs are not 100% compatible with the original files. If you are going to interface a program with the war server, the most convenient way will be to simply compile the source files for the war server, and then call high-level functions to do the job. Or – if you prefer it the ‘hard’ way – to compile the .x files with Sun’s original rpcgen and use the source modules produced by that. Note that there is a hack to implement reasonable security into the RPC interface. You have to study the WarUserHandle::RPCLogin() function in order to write your own login function to the user database/session manager.

The reason for the changes was the need to auto-generate source code modules that would fit into the War server framework, and the need to make the client modules thread-safe.