and I just got finished rewriting all my large webapps in some obscure Java framework for performance, because of some benchmarks I saw on HN. Guess now I have to rewrite it all in assembly, because more performance is always better right?
This is not a very fast webserver. Anything using sendfile() and threads/processes will beat it handily.
TCP HTTP Server written in Assembly
51–60 of 74 posts
Re: TCP HTTP Server written in Assembly
#52OMG all these macros. It looks more like Python then Assembly. Come on, real men do not use macros.
Re: TCP HTTP Server written in Assembly
#53Earlier quoted context omitted.
This is not a very fast webserver. Anything using sendfile() and threads/processes will beat it handily.
I haven't measured, but I'm pretty sure you're right.
This server is single threaded and artificially serializes requests, at a minimum. The copy through userspace is going to hurt compared to sendfile for larger files.
Re: TCP HTTP Server written in Assembly
#54OMG all these macros. It looks more like Python then Assembly. Come on, real men do not use macros.
Re: TCP HTTP Server written in Assembly
#55Cool stuff. Really, though, this is still relying on a rather large runtime library: the physical, data-link, and network-layer drivers. Now what'd be really awesome to see, would be one of those Operating System guides that shows you how to write an OS kernel, in assembler, that can speak HTTP. Even just limiting yourself to targeting the synthetic hardware of a VM program, it'd still be quite a feat. Bonus points i…
Re: TCP HTTP Server written in Assembly
#56Cool! My comments as an inexperienced assembly developer, assuming this is optimising for binary size: - The pug/doN macros do an extra reg-reg copy if passed a register - and the recursive definition calls pop/pop/pop instead of just add %esp, -4*N, you could shave a few bytes - AT&T syntax will always look weird to me, but the heavy use of macros and local labels is quite elegant - A little bit of candid swearing i…
Agree, AT&T syntax was just not designed for human reading. I doubt this is too optimized for size, since there are obvious tricks that it misses. Another observation: the strlen code is incorrect, as it also counts the \0. We can fix this, and make the code 1 byte shorter (in glorious Intel syntax): lea esi, source ; depends on source xor ecx, ecx ; 2 bytes salc ; 1 byte cld ; 1 byte _back: scasb ; 1 byte loopnz _ba…
I think at this point I might be able to get away with CLD since I never STD any more :)
Some of the obvious tricks it misses are probably because they're not obvious to me, while others may be just because I haven't gotten to them yet.
Re: TCP HTTP Server written in Assembly
#57Earlier quoted context omitted.
This is a simple, single-threaded single-process accept-read-respond-loop web server. It's vulnerable to trivial trickle DoS attacks and probably has other issues. There are no advantages, the author just did this for fun. The TCP part comes from C code in the kernel, so this headline is a little misleading ;-).
Agreed. However, it should be safe from buffer overflows, path traversal attacks, XSS, and obviously CSRF. It should be fine other than DoS. Let me know if you find any exceptions.
So, not only will a trickle DoS other clients, each byte will also force an O(n) traversal of $buf (burning CPU). Granted, buf is only 1000 bytes, but that's not great.
It looks like a request with no space could force you to walk (`repne scasb`) through invalid memory after $buf. Also maybe corrupt it (unescape_request_path).
It will also fail to correctly parse HTTP/0.9 (not a big deal, but part of spec). The parsing code ignores the existence of verbs other than GET. (Doesn't check that the verb is GET either.)
We don't validate that paths start with /, we just skip that byte. Okay:
mov (path), %al
...
cmp $'/, %al
je badreq
Since valid GETs are of the form: GET /foo.txt HTTP/1.0
^-- path=buf+5
As you point out, a client close will cause SIGPIPE causing a crash (DoS).That's all I see. But I'm not an asm expert and I'm sure I've missed something.
Re: TCP HTTP Server written in Assembly
#58Re: TCP HTTP Server written in Assembly
#59Earlier quoted context omitted.
Agreed. However, it should be safe from buffer overflows, path traversal attacks, XSS, and obviously CSRF. It should be fine other than DoS. Let me know if you find any exceptions.
It's hard to be vulnerable to XSS and CSRF with all-static content, no? So, not only will a trickle DoS other clients, each byte will also force an O(n) traversal of $buf (burning CPU). Granted, buf is only 1000 bytes, but that's not great. It looks like a request with no space could force you to walk (`repne scasb`) through invalid memory after $buf. Also maybe corrupt it (unescape_request_path). It will also fail t…
You would think, but actually Apache managed to be vulnerable to XSS by including bits of the request URL in its error paegs, if I remember right. Last millennium, I think.
> So, not only will a trickle DoS other clients, each byte will also force an O(n) traversal of $buf (burning CPU). Granted, buf is only 1000 bytes, but that's not great.
Hmm, while I hadn't thought about that, and I should have, I think that's probably okay; basically you're saying that you can get the machine to burn up to, say, 2048 cycles by sending it a small TCP packet. Which means that a 4-core 2GHz server machine can't handle more than about four million packets per second (well, one million until I parallelize), which is about 85 megabytes per second, or 680 megabits per second. There are probably other bottlenecks in the code, the kernel, or your data center that will kick in first. It's probably more effective to DoS the server by just requesting files from it.
> It looks like a request with no space could force you to walk (`repne scasb`) through invalid memory after $buf.
It's possible I could have gotten this wrong, but I did try to limit the number of bytes it would scan to the bytes that it had actually read, by doing
mov (bufp), %ecx
before the repne scasb. Did I screw that up?> HTTP/0.9 ...verbs other than GET.
Yes, those are unimplemented features, and you're right that their lack makes the server behave incorrectly; hopefully they don't result in security bugs. I think they don't matter in practice, since nobody sends HTTP/0.9 requests or HEAD requests, except by hand, do they?
> We don't validate that paths start with /, we just skip that byte.
Right. And the $'/ check below is to keep you from saying
GET //etc/passwd HTTP/1.0
and getting /etc/passwd. In case that matters in 2013.Thank you very much for looking over it!
Re: TCP HTTP Server written in Assembly
#60OMG all these macros. It looks more like Python then Assembly. Come on, real men do not use macros.
> Come on, real men do not use macros. The sexism and historical ignorance in this sentence are in a race to see which can be more breathtaking. Regardless of which wins, meshko will look like a complete fool to anyone who knows what they're talking about.
> Come on, real men do not use macros.
The sexism and historical ignorance in this sentence are in a race to see which can be more breathtaking.
Regardless of which wins, meshko will look like a complete fool to anyone who knows what they're talking about.