diff options
Diffstat (limited to 'src/microspdy/io_raw.c')
-rw-r--r-- | src/microspdy/io_raw.c | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/src/microspdy/io_raw.c b/src/microspdy/io_raw.c new file mode 100644 index 00000000..722f347e --- /dev/null +++ b/src/microspdy/io_raw.c @@ -0,0 +1,194 @@ +/* + This file is part of libmicrospdy + Copyright Copyright (C) 2013 Andrey Uzunov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/** + * @file io_raw.c + * @brief IO for SPDY without TLS. + * @author Andrey Uzunov + */ + +#include "platform.h" +#include "internal.h" +#include "session.h" +#include "io_raw.h" +//TODO put in in the right place +#include <netinet/tcp.h> + + +void +SPDYF_raw_global_init() +{ +} + + +void +SPDYF_raw_global_deinit() +{ +} + + +int +SPDYF_raw_init(struct SPDY_Daemon *daemon) +{ + (void)daemon; + + return SPDY_YES; +} + + +void +SPDYF_raw_deinit(struct SPDY_Daemon *daemon) +{ + (void)daemon; +} + + +int +SPDYF_raw_new_session(struct SPDY_Session *session) +{ + int fd_flags; + int val = 1; + int ret; + + //setting the socket to be non-blocking + fd_flags = fcntl (session->socket_fd, F_GETFL); + if ( -1 == fd_flags + || 0 != fcntl (session->socket_fd, F_SETFL, fd_flags | O_NONBLOCK)) + SPDYF_DEBUG("WARNING: Couldn't set the new connection to be non-blocking"); + + if(SPDY_DAEMON_FLAG_NO_DELAY & session->daemon->flags) + { + ret = setsockopt(session->socket_fd, IPPROTO_TCP, TCP_NODELAY, &val, (socklen_t)sizeof(val)); + if(-1 == ret) + SPDYF_DEBUG("WARNING: Couldn't set the new connection to TCP_NODELAY"); + } + + return SPDY_YES; +} + + +void +SPDYF_raw_close_session(struct SPDY_Session *session) +{ + (void)session; +} + + +int +SPDYF_raw_recv(struct SPDY_Session *session, + void * buffer, + size_t size) +{ + int n = read(session->socket_fd, + buffer, + size); + //if(n > 0) SPDYF_DEBUG("recvd: %i",n); + if (n < 0) + { + switch(errno) + { + case EAGAIN: +#if EAGAIN != EWOULDBLOCK + case EWOULDBLOCK: +#endif + case EINTR: + return SPDY_IO_ERROR_AGAIN; + + default: + return SPDY_IO_ERROR_ERROR; + } + } + + return n; +} + + +int +SPDYF_raw_send(struct SPDY_Session *session, + const void * buffer, + size_t size) +{ + int n = write(session->socket_fd, + buffer, + size); + //if(n > 0) SPDYF_DEBUG("sent: %i",n); + if (n < 0) + { + switch(errno) + { + case EAGAIN: +#if EAGAIN != EWOULDBLOCK + case EWOULDBLOCK: +#endif + case EINTR: + return SPDY_IO_ERROR_AGAIN; + + default: + return SPDY_IO_ERROR_ERROR; + } + } + + return n; +} + + +int +SPDYF_raw_is_pending(struct SPDY_Session *session) +{ + (void)session; + + return SPDY_NO; +} + + +int +SPDYF_raw_before_write(struct SPDY_Session *session) +{ +#if HAVE_DECL_TCP_CORK + if(0 == (SPDY_DAEMON_FLAG_NO_DELAY & session->daemon->flags)) + { + int val = 1; + int ret; + + ret = setsockopt(session->socket_fd, IPPROTO_TCP, TCP_CORK, &val, (socklen_t)sizeof(val)); + if(-1 == ret) + SPDYF_DEBUG("WARNING: Couldn't set the new connection to TCP_CORK"); + } +#endif + + return SPDY_YES; +} + + +int +SPDYF_raw_after_write(struct SPDY_Session *session, int was_written) +{ +#if HAVE_DECL_TCP_CORK + if(SPDY_YES == was_written && 0 == (SPDY_DAEMON_FLAG_NO_DELAY & session->daemon->flags)) + { + int val = 0; + int ret; + + ret = setsockopt(session->socket_fd, IPPROTO_TCP, TCP_CORK, &val, (socklen_t)sizeof(val)); + if(-1 == ret) + SPDYF_DEBUG("WARNING: Couldn't unset the new connection to TCP_CORK"); + } + +#endif + return was_written; +} |