Home | History | Annotate | Download | only in microspdy
      1 /*
      2     This file is part of libmicrospdy
      3     Copyright Copyright (C) 2013 Andrey Uzunov
      4 
      5     This program is free software: you can redistribute it and/or modify
      6     it under the terms of the GNU General Public License as published by
      7     the Free Software Foundation, either version 3 of the License, or
      8     (at your option) any later version.
      9 
     10     This program is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13     GNU General Public License for more details.
     14 
     15     You should have received a copy of the GNU General Public License
     16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 */
     18 
     19 /**
     20  * @file io_raw.c
     21  * @brief  IO for SPDY without TLS.
     22  * @author Andrey Uzunov
     23  */
     24 
     25 #include "platform.h"
     26 #include "internal.h"
     27 #include "session.h"
     28 #include "io_raw.h"
     29 //TODO put in in the right place
     30 #include <netinet/tcp.h>
     31 
     32 
     33 void
     34 SPDYF_raw_global_init()
     35 {
     36 }
     37 
     38 
     39 void
     40 SPDYF_raw_global_deinit()
     41 {
     42 }
     43 
     44 
     45 int
     46 SPDYF_raw_init(struct SPDY_Daemon *daemon)
     47 {
     48   (void)daemon;
     49 
     50 	return SPDY_YES;
     51 }
     52 
     53 
     54 void
     55 SPDYF_raw_deinit(struct SPDY_Daemon *daemon)
     56 {
     57   (void)daemon;
     58 }
     59 
     60 
     61 int
     62 SPDYF_raw_new_session(struct SPDY_Session *session)
     63 {
     64   int fd_flags;
     65   int val = 1;
     66   int ret;
     67 
     68 	//setting the socket to be non-blocking
     69 	fd_flags = fcntl (session->socket_fd, F_GETFL);
     70 	if ( -1 == fd_flags
     71 		|| 0 != fcntl (session->socket_fd, F_SETFL, fd_flags | O_NONBLOCK))
     72 		SPDYF_DEBUG("WARNING: Couldn't set the new connection to be non-blocking");
     73 
     74   if(SPDY_DAEMON_FLAG_NO_DELAY & session->daemon->flags)
     75   {
     76     ret = setsockopt(session->socket_fd, IPPROTO_TCP, TCP_NODELAY, &val, (socklen_t)sizeof(val));
     77     if(-1 == ret)
     78       SPDYF_DEBUG("WARNING: Couldn't set the new connection to TCP_NODELAY");
     79   }
     80 
     81 	return SPDY_YES;
     82 }
     83 
     84 
     85 void
     86 SPDYF_raw_close_session(struct SPDY_Session *session)
     87 {
     88   (void)session;
     89 }
     90 
     91 
     92 int
     93 SPDYF_raw_recv(struct SPDY_Session *session,
     94 				void * buffer,
     95 				size_t size)
     96 {
     97 	int n = read(session->socket_fd,
     98 					buffer,
     99 					size);
    100 	//if(n > 0) SPDYF_DEBUG("recvd: %i",n);
    101 	if (n < 0)
    102 	{
    103 		switch(errno)
    104 		{
    105 			case EAGAIN:
    106 #if EAGAIN != EWOULDBLOCK
    107       case EWOULDBLOCK:
    108 #endif
    109 			case EINTR:
    110         return SPDY_IO_ERROR_AGAIN;
    111 
    112 			default:
    113 				return SPDY_IO_ERROR_ERROR;
    114 		}
    115 	}
    116 
    117 	return n;
    118 }
    119 
    120 
    121 int
    122 SPDYF_raw_send(struct SPDY_Session *session,
    123 				const void * buffer,
    124 				size_t size)
    125 {
    126 	int n = write(session->socket_fd,
    127 					buffer,
    128 					size);
    129 	//if(n > 0) SPDYF_DEBUG("sent: %i",n);
    130 	if (n < 0)
    131 	{
    132 		switch(errno)
    133 		{
    134 			case EAGAIN:
    135 #if EAGAIN != EWOULDBLOCK
    136       case EWOULDBLOCK:
    137 #endif
    138 			case EINTR:
    139         return SPDY_IO_ERROR_AGAIN;
    140 
    141 			default:
    142 				return SPDY_IO_ERROR_ERROR;
    143 		}
    144 	}
    145 
    146 	return n;
    147 }
    148 
    149 
    150 int
    151 SPDYF_raw_is_pending(struct SPDY_Session *session)
    152 {
    153   (void)session;
    154 
    155 	return SPDY_NO;
    156 }
    157 
    158 
    159 int
    160 SPDYF_raw_before_write(struct SPDY_Session *session)
    161 {
    162 #if HAVE_DECL_TCP_CORK
    163   if(0 == (SPDY_DAEMON_FLAG_NO_DELAY & session->daemon->flags))
    164   {
    165     int val = 1;
    166     int ret;
    167 
    168     ret = setsockopt(session->socket_fd, IPPROTO_TCP, TCP_CORK, &val, (socklen_t)sizeof(val));
    169     if(-1 == ret)
    170       SPDYF_DEBUG("WARNING: Couldn't set the new connection to TCP_CORK");
    171   }
    172 #endif
    173 
    174 	return SPDY_YES;
    175 }
    176 
    177 
    178 int
    179 SPDYF_raw_after_write(struct SPDY_Session *session, int was_written)
    180 {
    181 #if HAVE_DECL_TCP_CORK
    182   if(SPDY_YES == was_written && 0 == (SPDY_DAEMON_FLAG_NO_DELAY & session->daemon->flags))
    183   {
    184     int val = 0;
    185     int ret;
    186 
    187     ret = setsockopt(session->socket_fd, IPPROTO_TCP, TCP_CORK, &val, (socklen_t)sizeof(val));
    188     if(-1 == ret)
    189       SPDYF_DEBUG("WARNING: Couldn't unset the new connection to TCP_CORK");
    190   }
    191 
    192 #endif
    193 	return was_written;
    194 }
    195