CyaSSL is an SSL library for devices like mbed.

Dependents:   cyassl-client Sync

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cyassl_io.c Source File

cyassl_io.c

00001 /* cyassl_io.c
00002  *
00003  * Copyright (C) 2006-2009 Sawtooth Consulting Ltd.
00004  *
00005  * This file is part of CyaSSL.
00006  *
00007  * CyaSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * CyaSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00020  */
00021 
00022 
00023 #ifdef _WIN32_WCE
00024     /* On WinCE winsock2.h must be included before windows.h for socket stuff */
00025     #include <winsock2.h>
00026 #endif
00027 
00028 #include "cyassl_int.h"
00029 
00030 /* if user writes own I/O callbacks they can define CYASSL_USER_IO to remove
00031    automatic setting of defualt I/O functions EmbedSend() and EmbedReceive()
00032    but they'll still nedd SetCallback xxx() at end of file 
00033 */
00034 #ifndef CYASSL_USER_IO
00035 
00036 #ifdef HAVE_LIBZ
00037     #include "zlib.h"
00038 #endif
00039 
00040 #ifndef USE_WINDOWS_API 
00041     #include <sys/types.h>
00042     #include <errno.h>
00043     #include <unistd.h>
00044     #include <fcntl.h>
00045     #if !(defined(DEVKITPRO) || defined(THREADX))
00046         #include <sys/socket.h>
00047         #include <arpa/inet.h>
00048         #include <netinet/in.h>
00049         #include <netdb.h>
00050         #include <sys/ioctl.h>
00051     #endif
00052     #ifdef THREADX
00053         #include <socket.h>
00054     #endif
00055 #endif /* USE_WINDOWS_API */
00056 
00057 #ifdef __sun
00058     #include <sys/filio.h>
00059 #endif
00060 
00061 #ifdef USE_WINDOWS_API 
00062     /* no epipe yet */
00063     #ifndef WSAEPIPE
00064         #define WSAEPIPE       -12345
00065     #endif
00066     #define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK
00067     #define SOCKET_EAGAIN      WSAEWOULDBLOCK
00068     #define SOCKET_ECONNRESET  WSAECONNRESET
00069     #define SOCKET_EINTR       WSAEINTR
00070     #define SOCKET_EPIPE       WSAEPIPE
00071 #else
00072     #define SOCKET_EWOULDBLOCK EWOULDBLOCK
00073     #define SOCKET_EAGAIN      EAGAIN
00074     #define SOCKET_ECONNRESET  ECONNRESET
00075     #define SOCKET_EINTR       EINTR
00076     #define SOCKET_EPIPE       EPIPE
00077 #endif /* USE_WINDOWS_API */
00078 
00079 
00080 #ifdef DEVKITPRO
00081     /* from network.h */
00082     int net_send(int, const void*, int, unsigned int);
00083     int net_recv(int, void*, int, unsigned int);
00084     #define SEND_FUNCTION net_send
00085     #define RECV_FUNCTION net_recv
00086 #else
00087     #define SEND_FUNCTION send
00088     #define RECV_FUNCTION recv
00089 #endif
00090 
00091 
00092 static INLINE int LastError(void)
00093 {
00094 #ifdef USE_WINDOWS_API 
00095     return WSAGetLastError();
00096 #else
00097     return errno;
00098 #endif
00099 }
00100 
00101 /* The receive embedded callback
00102  *  return : nb bytes read, or error
00103  */
00104 int EmbedReceive(char *buf, int sz, void *ctx)
00105 {
00106     int recvd;
00107     int err;
00108     int socket = *(int*)ctx;
00109 
00110     recvd = RECV_FUNCTION(socket, (char *)buf, sz, 0);
00111 
00112     if (recvd == -1) {
00113         err = LastError();
00114         if (err == SOCKET_EWOULDBLOCK ||
00115             err == SOCKET_EAGAIN)
00116             return IO_ERR_WANT_READ;
00117 
00118         else if (err == SOCKET_ECONNRESET)
00119             return IO_ERR_CONN_RST;
00120 
00121         else if (err == SOCKET_EINTR)
00122             return IO_ERR_ISR;
00123 
00124         else
00125             return IO_ERR_GENERAL;
00126     }
00127     else if (recvd == 0)
00128         return IO_ERR_CONN_CLOSE;
00129 
00130     return recvd;
00131 }
00132 
00133 /* The send embedded callback
00134  *  return : nb bytes sent, or error
00135  */
00136 int EmbedSend(char *buf, int sz, void *ctx)
00137 {
00138     int socket = *(int*)ctx;
00139     int sent;
00140     int len = sz;
00141 
00142     sent = SEND_FUNCTION(socket, &buf[sz - len], len, 0);
00143 
00144     if (sent == -1) {
00145         if (LastError() == SOCKET_EWOULDBLOCK || 
00146             LastError() == SOCKET_EAGAIN)
00147             return IO_ERR_WANT_WRITE;
00148 
00149         else if (LastError() == SOCKET_ECONNRESET)
00150             return IO_ERR_CONN_RST;
00151 
00152         else if (LastError() == SOCKET_EINTR)
00153             return IO_ERR_ISR;
00154 
00155         else if (LastError() == SOCKET_EPIPE)
00156             return IO_ERR_CONN_CLOSE;
00157 
00158         else
00159             return IO_ERR_GENERAL;
00160     }
00161  
00162     return sent;
00163 }
00164 
00165 
00166 #endif /* CYASSL_USER_IO */
00167 
00168 
00169 
00170 void CyaSSL_SetIORecv(SSL_CTX *ctx, CallbackIORecv CBIORecv)
00171 {
00172     ctx->CBIORecv = CBIORecv;
00173 }
00174 
00175 
00176 void CyaSSL_SetIOSend(SSL_CTX *ctx, CallbackIOSend CBIOSend)
00177 {
00178     ctx->CBIOSend = CBIOSend;
00179 }
00180 
00181 
00182 void CyaSSL_SetIOReadCtx(SSL* ssl, void *rctx)
00183 {
00184     ssl->IOCB_ReadCtx = rctx;
00185 }
00186 
00187 
00188 void CyaSSL_SetIOWriteCtx(SSL* ssl, void *wctx)
00189 {
00190     ssl->IOCB_WriteCtx = wctx;
00191 }
00192