OK, since the comments section is starting to get unwieldy, I'll type a longer and slightly more elaborate answer, that incorporates some parts from the answer by @VinnieFalco.
According to Wikipedia, a DoS attack is defined as: "an attempt to make a machine or network resource unavailable to its intended users" and it commonly involves "saturating the target machine with external communications requests, so much so that it cannot respond to legitimate traffic, or responds so slowly as to be rendered essentially unavailable"
We all agree that a system that is connected to the Internet and is offering a service at some port cannot just magically prevent bad people from connecting to it, nor can it choose to accept only "good" traffic while avoiding receiving "bad" traffic.
There many "types" of DoS attacks, but they all boil down to one thing: they seek to consume resources:
As you know, resources come in many forms; sometimes attacks will consume bandwidth, other times they will consume RAM, disk space, IOPS, file descriptors, license slots/seats, or just about any finite resource that your service requires.
Fundamentally, you have two options: either increase available resources above the level of the attack, or ride it out.
Sometimes you can do a little better: you can attenuate an attack that seeks to consume bandwidth by using a content-delivery network. You can go from rotating hard drives to flash-based storage, and even to RAM based storage if the attack causes I/O performance to drop. You can limit the use of commands that require resource under attack.
Sometimes you can do better still: you can detect that the attack traffic comes only from a subset of hosts and filtering those data streams off at an upstream provider. If I/O is a bottleneck, you can attempt to rearchitect code to reduce the amount of I/O necessary. If commands are computationally expensive, you can attempt to optimize them or even reimplement them in a more efficient manner.
But, ultimately, all you can really do is blunt the force of a DoS attack. Generally speaking, you cannot prevent a DoS, and if it hits, you usually end up having to buckle down and waiting for it to pass.
So what about the Ripple servers?
As far as increasing the available resources, obviously that's outside the purview of the code: it can't magically provision more resources. That's the job of server operators who will typically ensure that their servers have sufficient excess capacity to provide servers even when demand for service spikes. So this isn't anything the code can do about something about.
What the servers can do something about, however, is to attempt to detect when they are under heavy load or attack and respond to that. In a sense, both those scenarios play out the same:
The servers will penalize connections which are forcing the server to do more work per unit of time than the server considers reasonable. Typically the penalty is to inform the user that the server is too busy and to ignore the command and to disconnect him if he persists in issuing commands at an unacceptably high rate.
Of course, the server has no real way to distinguish with perfect accuracy whether a user is abusive or not because it doesn't have a crystal ball. All it knows is the commands that it receives from a source and the rate at which the those commands are being sent and it bases its decision on that. So while this countermeasure will affect users who are, indeed, abusive, it can also affect legitimate users.
The server can also track load across all its connections and can decide to make some commands (which it knows are very expensive but not strictly necessary) temporarily unavailable, as load begins to climb. In that way, the server can conserve resources to use in processing the commands which are necessary.
Of course, this approach is more blunt and will affect legitimate users, as the server may refuse to execute an expensive command even from a legitimate user who has not issued any other expensive commands nor caused undue load.
On top of that, there's what Vinnie Falco mentioned: the servers seek to protect themselves and the network from abuse by:
- Imposing (miniscule and neglible) transaction fees that are payable in XRP and which scale dynamically in response to various factors, including network load; and
- Imposing network-wide 'account' and 'action' reserves.
This means that someone seeking to attack the network in certain ways must, in essence, pay for the "privilege" of doing so and they harder they attack, they more they must pay.
Why is this helpful? Generally those who are orchestrating a (D)DoS attack don't really have to pay and their costs are minimal, making the attack not only cheap to launch but cheap to maintain as well. This is a huge advantage
By imposing fees, which, for regular users are negligible, Ripple servers and the network take that advantage away: they "prevent" (D)DoS attempts because the cost of launching and sustaining an attack against Ripple quickly adds up.
There are a few other mechanisms which Ripple servers implement to protect against and mitigate the effects of (D)DoS attack. Combined, all these things work pretty well, but the bottom line is that we have come full circle to what I said earlier:
A system that is connected to the Internet and is offering a service cannot just magically prevent bad people from connecting to it, nor can it choose to accept only "good" traffic while avoiding receiving "bad" traffic.
One other thing I didn't touch upon: Optimizing the Ripple server code to improve performance. This is something that we at Ripple Labs spend a lot of time on and we still have things we want to do and ideas we want to implement. We also hope that the vibrant community of talented open-source developers will take a look and contribute their many great ideas as well.