2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3 * 2009, 2010 Free Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
26 /* This is the only file that uses the berkeley sockets API.
28 * Also holds all the buffering code used in gnutls.
29 * The buffering code works as:
32 * 1. uses a buffer to hold data (application/handshake),
33 * we got but they were not requested, yet.
34 * (see gnutls_record_buffer_put(), gnutls_record_buffer_get_size() etc.)
36 * 2. uses a buffer to hold data that were incomplete (ie the read/write
38 * (see _gnutls_io_read_buffered(), _gnutls_io_write_buffered() etc.)
41 * 1. Uses a buffer to hold data that was not sent or received
42 * complete. (E.g. sent 10 bytes of a handshake packet that is 20 bytes
44 * (see _gnutls_handshake_send_int(), _gnutls_handshake_recv_int())
46 * 2. Uses buffer to hold the last received handshake message.
47 * (see _gnutls_handshake_buffer_put() etc.)
51 #include <gnutls_int.h>
52 #include <gnutls_errors.h>
53 #include <gnutls_num.h>
54 #include <gnutls_record.h>
55 #include <gnutls_buffers.h>
56 #include <gnutls_mbuffers.h>
65 #define EAGAIN EWOULDBLOCK
68 /* this is the maximum number of messages allowed to queue.
73 * gnutls_transport_set_errno:
74 * @session: is a #gnutls_session_t structure.
75 * @err: error value to store in session-specific errno variable.
77 * Store @err in the session-specific errno variable. Useful values
78 * for @err is EAGAIN and EINTR, other values are treated will be
79 * treated as real errors in the push/pull function.
81 * This function is useful in replacement push/pull functions set by
82 * gnutls_transport_set_push_function and
83 * gnutls_transport_set_pullpush_function under Windows, where the
84 * replacement push/pull may not have access to the same @errno
85 * variable that is used by GnuTLS (e.g., the application is linked to
86 * msvcr71.dll and gnutls is linked to msvcrt.dll).
88 * If you don't have the @session variable easily accessible from the
89 * push/pull function, and don't worry about thread conflicts, you can
90 * also use gnutls_transport_set_global_errno().
93 gnutls_transport_set_errno (gnutls_session_t session, int err)
95 session->internals.errnum = err;
99 * gnutls_transport_set_global_errno:
100 * @err: error value to store in global errno variable.
102 * Store @err in the global errno variable. Useful values for @err is
103 * EAGAIN and EINTR, other values are treated will be treated as real
104 * errors in the push/pull function.
106 * This function is useful in replacement push/pull functions set by
107 * gnutls_transport_set_push_function and
108 * gnutls_transport_set_pullpush_function under Windows, where the
109 * replacement push/pull may not have access to the same @errno
110 * variable that is used by GnuTLS (e.g., the application is linked to
111 * msvcr71.dll and gnutls is linked to msvcrt.dll).
113 * Whether this function is thread safe or not depends on whether the
114 * global variable errno is thread safe, some system libraries make it
115 * a thread-local variable. When feasible, using the guaranteed
116 * thread-safe gnutls_transport_set_errno() may be better.
119 gnutls_transport_set_global_errno (int err)
122 /* Keep this in sync with system_errno */
126 SetLastError (WSAEWOULDBLOCK);
129 SetLastError (WSAEINTR);
132 /* We don't care about anything else */
133 SetLastError (NO_ERROR);
141 /* Buffers received packets of type APPLICATION DATA and
145 _gnutls_record_buffer_put (content_type_t type,
146 gnutls_session_t session, opaque * data,
149 gnutls_buffer_st *buf;
156 case GNUTLS_APPLICATION_DATA:
157 buf = &session->internals.application_data_buffer;
158 _gnutls_buffers_log ("BUF[REC]: Inserted %d bytes of Data(%d)\n",
159 (int) length, (int) type);
162 case GNUTLS_HANDSHAKE:
163 buf = &session->internals.handshake_data_buffer;
164 _gnutls_buffers_log ("BUF[HSK]: Inserted %d bytes of Data(%d)\n",
165 (int) length, (int) type);
168 case GNUTLS_INNER_APPLICATION:
169 buf = &session->internals.ia_data_buffer;
170 _gnutls_buffers_log ("BUF[IA]: Inserted %d bytes of Data(%d)\n",
171 (int) length, (int) type);
176 return GNUTLS_E_INVALID_REQUEST;
179 if (_gnutls_buffer_append_data (buf, data, length) < 0)
182 return GNUTLS_E_MEMORY_ERROR;
189 _gnutls_record_buffer_get_size (content_type_t type, gnutls_session_t session)
193 case GNUTLS_APPLICATION_DATA:
194 return session->internals.application_data_buffer.length;
196 case GNUTLS_HANDSHAKE:
197 return session->internals.handshake_data_buffer.length;
199 case GNUTLS_INNER_APPLICATION:
200 return session->internals.ia_data_buffer.length;
203 return GNUTLS_E_INVALID_REQUEST;
208 * gnutls_record_check_pending:
209 * @session: is a #gnutls_session_t structure.
211 * This function checks if there are any data to receive in the gnutls
214 * Returns: the size of that data or 0.
217 gnutls_record_check_pending (gnutls_session_t session)
219 return _gnutls_record_buffer_get_size (GNUTLS_APPLICATION_DATA, session);
223 _gnutls_record_buffer_get (content_type_t type,
224 gnutls_session_t session, opaque * data,
227 if (length == 0 || data == NULL)
230 return GNUTLS_E_INVALID_REQUEST;
235 case GNUTLS_APPLICATION_DATA:
236 _gnutls_buffer_pop_data (&session->internals.application_data_buffer,
238 _gnutls_buffers_log ("BUFFER[REC][AD]: Read %d bytes of Data(%d)\n",
239 (int) length, (int) type);
242 case GNUTLS_HANDSHAKE:
243 _gnutls_buffer_pop_data (&session->internals.handshake_data_buffer,
245 _gnutls_buffers_log ("BUF[REC][HD]: Read %d bytes of Data(%d)\n",
246 (int) length, (int) type);
249 case GNUTLS_INNER_APPLICATION:
251 _gnutls_buffer_pop_data (&session->internals.ia_data_buffer, data,
253 _gnutls_buffers_log ("BUF[REC][IA]: Read %d bytes of Data(%d)\n",
254 (int) length, (int) type);
259 return GNUTLS_E_INVALID_REQUEST;
267 reset_errno (gnutls_session_t session)
269 session->internals.errnum = 0;
273 get_errno (gnutls_session_t session)
275 if (session->internals.errnum != 0)
276 return session->internals.errnum;
278 return session->internals.errno_func (session->
279 internals.transport_recv_ptr);
283 /* This function is like read. But it does not return -1 on error.
284 * It does return gnutls_errno instead.
286 * Flags are only used if the default recv() function is being used.
289 _gnutls_read (gnutls_session_t session, mbuffer_st ** bufel,
290 size_t size, gnutls_pull_func pull_func)
295 gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;
300 return GNUTLS_E_INTERNAL_ERROR;
303 *bufel = _mbuffer_alloc (0, size);
307 return GNUTLS_E_MEMORY_ERROR;
309 ptr = (*bufel)->msg.data;
311 session->internals.direction = 0;
316 reset_errno (session);
318 i = pull_func (fd, &ptr[size - left], left);
322 int err = get_errno (session);
324 _gnutls_read_log ("READ: %d returned from %p, errno=%d gerrno=%d\n",
325 (int) i, fd, errno, session->internals.errnum);
327 if (err == EAGAIN || err == EINTR)
332 _gnutls_read_log ("READ: returning %d bytes from %p\n",
333 (int) (size - left), fd);
339 return GNUTLS_E_AGAIN;
340 return GNUTLS_E_INTERRUPTED;
345 return GNUTLS_E_PULL_ERROR;
351 _gnutls_read_log ("READ: Got %d bytes from %p\n", (int) i, fd);
358 (*bufel)->msg.size += i;
363 if (_gnutls_log_level >= 7)
365 _gnutls_read_log ("READ: read %d bytes from %p\n",
366 (int) (size - left), fd);
370 return (size - left);
376 _gnutls_writev_emu (gnutls_session_t session, const giovec_t * giovec,
380 gnutls_transport_ptr_t fd = session->internals.transport_send_ptr;
385 for (j = 0; j < giovec_cnt; j++)
387 sizeOfPtr = giovec[j].iov_len;
388 iptr = giovec[j].iov_base;
390 ret = session->internals.push_func (fd, iptr, sizeOfPtr);
397 if (ret != giovec[j].iov_len)
408 _gnutls_writev (gnutls_session_t session, const giovec_t * giovec,
412 gnutls_transport_ptr_t fd = session->internals.transport_send_ptr;
414 reset_errno (session);
416 if (session->internals.push_func != NULL)
417 i = _gnutls_writev_emu (session, giovec, giovec_cnt);
419 i = session->internals.vec_push_func (fd, giovec, giovec_cnt);
423 int err = get_errno (session);
424 _gnutls_debug_log ("errno: %d\n", err);
426 return GNUTLS_E_AGAIN;
427 else if (err == EINTR)
428 return GNUTLS_E_INTERRUPTED;
432 return GNUTLS_E_PUSH_ERROR;
438 #define RCVLOWAT session->internals.lowat
440 /* This function is only used with berkeley style sockets.
441 * Clears the peeked data (read with MSG_PEEK).
444 _gnutls_io_clear_peeked_data (gnutls_session_t session)
446 mbuffer_st *peekdata;
449 if (session->internals.have_peeked_data == 0 || RCVLOWAT == 0)
452 /* this was already read by using MSG_PEEK - so it shouldn't fail */
455 { /* we need this to finish now */
457 _gnutls_read (session, &peekdata, RCVLOWAT - sum,
458 session->internals.pull_func);
461 _mbuffer_xfree (&peekdata);
463 while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN
472 session->internals.have_peeked_data = 0;
477 /* This function is like recv(with MSG_PEEK). But it does not return -1 on error.
478 * It does return gnutls_errno instead.
479 * This function reads data from the socket and keeps them in a buffer, of up to
482 * This is not a general purpose function. It returns EXACTLY the data requested,
483 * which are stored in a local (in the session) buffer.
487 _gnutls_io_read_buffered (gnutls_session_t session, size_t total,
488 content_type_t recv_type)
490 ssize_t ret = 0, ret2 = 0;
492 mbuffer_st *bufel = NULL;
493 size_t recvlowat, recvdata, readsize;
495 if (total > MAX_RECV_SIZE || total == 0)
497 gnutls_assert (); /* internal error */
498 return GNUTLS_E_INVALID_REQUEST;
501 /* If an external pull function is used, then do not leave
502 * any data into the kernel buffer.
504 if (session->internals.pull_func != system_read)
510 /* leave peeked data to the kernel space only if application data
511 * is received and we don't have any peeked
512 * data in gnutls session.
514 if (recv_type != GNUTLS_APPLICATION_DATA
515 && session->internals.have_peeked_data == 0)
518 recvlowat = RCVLOWAT;
523 /* calculate the actual size, ie. get the minimum of the
524 * buffered data and the requested data.
526 min = MIN (session->internals.record_recv_buffer.byte_length, total);
529 /* if we have enough buffered data
530 * then just return them.
538 /* min is over zero. recvdata is the data we must
539 * receive in order to return the requested data.
541 recvdata = total - min;
542 readsize = recvdata - recvlowat;
544 /* Check if the previously read data plus the new data to
545 * receive are longer than the maximum receive buffer size.
547 if ((session->internals.record_recv_buffer.byte_length + recvdata) >
550 gnutls_assert (); /* internal error */
551 return GNUTLS_E_INVALID_REQUEST;
560 /* READ DATA - but leave RCVLOWAT bytes in the kernel buffer.
565 _gnutls_read (session, &bufel, readsize,
566 session->internals.pull_func);
568 /* return immediately if we got an interrupt or eagain
571 if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
573 _mbuffer_xfree (&bufel);
578 /* copy fresh data to our buffer.
583 ("RB: Have %d bytes into buffer. Adding %d bytes.\n",
584 (int) session->internals.record_recv_buffer.byte_length, (int) ret);
585 _gnutls_read_log ("RB: Requested %d bytes\n", (int) total);
587 _mbuffer_enqueue (&session->internals.record_recv_buffer, bufel);
590 _mbuffer_xfree (&bufel);
593 /* This is hack in order for select to work. Just leave recvlowat data,
594 * into the kernel buffer (using a read with MSG_PEEK), thus making
595 * select think, that the socket is ready for reading.
596 * MSG_PEEK is only used with berkeley style sockets.
598 if (ret == readsize && recvlowat > 0)
600 ret2 = _gnutls_read (session, &bufel, recvlowat, system_read_peek);
602 if (ret2 < 0 && gnutls_error_is_fatal (ret2) == 0)
604 _mbuffer_xfree (&bufel);
610 _gnutls_read_log ("RB-PEEK: Read %d bytes in PEEK MODE.\n",
613 ("RB-PEEK: Have %d bytes into buffer. Adding %d bytes.\nRB: Requested %d bytes\n",
614 (int) session->internals.record_recv_buffer.byte_length,
615 (int) ret2, (int) total);
616 session->internals.have_peeked_data = 1;
617 _mbuffer_enqueue (&session->internals.record_recv_buffer, bufel);
620 _mbuffer_xfree (&bufel);
623 if (ret < 0 || ret2 < 0)
626 /* that's because they are initialized to 0 */
627 return MIN (ret, ret2);
632 if (ret > 0 && ret < recvlowat)
635 return GNUTLS_E_AGAIN;
644 ret = session->internals.record_recv_buffer.byte_length;
646 if ((ret > 0) && ((size_t) ret < total))
650 return GNUTLS_E_AGAIN;
658 /* This function is like write. But it does not return -1 on error.
659 * It does return gnutls_errno instead.
661 * This function takes full responsibility of freeing msg->data.
663 * In case of E_AGAIN and E_INTERRUPTED errors, you must call
664 * gnutls_write_flush(), until it returns ok (0).
666 * We need to push exactly the data in msg->size, since we cannot send
667 * less data. In TLS the peer must receive the whole packet in order
668 * to decrypt and verify the integrity.
672 _gnutls_io_write_buffered (gnutls_session_t session,
673 mbuffer_st * bufel, unsigned int mflag)
675 mbuffer_head_st *const send_buffer = &session->internals.record_send_buffer;
677 /* to know where the procedure was interrupted.
679 session->internals.direction = 1;
681 _mbuffer_enqueue (send_buffer, bufel);
684 ("WRITE: enqueued %d bytes for %p. Total %d bytes.\n",
685 (int) bufel->msg.size, session->internals.transport_recv_ptr,
686 (int) send_buffer->byte_length);
688 if (mflag == MBUFFER_FLUSH)
689 return _gnutls_io_write_flush (session);
691 return bufel->msg.size;
694 typedef ssize_t (*send_func) (gnutls_session_t, const giovec_t *, int);
696 /* This function writes the data that are left in the
697 * TLS write buffer (ie. because the previous write was
701 _gnutls_io_write_flush (gnutls_session_t session)
704 mbuffer_head_st *send_buffer = &session->internals.record_send_buffer;
706 ssize_t sent = 0, tosend = 0;
707 giovec_t iovec[MAX_QUEUE];
711 _gnutls_write_log ("WRITE FLUSH: %d bytes in buffer.\n",
712 (int) send_buffer->byte_length);
714 for (cur = _mbuffer_get_first (send_buffer, &msg);
715 cur != NULL; cur = _mbuffer_get_next (cur, &msg))
717 iovec[i].iov_base = msg.data;
718 iovec[i++].iov_len = msg.size;
721 /* we buffer up to MAX_QUEUE messages */
722 if (i >= sizeof (iovec) / sizeof (iovec[0]))
725 return GNUTLS_E_INTERNAL_ERROR;
735 ret = _gnutls_writev (session, iovec, i);
738 _mbuffer_remove_bytes (send_buffer, ret);
739 _gnutls_write_log ("WRITE: wrote %d bytes, %d bytes left.\n",
740 ret, (int) send_buffer->byte_length);
744 else if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN)
746 _gnutls_write_log ("WRITE interrupted: %d bytes left.\n",
747 (int) send_buffer->byte_length);
752 _gnutls_write_log ("WRITE error: code %d, %d bytes left.\n",
753 ret, (int) send_buffer->byte_length);
762 return GNUTLS_E_AGAIN;
768 /* This function writes the data that are left in the
769 * Handshake write buffer (ie. because the previous write was
774 _gnutls_handshake_io_write_flush (gnutls_session_t session)
776 mbuffer_head_st *const send_buffer =
777 &session->internals.handshake_send_buffer;
783 _gnutls_write_log ("HWRITE FLUSH: %d bytes in buffer.\n",
784 (int) send_buffer->byte_length);
786 for (cur = _mbuffer_get_first (send_buffer, &msg);
787 cur != NULL; cur = _mbuffer_get_first (send_buffer, &msg))
789 ret = _gnutls_send_int (session, GNUTLS_HANDSHAKE,
790 session->internals.handshake_send_buffer_htype,
792 msg.data, msg.size, 0 /* do not flush */ );
796 _mbuffer_remove_bytes (send_buffer, ret);
798 _gnutls_write_log ("HWRITE: wrote %d bytes, %d bytes left.\n",
799 ret, (int) send_buffer->byte_length);
805 _gnutls_write_log ("HWRITE error: code %d, %d bytes left.\n",
806 ret, (int) send_buffer->byte_length);
813 return _gnutls_io_write_flush (session);
818 /* This is a send function for the gnutls handshake
819 * protocol. Just makes sure that all data have been sent.
823 _gnutls_handshake_io_cache_int (gnutls_session_t session,
824 gnutls_handshake_description_t htype,
827 mbuffer_head_st *const send_buffer =
828 &session->internals.handshake_send_buffer;
830 _mbuffer_enqueue (send_buffer, bufel);
831 session->internals.handshake_send_buffer_htype = htype;
834 ("HWRITE: enqueued %d. Total %d bytes.\n",
835 (int) bufel->msg.size, (int) send_buffer->byte_length);
840 /* This is a receive function for the gnutls handshake
841 * protocol. Makes sure that we have received all data.
844 _gnutls_handshake_io_recv_int (gnutls_session_t session,
846 gnutls_handshake_description_t htype,
847 void *iptr, size_t sizeOfPtr)
857 if (sizeOfPtr == 0 || iptr == NULL)
860 return GNUTLS_E_INVALID_REQUEST;
863 if (session->internals.handshake_recv_buffer.length > 0)
867 /* if we have already received some data */
868 if (sizeOfPtr <= session->internals.handshake_recv_buffer.length)
870 /* if requested less data then return it.
875 _gnutls_buffer_pop_data (&session->internals.handshake_recv_buffer,
882 _gnutls_buffer_pop_data (&session->internals.handshake_recv_buffer,
886 htype = session->internals.handshake_recv_buffer_htype;
887 type = session->internals.handshake_recv_buffer_type;
892 dsize = sizeOfPtr - left;
893 i = _gnutls_recv_int (session, type, htype, &ptr[dsize], left);
897 if (dsize > 0 && (i == GNUTLS_E_INTERRUPTED || i == GNUTLS_E_AGAIN))
901 _gnutls_buffer_append_data (&session->internals.
902 handshake_recv_buffer, iptr, dsize);
904 session->internals.handshake_recv_buffer_htype = htype;
905 session->internals.handshake_recv_buffer_type = type;
920 session->internals.handshake_recv_buffer.length = 0;
922 return sizeOfPtr - left;
925 /* Buffer for handshake packets. Keeps the packets in order
926 * for finished messages to use them. Used in HMAC calculation
927 * and finished messages.
930 _gnutls_handshake_buffer_put (gnutls_session_t session, opaque * data,
937 if ((session->internals.max_handshake_data_buffer_size > 0) &&
938 ((length + session->internals.handshake_hash_buffer.length) >
939 session->internals.max_handshake_data_buffer_size))
942 return GNUTLS_E_HANDSHAKE_TOO_LARGE;
945 _gnutls_buffers_log ("BUF[HSK]: Inserted %d bytes of Data\n", (int) length);
946 if (_gnutls_buffer_append_data (&session->internals.handshake_hash_buffer,
950 return GNUTLS_E_MEMORY_ERROR;
957 _gnutls_handshake_buffer_get_size (gnutls_session_t session)
960 return session->internals.handshake_hash_buffer.length;
963 /* this function does not touch the buffer
964 * and returns data from it (peek mode!)
967 _gnutls_handshake_buffer_get_ptr (gnutls_session_t session,
968 opaque ** data_ptr, size_t * length)
971 *length = session->internals.handshake_hash_buffer.length;
973 _gnutls_buffers_log ("BUF[HSK]: Peeked %d bytes of Data\n",
974 (int) session->internals.handshake_hash_buffer.length);
976 if (data_ptr != NULL)
977 *data_ptr = session->internals.handshake_hash_buffer.data;
982 /* Does not free the buffer
985 _gnutls_handshake_buffer_empty (gnutls_session_t session)
988 _gnutls_buffers_log ("BUF[HSK]: Emptied buffer\n");
990 session->internals.handshake_hash_buffer.length = 0;
997 _gnutls_handshake_buffer_clear (gnutls_session_t session)
1000 _gnutls_buffers_log ("BUF[HSK]: Cleared Data from buffer\n");
1001 _gnutls_buffer_clear (&session->internals.handshake_hash_buffer);
1007 * gnutls_transport_set_pull_function:
1008 * @session: is a #gnutls_session_t structure.
1009 * @pull_func: a callback function similar to read()
1011 * This is the function where you set a function for gnutls to receive
1012 * data. Normally, if you use berkeley style sockets, do not need to
1013 * use this function since the default (recv(2)) will probably be ok.
1015 * PULL_FUNC is of the form,
1016 * ssize_t (*gnutls_pull_func)(gnutls_transport_ptr_t, void*, size_t);
1019 gnutls_transport_set_pull_function (gnutls_session_t session,
1020 gnutls_pull_func pull_func)
1022 session->internals.pull_func = pull_func;
1026 * gnutls_transport_set_push_function:
1027 * @session: is a #gnutls_session_t structure.
1028 * @push_func: a callback function similar to write()
1030 * This is the function where you set a push function for gnutls to
1031 * use in order to send data. If you are going to use berkeley style
1032 * sockets, you do not need to use this function since the default
1033 * (send(2)) will probably be ok. Otherwise you should specify this
1034 * function for gnutls to be able to send data.
1036 * PUSH_FUNC is of the form,
1037 * ssize_t (*gnutls_push_func)(gnutls_transport_ptr_t, const void*, size_t);
1040 gnutls_transport_set_push_function (gnutls_session_t session,
1041 gnutls_push_func push_func)
1043 session->internals.push_func = push_func;
1044 session->internals.vec_push_func = NULL;
1048 * gnutls_transport_set_vec_push_function:
1049 * @session: is a #gnutls_session_t structure.
1050 * @vec_func: a callback function similar to writev()
1052 * This is the function where you set a push function for gnutls to
1053 * use in order to send data. If you are going to use berkeley style
1054 * sockets, you do not need to use this function since the default
1055 * (send(2)) will probably be ok. Otherwise you should specify this
1056 * function for gnutls to be able to send data.
1058 * PUSH_FUNC is of the form,
1059 * ssize_t (*gnutls_push_func)(gnutls_transport_ptr_t, const void*, size_t);
1062 gnutls_transport_set_vec_push_function (gnutls_session_t session,
1063 gnutls_vec_push_func vec_func)
1065 session->internals.push_func = NULL;
1066 session->internals.vec_push_func = vec_func;
1070 * gnutls_transport_set_errno_function:
1071 * @session: is a #gnutls_session_t structure.
1072 * @errno_func: a callback function similar to write()
1074 * This is the function where you set a function to retrieve errno
1075 * after a failed push or pull operation.
1077 * errno_func is of the form,
1078 * int (*gnutls_errno_func)(gnutls_transport_ptr_t);
1079 * and should return the errno.
1082 gnutls_transport_set_errno_function (gnutls_session_t session,
1083 gnutls_errno_func errno_func)
1085 session->internals.errno_func = errno_func;