Live data from Hacker News

TCP HTTP Server written in Assembly

canonical.org

61–70 of 74 posts

Re: TCP HTTP Server written in Assembly

#61
post #51

Earlier quoted context omitted.

I haven't measured, but I'm pretty sure you're right.

Me too. You could probably find a single-threaded, small file benchmark where they compare similarly (or this even compares better — it does almost nothing). But this is not most benchmarks. Large files or multiple clients will bench this server poorly compared to MT + sendfile(2). This server is single threaded and artificially serializes requests, at a minimum. The copy through userspace is going to hurt compared t…

I made it fork. Now, on my netbook, it's able to handle in the neighborhood of a thousand requests per second and 20 megabytes per second, with up to 2048 concurrent connections. Not, I think, spectacular performance, but acceptable for many purposes. You can still DoS it by opening 2048 concurrent connections to it; as long as they are open, it will open no new connections, and it has no timeout.

This has bloated the executable up to 2088 bytes.

Re: TCP HTTP Server written in Assembly

#62
I hacked on httpdito some more, and it has been improved in several ways:

- it now forks so that it can handle multiple concurrent connections (up to a limit of 2048);

- it no longer uses libc at all, so it's down to 2088 bytes (I had it lower, but then I added forking);

- it's less complex now that it only has one way of invoking system calls instead of two;

- there are some performance results in the comments.

- it has a name, "httpdito";

- strlen works correctly.

Probably nobody will read this comment here, but I thought it was worth mentioning.

Re: TCP HTTP Server written in Assembly

#63
post #59

Earlier quoted context omitted.

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…

> It's hard to be vulnerable to XSS and CSRF with all-static content, no? 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. Hm…

Didn't send ab HEAD requests?

I know it does this by a given flag, but in some tests I have seen some HEADs between my GETs. I haven't used ab for long time, so don't quote me on that. Have u tried httpress[1] as a benchmark tool?

How about a simple check against the first byte equals G (DEC 71) if it is a GET? Shouldn't be that expensive, I think.

Thanks for creating it.

[1] https://bitbucket.org/yarosla/httpress/wiki/Home

Re: TCP HTTP Server written in Assembly

#64
post #56
post #32

Earlier quoted context omitted.

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…

BTW, I've fixed the strlen code (although differently). I didn't know about SALC! That's a very clever way of zeroing AL. 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.

Your way is much cleaner; mine was just a size gimmick. I just can't resist it :)

Re: TCP HTTP Server written in Assembly

#65
post #42
post #22

OMG 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.

Wait, are you serious?

Re: TCP HTTP Server written in Assembly

#66
post #42
post #22

OMG 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.

Would the joking intent of the usage of men-centric idiom be more clear if I append "now get off my lawn" to the comment?

Re: TCP HTTP Server written in Assembly

#67
post #59

Earlier quoted context omitted.

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…

> It's hard to be vulnerable to XSS and CSRF with all-static content, no? 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. Hm…

> four million packets per second (well, one million until I parallelize), which is about 85 megabytes per second

Why is this more than 4 million bytes per second (4 MB/s)? A packet can contain a single byte.

Re: TCP HTTP Server written in Assembly

#68
post #59

Earlier quoted context omitted.

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…

> It's hard to be vulnerable to XSS and CSRF with all-static content, no? 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. Hm…

> before the repne scasb. Did I screw that up?

Ah, it's possible repne scasb halts when ecx drops to zero (that would explain some of the string length asm code I found when I googled it). I'm not very familiar with x86 mneumonics apart from the basics ('mov').

Re: TCP HTTP Server written in Assembly

#69
post #59

Earlier quoted context omitted.

> It's hard to be vulnerable to XSS and CSRF with all-static content, no? 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. Hm…

> four million packets per second (well, one million until I parallelize), which is about 85 megabytes per second Why is this more than 4 million bytes per second (4 MB/s)? A packet can contain a single byte.

To be a valid TCP packet, it needs to contain at a minimum a 20-byte IP header and a 20-byte TCP header, plus the one byte of payload. In practice your server is probably receiving the packet over Ethernet, so it probably has an Ethernet header and things like that, too, but that's a minimum. You could approach it over, say, SLIP.

Re: TCP HTTP Server written in Assembly

#70
post #63
post #59

Earlier quoted context omitted.

> It's hard to be vulnerable to XSS and CSRF with all-static content, no? 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. Hm…

Didn't send ab HEAD requests? I know it does this by a given flag, but in some tests I have seen some HEADs between my GETs. I haven't used ab for long time, so don't quote me on that. Have u tried httpress[1] as a benchmark tool? How about a simple check against the first byte equals G (DEC 71) if it is a GET? Shouldn't be that expensive, I think. Thanks for creating it. [1] https://bitbucket.org/yarosla/httpress/wi…

I don't know if ab sends HEAD requests! Thanks for the link to httpress; I've been having trouble with ab failing at high concurrencies (1000 concurrent connections) and also being the bottleneck.
Post reply on HN