Is there a libc function that would do the same thing as getline, but would work with a connected socket instead of a FILE * stream ?
A workaround wou开发者_JAVA百科ld be to call fdopen on a socket. What are things that should be taken care of, when doing so. What are reasons to do it/ not do it.
One obvious reason to do it is to call getline and co, but maybe it is a better idea to rewrite some custom getline ?
when you call a read on a socket, then it can return a zero value prematurely. eg.
read(fd, buf, bufsize)
can return a value less than bufsize if the kernel buffer for the tcp socket is full. in such a case it may be required to call the read function again unless it returns a zero or a negative result.
thus it is best to avoid stdio functions. you need to create wrappers for the read function in order to implement the iterative call to read for getting bufsize bytes reliably. it should return a zero value only when no more bytes can be read from the socket, as if the file is being read from the local disk.
you can find wrappers in the book Computer Systems: A Programmer's Perspective by Randal Bryant.
The source code is available at this site. look for functions beginning with rio_.
If the socket is connected to untrusted input, be prepared for arbitrary input within arbitrary time frame
- \0 character before \r\n
- wait eternally for any of \r or \n
- any other potentially ugly thing
One way to address the arbitrary timing and arbitrary data would be to provide timeouts on the reads e.g. via select(2) and feed the data you actually receive to some well-written state machine byte by byte.
The problem would be if you don't receive the new line (\n or \r\n, depends on your implementation) the program would hang. I'd write your own version that also makes calls to select() to check if the socket is still read/writable and doesn't have any errors. Really there would be no way to tell if another "\n" or "\r\n" is coming so make sure you know that the data from the client/server will be consistent.
Imagine you coded a webserver that reads the headers using getline(). If an attacker simple sent
GET / HTTP/1.1\r\n
This line isn't terminated: bla
The call the getline would never return and the program would hang. Probably costing you resources and eventually a DoS would be possible.
精彩评论