UDP Andy McFadden's UDP client, the wave of the future ---------------------------------------------------------------------- From: fadden@uts.amdahl.com (Andy McFadden) Newsgroups: alt.games.xtrek Subject: UDP client available for testing Date: 8 Mar 92 23:45:51 GMT Last night (Saturday) I went a few rounds with Tedd Hadley on a UCI machine. What made this worthy of note was that: - I'm in Santa Clara - I'm running through a gateway machine, so there's a user-level process transferring every packet - I was using a UDP connection - I was smoothly running at NINE UPDATES PER SECOND Initial results have been pretty impressive. What we haven't tried is using UDP clients on a server during a full game. So, a client binary (currently Sun 4 only, since that's all we have) is being made available for you to try. The server information: codes.ics.uci.edu 128.195.10.25 (2592) 7 days/24 hours for now; however, not guaranteed indefinitely. The client (sun 4, SunOS 4.1.1, X11R4 only): pittslug.sug.org: /pub/udp_client.sun4 (once they move it from the /incoming directory) also cad.ics.uci.edu: /pub/netrek/udp_client.sun4 The short description of what to do is: connect to the server, hit '+', and hit the button labeled "switch to UDP." Most of the controls are pretty obvious. You might want to leave the '+' menu up, since it will tell you how many packets have been lost. To see something amusing, try disabling the sequence checking. Every once in a while you'll get some packets out of order, and your ship updates will look like those old Purina cat chow ads... It won't tell you when packets have simply been lost though. Feel free to try the client on other servers. Attempting to switch to UDP will simply cause a warning message after a few seconds. Running older clients on the UDP server is also fine; you're 100% TCP until you hit the magic button. (This is commonly referred to as "bolting a feature onto the side.") If you have problems or want to make a suggestion, send me some mail (don't bother the server op unless the daemon's dead or something like that.) The binary-only release is only until we are sure that the UDP code is relatively bug-free and isn't lacking anything important. Once I feel confident about this stuff, I'll put the source code up for grabs. (I may do a limited initial release on the server source... that way if something's flaky or we need to tune it for better performance, there'll be a smaller group to distribute fixes to.) This is the UDP_README file; it is not required reading unless you want to know what's going on inside. To play all you need to know is '+'. ===== Netrek UDP enhancements Andy McFadden (fadden@uts.amdahl.com) --- PROTOTYPE INFO v0.2 -*- NOTHING IS FINAL --- Goals ===== A protocol which: - guarantees the reliability of certain packets - allows switching on demand from TCP to UDP/TCP and back - won't hang or cause abnormal termination if a UDP packet is lost A simple user interface. Compatibility with existing (i.e. non-UDP) clients & servers. Implementation overview ======================= The client will have a new menu (hit '+') with UDP features: ro Current protocol (send/recv, TCP or UDP) ro Status (Connected, Switching, etc) ro UDP packets dropped (total count, %) r/w Use sequence #s (can turn sequence # checking on/off) r/w Debug (turn debug msgs on/off) r/w Client send protocol (can choose to send with TCP while recv UDP) r/w Switch to xxx (tapping this changes the protocol) wo Done (close menu) The server will have a new .sysdef option: UDP=0 disallow UDP connections UDP=1 allow UDP connections UDP=2 allow connections, print debugging info UDP=3 allow connections, print VERBOSE debugging info netrek/socket.c and ntserv/socket.c have been modified extensively, mainly to implement the UDP connection protocol (explained later). Packets travelling across the TCP and UDP connections will be treated equally once they have been read; there will be no distinction between packet types. When UDP mode is enabled, all transmissions (defined as a single write() call) will include a sequence packet at the start. If the sequence # is too low, then the rest of the transmission on that channel will be dropped until the next sequence packet is seen. The big exception is that TCP packets are NEVER ignored, since they are assumed to include critical information. Because of the possibility of varying rates on TCP and UDP channels, I have choosen to ignore the sequence number in the TCP packet (in fact, I don't even send one). The two kinds of packets arrive on different schedules, so trying to maintain synchronization is impossible. TCP packets will continue to be placed into a buffer roughly 16K in size. UDP transmissions will be cut off at 960 bytes. If the player decides that the loss of incoming packets is acceptable but the outgoing packet loss is intolerable, TCP send mode can be selected (which simply directs the client to send all outgoing packts down the TCP channel, regardless of packet type). Receiving with TCP while sending with UDP doesn't make much sense and would require a new request message, so I have decided not to implement it for the time being. Critical/non-critical packets ============================= Two criteria were used: (1) will bad things happen if the packet doesn't get through? (2) is it something which ought to be reliable and doesn't happen very often? (ex: SP_MOTD) Server critical: 1 SP_MESSAGE 2 SP_PLAYER_INFO 10 SP_WARNING 11 SP_MOTD 13 SP_QUEUE 16 SP_PICKOK 17 SP_LOGIN 19 SP_MASK 20 SP_PSTATUS 21 SP_BADVERSION 24 SP_PL_LOGIN 25 SP_RESERVED 26 SP_PLANET_LOC Server non-critical: 3 SP_KILLS 4 SP_PLAYER 5 SP_TORP_INFO 6 SP_TORP 7 SP_PHASER 8 SP_PLASMA_INFO 9 SP_PLASMA 12 SP_YOU 14 SP_STATUS 15 SP_PLANET 18 SP_FLAGS 22 SP_HOSTILE 23 SP_STATS 27 SP_SCAN (Amdahl scanning beams) 28 SP_UDP_REPLY (UDP packet; only kind sent in UDP mode is VERIFY packet) 29 SP_SEQUENCE Client critical: 1 CP_MESSAGE 8 CP_LOGIN 9 CP_OUTFIT 10 CP_WAR 27 CP_SOCKET 28 CP_OPTIONS 29 CP_BYE 32 CP_RESETSTATS 33 CP_RESERVED 35 CP_UDP_REQ (uses a special case to send the VERIFY packet through UDP) Client non-critical: 2 CP_SPEED 3 CP_DIRECTION 4 CP_PHASER 5 CP_PLASMA 6 CP_TORP 7 CP_QUIT 11 CP_PRACTR 12 CP_SHIELD 13 CP_REPAIR 14 CP_ORBIT 15 CP_PLANLOCK 16 CP_PLAYLOCK 17 CP_BOMB 18 CP_BEAM 19 CP_CLOAK 20 CP_DET_TORPS 21 CP_DET_MYTORP 22 CP_COPILOT 23 CP_REFIT 24 CP_TRACTOR 25 CP_REPRESS 26 CP_COUP 30 CP_DOCKPERM 31 CP_UPDATES 34 CP_SCAN (Amdahl scanning beams) 36 CP_SEQUENCE UDP performance and side effects ================================ It should be noted that setting the update rate to 5 frames/second does NOT mean that the server only sends data that fast. It specifies a MINIMUM transmission frequency; the server will send regardless when its buffer fills. Under TCP this is about 16K, so even at 1 update/second you are unlikely to receive any information early. Under UDP the buffer size is 960 bytes, so you will receive smaller packets more often. It is quite possible to have the frame rate appear to increase when you move into the thick of a battle. This does NOT mean that the server is sending more data; it's merely spreading the same data over serveral packets. It also does not mean that your display will suddenly speed up; in fact, most people used to 5 updates/second say that the display appears to slow down at 9 updates/second. The smoother display which (accidentally) results will most likely be beneficial to most people. (in case I've managed to hopelessly confuse you, think of it this way: the server will still be sending updates at the same rate, but some will arrive a few milliseconds earlier than the others. Your client will get some data, redraw, get more data, redraw, ... In most cases, I wouldn't expect to receive more than two packets per update, so it shouldn't be a major issue. That remains to be seen, however.) Socket details ============== A typical way to connect is: - server opens a port with bind(), and passes the number to the client via TCP - client opens the UDP port, does a connect(), and sends some data via UDP - server does a recvfrom(), which supplies the client address and port - server does a connect() A two-way UDP connection is now established. Under UTS 2.1 however, recvfrom() is broken, and doesn't always fill in the "from" parameter (the whole reason for the client sending data to ther server before the server connects is so that the server can identify the client's host and port). Since I'm writing and debugging this under UTS, the client packet must contain the client's UDP port number. (note that UTS product support has been made aware of the problem, and is working to fix it.) So, the connection actually works like this: - client opens a port with bind(), and passes the port number to the server - the server does a connect(), and passes it's port number back to the client - the client does a connect() to the server's port This sort of thing is a partial justification for the complicated UDP connection process (explained below). However, this makes it very complicated for people running a client through a gateway machine to get a UDP connection. So, I have left the recvfrom() code in the client (#ifdefed out), and added some comments and #defines for gateway stuff. The client will specify which kind of response is desired when it sends the initial UDP request packet, so the decision to use or not use recvfrom() is strictly within the client. (The reasons for leaving the recvfrom() code #ifdefed out are: (1) you don't gain anything unless a gateway is involved, (2) with the "port passing" method there's absolutely no interruption in game play while the protocol switches, and (3) the client will hang briefly in recvfrom() if the server doesn't support UDP. If you prefer recvfrom(), go ahead and edit the defines.) Source code modifications ========================= Most of the changes were restricted to socket.c, packets.h, defs.h, and data.c/data.h in both client and server. Some minor fixes had to be added to deal with ghostbusting correctly (we can assume that the UDP link will be severed, so both sides will revert to TCP automatically), and the UDP socket had to be added to the select() call in netrek/input.c. On the whole, integrating the UDP code into an existing server should not prove to be a major chore. Explanation of UDP connection process ===================================== This is somewhat involved, because there are some nasty failure states: - ntserv using UDP, client ignoring updates - client using UDP, server ignoring messages - ntserv and client both decide to use UDP, but server can't connect - client stutters and sends a second request, causing server to reroute data ... Most failures end up with server and client ignoring each other, forcing the player to disconnect. Might be worthwhile to add a "force reset" to make the server switch back to the TCP line. If this protocol does its job, then that shouldn't be necessary. (A state diagram would be better, but harder to interpret. This is woefully incomplete, but should impart a reasonable understanding of what's going on.) COMM_XXX indicates where the client or server expects to send/receive data STAT_XXX indicates the "state" of the client Initial state: Client: COMM_TCP, STAT_CONNECTED Server: COMM_TCP C finds a free port and bind()s it C sends a CP_UDP_REQ(COMM_UDP, client_port) Client: COMM_TCP, STAT_SWITCH_UDP Server: COMM_TCP (if the server doesn't send a response within 25 updates, figure the server doesn't know about UDP and reset to STAT_CONNECTED.) S checks it's current mode: if already UDP, drop current connection and proceed below if S isn't allowing UDP connections, it sends SP_UDP_REPLY(SWITCH_UDP_DENIED,0) S opens a UDP socket, connect()s to the client and sends a REPLY(SWITCH_UDP_OK, server_port) over TCP - or - REPLY(SWITCH_UDP_OK, 0) over UDP <-- if recvfrom() is used Client: COMM_TCP, STAT_SWITCH_UDP Server: COMM_TCP C tries to connect() to UDP port (from message or result of recvfrom()) if it fails, it resets state and sends REQ(COMM_TCP,0) C sends REQ(COMM_VERIFY, 0) through UDP connection if it times out, C will reset state and send REQ(COMM_TCP,0) Client: COMM_UDP, STAT_VERIFY_UDP Server: COMM_TCP S gets the verification message and begins sending data down the UDP link First packet is a REPLY(SWITCH_VERIFY,0) (to guarantee that something does in fact get sent across the UDP connection). If the reply gets lost, and nothing else gets sent via UDP for a while, the client will time out and reset. If recvfrom() is used, then this VERIFY is simply ignored. Client: COMM_UDP, STAT_VERIFY_UDP Server: COMM_UDP C gets an update on the UDP line Client: COMM_UDP, STAT_CONNECTED Server: COMM_UDP [C can now begin sending data on the UDP line] --- now switch back to TCP --- C sends a REQ(COMM_TCP,0) [and stops sending data on the UDP line] Client: COMM_UDP, STAT_SWITCH_TCP Server: COMM_UDP S checks it's current mode: if it's already TCP, send REPLY(SWITCH_TCP_OK,0) and do nothing further S closes its UDP socket, resets its mode to COMM_TCP, and sends a REPLY(SWITCH_TCP_OK, 0) Client: COMM_UDP, STAT_SWITCH_TCP Server: COMM_TCP C closes its UDP socket, and changes mode Client: COMM_TCP, STAT_CONNECTED Server: COMM_TCP Misc stuff ========== I'd like to thank Kevin Smith for providing some sample UDP code, and providing feedback on the design. Tedd Hadley brought up the first non-Amdahl server with UDP, and helped me find a couple of bugs. That's all, folks... ------------------------------ From: fadden@uts.amdahl.com (Andy McFadden) Newsgroups: alt.games.xtrek Subject: UDP client doc Date: 19 Mar 92 01:12:15 GMT This is the client documentation for the New & Improved client. Tedd has the source code, so (if all goes well) a new client/server should be available in a day or two. I haven't been able to contact Terence, so bronco fans will have to wait. A couple of comments are in order... (1) I don't know if the "double UDP" transmissions will help or merely waste network bandwidth and cause the "#of transmissions dropped" indicator to go twice as fast. Since it's a server mod, I can't test it without a new & improved & lagged server to try it on. If it sucks wind, it'll be removed with the next update. (2) Something I had contemplated before but didn't remember to add is an "update all" button. Pressing it would cause the server to send 3 UDP packets, one with planet info, one with player info, and one with torp status for everybody. That way if you're getting ghosts or you've got tons of floating torps, you could hit the button (or maybe just the TAB key) and it'll try to clear stuff up. I'm sending it over UDP because TCP transmissions can get delayed for inordinate amounts of time... if it doesn't get through, just hit TAB again (or whatever). This'll be added to the next update (which will hopefully be a minor one). (3) While you're heaping praise and throwing thanks, don't forget to include Tedd Hadley and Terence Chang. It isn't easy to integrate this stuff into their code, because all three of us are using different sources. So much has changed in socket.c that a diff from my source would be more confusing than helpful (not to mention several hundred lines long), so they have to make changes by hand to preserve their own modifications. (4) Don't use the "double UDP" and "forced send" options unless you have to. They can adversely affect the network (esp. double UDP), and degrade performance for everybody. Once I get the "update all" thing in place, then you will be able to compensate for the occasional dropped packet manually instead of this psycho autosend stuff. I was playing on bronco last night around 9:30pm; was at 9 updates/second and had only 17 dropped packets during the entire 30 minutes I was playing. For once in my life I found it annoying to NOT have lag; I was trying to test the forced send on a server with bad lag... ------------------------------ From: fadden@uts.amdahl.com (Andy McFadden) Newsgroups: alt.games.xtrek Subject: Double UDP Date: 24 Mar 92 01:01:06 GMT By now the New & Improved UDP client/server should be available. It provides a new service called "double UDP", where the server sends two packets/update (a big one with everything in it, and a small one with just semi-critical info in it). The theory is that only one of the two will be dropped. With luck, semi-critical packets should be relatively infrequent, or at least small. Initial results have not been promising, and I'm contemplating the removal of the double UDP code (well, it'll be #ifdefed out; in fact, I've already put the #ifdefs in). I'd like to know if it makes a difference for anyone (besides hosing the network). Also, I'd be interested in knowing if the enforced UDP send stuff is making a difference. It seems simple enough to work. BTW, the following commands are "enforced": speed direction shield orbit repair beamup beamdown cloak bomb docking permission player lock planet lock phaser <-- only if weapons are enforced plasma <-- ditto tractor pressor (for server hackers, I did all the "short" ones plus tractor/pressor) Enforcing some of the other commands would require a more complicated mechanism. As it is, speed and direction aren't really "enforced", since the chances of changing to the requested speed or direction in 1/5th of a second are zero unless you're already going that speed or direction. What it does is try to enforce it, but give up after one try... basically there's always a duplicate on speed and direction commands. They're small and don't happen very often though. Enforcing torps would've been really nasty if the "you have fired a torp" response got dropped or delayed. You could theoretically end up dumping your whole load of torps, though in reality you'd probably only end up firing one or two extra. Enforcing "det torps" and "det own" is difficult because the client really doesn't know if the server did it or not. Sending "det own" twice would be okay, but doubling "det torps" would be bad. (hmm... maybe I'll auto-double det own.) Most will give up after 10 tries. tractor/pressor and beam up/down will give up after 5 tries. The weapons will only retry once (no point in repeated re-phasering two seconds later...) Note that if you hit 'b' while flying, you'll get "must be orbiting..." messages for 10 updates. Similar things will happen with many of the other commands. If something is especially annoying, let me know. ------------------------------ From: fadden@uts.amdahl.com (Andy McFadden) Newsgroups: alt.games.xtrek,rec.games.netrek Subject: Re: UDP client frustration Date: 2 Apr 92 01:15:36 GMT The UDP clients and servers are undergoing an upgrade. I added a "messages" section to the UDP client documentation, which is shown below for your viewing pleasure... Be patient. I think you'll like the new stuff (the long-awaited "update all" button is here, but you won't need to push it if you're using "fat UDP".) If all goes well, next release should be 1.0 and be generally available. Then everyone will get to see the tangled mess that Tedd and Terence have had to put up with... :-) ===== Netrek UDP Enhancements - Client Documentation By Andy McFadden (fadden@uts.amdahl.com) Dual channel model, version 0.3 Updated: 01-Apr-92 The client has a new menu, available by hitting '+'. It's similar to the 'O' options window, only it's not glued to the netrek window by default (so you can push it off to the side while you play). The buttons are: ====================================== 0 | UDP channel is [OPEN/CLOSED] | ====================================== 1 | > Status: [Connected/...] | ====================================== 2 | > UDP trans dropped: X (Y% | Z%) | ====================================== 3 | Sequence checking is [ON/OFF] | ====================================== 4 | Sending with [simple UDP/...] | ====================================== 5 | Receiving with [simple UDP/...] | ====================================== 6 | Debugging info is [OFF/ON...] | ====================================== 7 | Force reset to TCP | ====================================== 8 | Update everything | ====================================== 9 | Done | ====================================== Explanations: 0 Pressing this button opens or closes the UDP channel. UDP transmissions are only possible when the channel is open. Note that it is actually possible to send & receive using only TCP while the UDP channel is open, but that would be pointless. 1 This displays the current state of the connection. Possible values: - Connected (this is the normal state) - Requesting switch to UDP - Requesting switch to TCP - Verifying UDP connection 2 This displays the total number of UDP transmissions dropped during the current game (X), that number expressed as a percentage (Y), and the number of transmissions which have been dropped recently (Z). Z% is computed once every minute; after it's displayed, the counters are reset to zero. Thus Z is an indication of recent line conditions, while Y tells you how conditions were over the entire game. 3 Clicking on this toggles sequence checking. When sequence checking is ON, packets from the server which arrive out of order are thrown away. This prevents a number of possibly nasty bugs from occurring (the least of which is watching your ship jump around when an old update arrives). When sequence checking is OFF, the "transmissions dropped" values are not updated. 4 This determines how packets are sent. There are four settings: - Send with TCP only. If your TCP link is decent but you are dropping UDP commands, this is useful. - Send with simple UDP. Most commands will be sent via UDP. This is the default. - Send with enforced UDP (state only). Several of the commands which are sent via UDP will be repeated if the next update doesn't reflect that change. For example, if you try to raise shields but they aren't up on the next update, the "raise shields" command will be resent. Note that some commands will be repeated up to 10 times. On a lagged system, this can result in every command being sent twice. - Send with enforced UDP (state+weap). This is like the previous, except that phasers and plasmas are also repeated (but only once). This will usually result in warnings about phasers not recharging or limits on computer power, which should be ignored. 5 This determines how packets are sent by the server. There are four settings: - Receive with TCP only. This tells the server to transmit everything using TCP only. This is rather silly, but what the hell. - Recieve with simple UDP. The server sends critical packets with TCP, and non-critical packets with UDP. This is the default. - Receive with fat UDP. The server adds some previously sent data onto newer packets, but only if there's room. Eventually all previously sent data will be sent again, so if you missed a planet update the first time around you'll get it eventually. - Receive with double UDP. The server sends critical packets with TCP, non-critical packets with UDP, and semi-critical packets in two consecutive UDP transmissions. The idea is that one or the other of the transmissions with semi-critical information may be lost, but probably not both. This idea may not always work; more testing is needed. It also increases the strain on the network, so it shouldn't be used if you have a reliable local connection. WARNING: this relies on the sequencing mechanism to drop the extra packets. If you turn off sequence checking, you may get weird results. NOTE: initial results have not been promising. This may be disabled in future clients/servers. 6 There are three levels of debugging info: - OFF (the default). - Connection messages only. Prints diagnostics when you connect, disconnect, or something goes wrong. If you are having problems, you should use this setting; it's silent until something goes wrong. - Verbose info. This prints a line every time something is sent or received on the UDP line (unless somebody has commented V_UDPDIAG out of defs.h on your copy of the client). This is more information than most people want or need, and it'll slow your updates down, so leave it off unless you're curious. 7 If your UDP connection gets jammed up for some reason, hit this button. It'll close the UDP socket, reset all connection-related information, and reset all the menu options to defaults. It does all this rather abruptly and could jam future UDP connection attempts, so don't use it unless you really need to (i.e., don't hit it just because your client hasn't received updates in the last five seconds). 8 If you've got ghost torps or planets you can't see info on, click here (or hit '=', the "update all" key). This will cause the server to mark its copies of much of its internal state as "never been sent." The next update will be a fairly big one... Unless the updates themselves get dropped, your display should synchronize with the server. To prevent people from loading down the server maliciously, there will be a period of a few seconds during which update requests will be ignored. 9 Done. Click this to close the window. If you try to switch to UDP on a server which doesn't support it, the client will eventually time out. Unless you're using the recvfrom() option in the client, the game will not hang during this period. It is generally to your advantage to NOT use enforced UDP, fat UDP, or double UDP, because they cause more information to be sent than is really necessary. This will degrade overall performance, and make your connection worse by increasing the amount of time that your client and server processes spend handling incoming packets. If you're only getting 2 or 3% packet loss, it's probably better to deal with a few ghost torps, and just hit the "update all" button if something doesn't look right (like somebody who just died still has kills, or you can't get info on a planet you're orbiting). If you get 5 or 10% packet loss, or your commands are being dropped regularly, then switching to enforced and/or fat UDP is a good idea. Messages you might encounter: "UDP connection established" Congratulations, you're in. "Switched to TCP-only connection" Congratulations, you're out. "Timed out waiting for UDP response from server" "UDP connection request timed out" Odds are this server doesn't support UDP. You'll see one or the other of these messages, depending on how your client is configured. "UDP link severed" Whoops. Something broke your UDP connection, so the client and server have reset themselves to a TCP-only connection. "Sent request for full update" This acknowledges that the update request has been sent. It could get lost. If so, send it again; the server will ignore duplicate requests for about five seconds after receiving the first, so hitting the key three or four times is considered acceptable behavior. "Request is in progress, do not disturb" Stop trying to switch. It'll happen. "Unable to establish UDP connection" "Connection attempt failed" Something in the collection of connect()s and bind()s didn't happen. These usually indicates a failure on the client machine. "UDP protocol request denied" The server admin has set "UDP=0" in his .sysdef file. UDP connections are possible, but are being rejected at the moment. "UDP protocol request failed (bad version)" Your version of the UDP protocol doesn't match what the server is using. The following are warnings generated by the server: "WARNING: BROKEN mode is enabled" You're playing on a server with a self-inflicted 20% packet loss rate. This exists to test certain protocols, like fat UDP. "Server can't do that UDP mode" This will appear if you try to change to a UDP mode that the server isn't aware of. Shouldn't happen unless you mess around with your client. "Server will send with TCP only" "Server will send with simple UDP" "Server will send with fat UDP; sent full update" "Server will send with double UDP" "Request for double UDP DENIED (set to simple)" This should be pretty obvious. If double UDP has been excised from the server, you'll get the last message instead of the second-to-last message. "Update request DENIED (chill out!)" Stop banging on the "update all" key. "Server UDP is v%.1f, client is v%.1f" If your version is off, the server will try to be helpful and tell you what the problem is. If you enable the first notch of debugging, you'll get more verbose information explaining what failed and why. It's meant to be informative, not readable; if you don't understand it, don't worry about it. Things like connection failures should be easy to diagnose from the information given (though you may need to talk to the server admin to see what's going on at the other side as well). Notes for people running through Internet gateways: Recompile the client with "-DGATEWAY" in CFLAGS in the Makefile. Then change the code at the end of "main.c" to reflect your site. The gateway program ("gw", written by Kevin Smith) with my UDP extensions should be available on John Hardwick's FTP site (gs69.sp.cs.cmu.edu, /usr/jch/netrek/); it explains most of what you need to know. You will have an extra box on the '+' menu, which shows you what it thinks the gateway machine's name is and what ports it will try to use. It's a pain, but hey, it works. Final bits: If you're using a UDP-capable client, there's a 99.99% chance that I did *NOT* write the client. My changes are supplied as diffs and pieces of source code, not as an entire client... If you can't get a window to open or don't like some aspect of the display or controls, don't send me mail, I have no control over it. Similarly, please don't ask me for a UDP-capable client. I'll be glad to forward source code once it's completed, but by then it'll be on various FTP sites anyway. ------------------------------ Newsgroups: rec.games.netrek From: terence@bronco.ece.cmu.edu (Terence Chang) Subject: Re: UDP and regions Date: Mon, 6 Apr 1992 20:43:42 GMT [ Blah, what's with all this ambiguous newsreader attribution (using pure white space only to attribute quotes != good). ] fadden@xserver.uts.amdahl.com (Andy McFadden) writes: >The added strain on bronco is probably due to the increasing number of people >who can play at 9 updates per second. As UDP spreads it will probably be >necessary to change the server to restrict the #of updates per second to 7 >or 5. A few empirical observations (empirical is an engineer's favorite word, isn't it?) about UDP's impact on bronco: pre-UDP UDP full server's CPU usage 40% ~60% ntserv SZ (RSS slightly less) 140K 280K avg queue size, evenings ~6 ~12 avg # of UDP connections 0 8 swapping with no other machine activity? no no thrashing on disk swap? some a lot Experiment: I've added a 5 update/sec limit to bronco; it'll be this way for about a week. I'll unscientifically sample the CPU usage and queue size and see if anything changes. I'm pretty sure, however, that the UDP mode itself is primarily responsible for the increased load (colloquially, I'd say it's like a having "UDP ntserv" process piggybacked on the TCP ntserv one). Terence ------------------------------ Newsgroups: rec.games.netrek From: terence@bronco.ece.cmu.edu (Terence Chang) Subject: Re: UDP and regions Date: Tue, 7 Apr 1992 04:23:39 GMT fadden@xserver.uts.amdahl.com (Andy McFadden) writes: >Unless they're >using fat UDP, double UDP, or forced UDP, the difference should be negligible >(especially in the server). The server really isn't doing any extra work; >it's just supplying bcopy() with a different destination. Obviously the >extended modes make things worse, but it's not THAT big a difference. Yeah, looks like you're right; take a look at this modified ps dump (UDP users were crossreferenced from netstat, hostnames x'ed to protect the innocent): pid CPU usage (secs) 27482 140 ntserv xxx.ECE.CMU.EDU 27515 137 ntserv xxxxx-xxxx.ECE.CMU.EDU 27578 130 ntserv xxxxxxxxxx.BH.ANDREW.CMU.EDU 27581 UDP 151 ntserv xxx-xx.Berkeley.EDU 27596 136 ntserv xxxxx-xxxx.ECE.CMU.EDU 27630 UDP 124 ntserv xxxxxxx.cs.umd.edu 27631 114 ntserv xxxxxx.cs.umd.edu 27641 96 ntserv xxxxxxxxx.its.rpi.edu 27643 UDP 121 ntserv xxxxxxx.SEAS.UPENN.EDU 27644 109 ntserv xxxxxxx.RES.ANDREW.CMU.EDU 27656 UDP 117 ntserv xxxxx.reed.edu 27657 98 ntserv xxxxxxxx.WS.CC.CMU.EDU 27692 94 ntserv xxxxxx.FRC.RI.CMU.EDU 27696 71 ntserv xxxxxx.BH.ANDREW.CMU.EDU 27707 UDP 38 ntserv xxxxxx.SEAS.UPENN.EDU 27721 23 ntserv xxxxxxxxx.gatech.edu 27757 0 ntserv xxxxxxxxx.BH.ANDREW.CMU.EDU There are 17 entries given, by increasing pid, therefore by sequential arrival (connection) time to the server. The 17th (and subsequent entries) are listed with 0 seconds CPU time used because they're sleeping on the queue. At the time the dump was made, the update limit was set to 5. If we assume evenly spaced arrival times (unlikely), assume that UDP connections are initated immediately, ignore the different flavors of UDP, assume that CPU usage is linearly proportional to total connection time, and assume that this is a representative sample (unlikely), you can plot CPU usage vs time for TCP and UDP with xgraph and then do a best straight-line fit, and compare the slopes. Heh heh. Right. Well, anyway, I tried all that and found that the UDP CPU usage was 20% +/- 5% steeper than TCP -- which isn't much. More accurate measurements could be made. I guess I'll keep trying these silly experiments. Terence ------------------------------ From: fadden@uts.amdahl.com (Andy McFadden) Newsgroups: rec.games.netrek,alt.games.xtrek Subject: UDP v1.0 SOURCES ARE AVAILABLE Date: 8 Apr 92 22:02:13 GMT I just stuffed the following into the "incoming" directory on pittslug.sug.org: udpcli.tar.Z UDP client stuff udpsrv.tar.Z UDP server stuff Knock yourselves out. :-) ------------------------------ From: fadden@uts.amdahl.com (Andy McFadden) Newsgroups: rec.games.netrek Subject: UDP v1.0 README addendum Date: 9 Apr 92 03:55:22 GMT A few things I forgot to put into the readme (before I get a landslide of mail): First, I'd like to emphasize that you should NOT replace your files with mine except for socket.c, packets.h, and udpopt.c. The rest of them are along so you can see what the changes look like in context (well, more context than the diff -c shows). Second, there are #defines in both socket.c files for Amdahl scanning beams and visible tractor beams. Examining the first part of the socket.c files should make what you need to do apparent. I should've commented out the scanning beam stuff, but forgot (the client would also need a "scan.c" file; without it, your client won't link). Third, Tedd Hadley has generously (and foolishly) agreed to help answer questions. If you're having problems integrating my code into yours, I suggest you send mail to him - after all, he's had more practice. (Don't forget that he and Terence had to re-integrate my sources on at LEAST three occasions, possibly more like five.) Questions about how something works should be sent to me (though I'm prefectly willing to let Tedd handle ALL the mail, I suppose I shouldn't let him suffer too much from that slip in judgement ;-) ). Once again, that number is hadley@osiris.ics.uci.edu (which, at last report, was a good place to test your UDP clients). Fourth, don't ask me about blessed clients, unless you've got an Amdahl (or compatible) mainframe. Hmm, maybe with all the scrambling going on for new clients, it'd be a good time to change the authentication routine...? ------------------------------ From: hadley@cad.ics.uci.edu (Tedd Hadley) Newsgroups: rec.games.netrek Subject: UDP v1.0 blessed clients for sun{3,4},mips Date: 9 Apr 92 23:24:20 GMT UDP client binaries for sun3, sun4, and mips are at v1.0 * no major UDP changes. * made several fixes for better behavior under "fat" UDP, hopefully eliminating extraneous torp explosions and incorrect torp numbers. * applied Richard Caley's X11 patches (from jch's FTP site) * the binaries are now compressed at the FTP sites. cad.ics.uci.edu (128.195.10.26) /pub/netrek/udp_client.{sun3,sun3_static,sun4,sun4_static,mips}.Z pittslug.sug.org (192.58.107.150) /pub/netrek/udp_client.{sun3,sun3_static,sun4,sun4_static,mips}.Z NOTE: Date should be 4/9 or later. If not, you can get the clients from the /incoming directory. If you see any bugs or strange behavior please report it to me. Looks like there's UDP upgrades in progress/done at several servers. netrek.cis.ksu.edu? bigdog.berkeley.edu? bronco is down at the moment so I'm not sure if it's at 1.0 yet. osiris.ics.uci.edu is at 1.0 with the broken UDP option. codes I'll take care of this evening. ------------------------------ From: fadden@uts.amdahl.com (Andy McFadden) Newsgroups: rec.games.netrek Subject: Re: netrek.atd.ucar.edu: ntserv death? Date: 23 Apr 93 20:04:19 GMT In article froud@Sol40.essex.ac.uk (Froud D D M) writes: >TWICE now I've been in a SB with armies only to find myself suddenly unable >to move, raise shields, anything and surprise, surprise, an enemy ship wanders >down and kills me. Can you send messages? If so, then your UDP connection has jammed up. This seems to happen most often to or from specific sites, so bugs in UDP implementations may be the culprit (I can't think of too many applications that use connected UDP sockets... most use sendto() and recvfrom(), so connected UDP probably isn't as robust). The solution is to close and reopen your UDP channel from the '+' menu. Sometimes it clears up all by itself, but most times closing & reopening is necessary to fix it. ------------------------------ End of UDP **********