00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include <gnutls_int.h>
00051 #include <gnutls_errors.h>
00052 #include <gnutls_num.h>
00053 #include <gnutls_record.h>
00054 #include <gnutls_buffers.h>
00055
00056 #include <errno.h>
00057
00058 #ifdef _WIN32
00059 # include <winsock2.h>
00060 #endif
00061
00062 #ifndef EAGAIN
00063 # define EAGAIN EWOULDBLOCK
00064 #endif
00065
00066
00067
00068
00069 int
00070 MHD_gnutls_record_buffer_put (content_type_t type,
00071 MHD_gtls_session_t session, opaque * data,
00072 size_t length)
00073 {
00074 MHD_gtls_buffer *buf;
00075
00076 if (length == 0)
00077 return 0;
00078
00079 switch (type)
00080 {
00081 case GNUTLS_APPLICATION_DATA:
00082 buf = &session->internals.application_data_buffer;
00083 MHD__gnutls_buffers_log ("BUF[REC]: Inserted %d bytes of Data(%d)\n",
00084 length, type);
00085 break;
00086
00087 case GNUTLS_HANDSHAKE:
00088 buf = &session->internals.handshake_data_buffer;
00089 MHD__gnutls_buffers_log ("BUF[HSK]: Inserted %d bytes of Data(%d)\n",
00090 length, type);
00091 break;
00092
00093 case GNUTLS_INNER_APPLICATION:
00094 buf = &session->internals.ia_data_buffer;
00095 MHD__gnutls_buffers_log ("BUF[IA]: Inserted %d bytes of Data(%d)\n",
00096 length, type);
00097 break;
00098
00099 default:
00100 MHD_gnutls_assert ();
00101 return GNUTLS_E_INVALID_REQUEST;
00102 }
00103
00104 if (MHD_gtls_buffer_append (buf, data, length) < 0)
00105 {
00106 MHD_gnutls_assert ();
00107 return GNUTLS_E_MEMORY_ERROR;
00108 }
00109
00110 return 0;
00111 }
00112
00113 int
00114 MHD_gnutls_record_buffer_get_size (content_type_t type,
00115 MHD_gtls_session_t session)
00116 {
00117 switch (type)
00118 {
00119 case GNUTLS_APPLICATION_DATA:
00120 return session->internals.application_data_buffer.length;
00121
00122 case GNUTLS_HANDSHAKE:
00123 return session->internals.handshake_data_buffer.length;
00124
00125 case GNUTLS_INNER_APPLICATION:
00126 return session->internals.ia_data_buffer.length;
00127
00128 default:
00129 return GNUTLS_E_INVALID_REQUEST;
00130 }
00131 }
00132
00133 int
00134 MHD_gtls_record_buffer_get (content_type_t type, MHD_gtls_session_t session,
00135 opaque * data, size_t length)
00136 {
00137 if (length == 0 || data == NULL)
00138 {
00139 MHD_gnutls_assert ();
00140 return GNUTLS_E_INVALID_REQUEST;
00141 }
00142
00143 switch (type)
00144 {
00145 case GNUTLS_APPLICATION_DATA:
00146
00147 if (length > session->internals.application_data_buffer.length)
00148 {
00149 length = session->internals.application_data_buffer.length;
00150 }
00151
00152 MHD__gnutls_buffers_log ("BUFFER[REC][AD]: Read %d bytes of Data(%d)\n",
00153 length, type);
00154
00155 session->internals.application_data_buffer.length -= length;
00156 memcpy (data, session->internals.application_data_buffer.data, length);
00157
00158
00159 memmove (session->internals.application_data_buffer.data,
00160 &session->internals.application_data_buffer.data[length],
00161 session->internals.application_data_buffer.length);
00162
00163
00164
00165
00166
00167 break;
00168
00169 case GNUTLS_HANDSHAKE:
00170 if (length > session->internals.handshake_data_buffer.length)
00171 {
00172 length = session->internals.handshake_data_buffer.length;
00173 }
00174
00175 MHD__gnutls_buffers_log ("BUF[REC][HD]: Read %d bytes of Data(%d)\n",
00176 length, type);
00177
00178 session->internals.handshake_data_buffer.length -= length;
00179 memcpy (data, session->internals.handshake_data_buffer.data, length);
00180
00181
00182 memmove (session->internals.handshake_data_buffer.data,
00183 &session->internals.handshake_data_buffer.data[length],
00184 session->internals.handshake_data_buffer.length);
00185
00186 break;
00187
00188 case GNUTLS_INNER_APPLICATION:
00189 if (length > session->internals.ia_data_buffer.length)
00190 length = session->internals.ia_data_buffer.length;
00191
00192 MHD__gnutls_buffers_log ("BUF[REC][IA]: Read %d bytes of Data(%d)\n",
00193 length, type);
00194
00195 session->internals.ia_data_buffer.length -= length;
00196 memcpy (data, session->internals.ia_data_buffer.data, length);
00197
00198
00199 memmove (session->internals.ia_data_buffer.data,
00200 &session->internals.ia_data_buffer.data[length],
00201 session->internals.ia_data_buffer.length);
00202
00203 break;
00204
00205 default:
00206 MHD_gnutls_assert ();
00207 return GNUTLS_E_INVALID_REQUEST;
00208 }
00209
00210 return length;
00211 }
00212
00213
00214
00215
00216
00217
00218 static ssize_t
00219 MHD__gnutls_read (MHD_gtls_session_t session, void *iptr,
00220 size_t sizeOfPtr, int flags)
00221 {
00222 size_t left;
00223 ssize_t i = 0;
00224 char *ptr = iptr;
00225 unsigned j, x, sum = 0;
00226 MHD_gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;
00227
00228 session->internals.direction = 0;
00229
00230 left = sizeOfPtr;
00231 while (left > 0)
00232 {
00233 session->internals.errnum = 0;
00234 if (session->internals.MHD__gnutls_pull_func == NULL)
00235 {
00236 i =
00237 recv (GNUTLS_POINTER_TO_INT (fd), &ptr[sizeOfPtr - left], left,
00238 flags);
00239 #if HAVE_WINSOCK
00240 if (i < 0)
00241 {
00242 int tmperr = WSAGetLastError ();
00243 switch (tmperr)
00244 {
00245 case WSAEWOULDBLOCK:
00246 session->internals.errnum = EAGAIN;
00247 break;
00248
00249 case WSAEINTR:
00250 session->internals.errnum = EINTR;
00251 break;
00252
00253 default:
00254 session->internals.errnum = EIO;
00255 break;
00256 }
00257 WSASetLastError (tmperr);
00258 }
00259 #endif
00260 }
00261 else
00262 i = session->internals.MHD__gnutls_pull_func (fd,
00263 &ptr[sizeOfPtr - left],
00264 left);
00265
00266 if (i < 0)
00267 {
00268 int err = session->internals.errnum ? session->internals.errnum
00269 : errno;
00270
00271 MHD__gnutls_read_log
00272 ("READ: %d returned from %d, errno=%d gerrno=%d\n", i, fd, errno,
00273 session->internals.errnum);
00274
00275 if (err == EAGAIN || err == EINTR)
00276 {
00277 if (sizeOfPtr - left > 0)
00278 {
00279
00280 MHD__gnutls_read_log ("READ: returning %d bytes from %d\n",
00281 sizeOfPtr - left, fd);
00282
00283 goto finish;
00284 }
00285 MHD_gnutls_assert ();
00286
00287 if (err == EAGAIN)
00288 return GNUTLS_E_AGAIN;
00289 return GNUTLS_E_INTERRUPTED;
00290 }
00291 else
00292 {
00293 MHD_gnutls_assert ();
00294 return GNUTLS_E_PULL_ERROR;
00295 }
00296 }
00297 else
00298 {
00299
00300 MHD__gnutls_read_log ("READ: Got %d bytes from %d\n", i, fd);
00301
00302 if (i == 0)
00303 break;
00304 }
00305
00306 left -= i;
00307
00308 }
00309
00310 finish:
00311
00312 if (MHD__gnutls_log_level >= 7)
00313 {
00314 char line[128];
00315 char tmp[16];
00316
00317 MHD__gnutls_read_log ("READ: read %d bytes from %d\n",
00318 (sizeOfPtr - left), fd);
00319
00320 for (x = 0; x < ((sizeOfPtr - left) / 16) + 1; x++)
00321 {
00322 line[0] = 0;
00323
00324 sprintf (tmp, "%.4x - ", x);
00325 MHD_gtls_str_cat (line, sizeof (line), tmp);
00326
00327 for (j = 0; j < 16; j++)
00328 {
00329 if (sum < (sizeOfPtr - left))
00330 {
00331 sprintf (tmp, "%.2x ", ((unsigned char *) ptr)[sum++]);
00332 MHD_gtls_str_cat (line, sizeof (line), tmp);
00333 }
00334 }
00335 MHD__gnutls_read_log ("%s\n", line);
00336 }
00337 }
00338
00339 return (sizeOfPtr - left);
00340 }
00341
00342 #define RCVLOWAT session->internals.lowat
00343
00344
00345
00346
00347 int
00348 MHD_gtls_io_clear_peeked_data (MHD_gtls_session_t session)
00349 {
00350 char *peekdata;
00351 int ret, sum;
00352
00353 if (session->internals.have_peeked_data == 0 || RCVLOWAT == 0)
00354 return 0;
00355
00356 peekdata = MHD_gnutls_alloca (RCVLOWAT);
00357 if (peekdata == NULL)
00358 {
00359 MHD_gnutls_assert ();
00360 return GNUTLS_E_MEMORY_ERROR;
00361 }
00362
00363
00364 sum = 0;
00365 do
00366 {
00367 ret = MHD__gnutls_read (session, peekdata, RCVLOWAT - sum, 0);
00368 if (ret > 0)
00369 sum += ret;
00370 }
00371 while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN || sum
00372 < RCVLOWAT);
00373
00374 MHD_gnutls_afree (peekdata);
00375
00376 if (ret < 0)
00377 {
00378 MHD_gnutls_assert ();
00379 return ret;
00380 }
00381
00382 session->internals.have_peeked_data = 0;
00383
00384 return 0;
00385 }
00386
00387 void
00388 MHD_gtls_io_clear_read_buffer (MHD_gtls_session_t session)
00389 {
00390 session->internals.record_recv_buffer.length = 0;
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 ssize_t
00403 MHD_gtls_io_read_buffered (MHD_gtls_session_t session, opaque ** iptr,
00404 size_t sizeOfPtr, content_type_t recv_type)
00405 {
00406 ssize_t ret = 0, ret2 = 0;
00407 size_t min;
00408 int buf_pos;
00409 opaque *buf;
00410 int recvlowat;
00411 int recvdata, alloc_size;
00412
00413 *iptr = session->internals.record_recv_buffer.data;
00414
00415 if (sizeOfPtr > MAX_RECV_SIZE || sizeOfPtr == 0)
00416 {
00417 MHD_gnutls_assert ();
00418 return GNUTLS_E_INVALID_REQUEST;
00419 }
00420
00421
00422
00423
00424 if (session->internals.MHD__gnutls_pull_func != NULL)
00425 {
00426 recvlowat = 0;
00427 }
00428 else
00429 {
00430
00431
00432
00433
00434 if (recv_type != GNUTLS_APPLICATION_DATA
00435 && session->internals.have_peeked_data == 0)
00436 recvlowat = 0;
00437 else
00438 recvlowat = RCVLOWAT;
00439 }
00440
00441
00442
00443
00444 min = MIN (session->internals.record_recv_buffer.length, sizeOfPtr);
00445 if (min > 0)
00446 {
00447
00448
00449
00450 if (min == sizeOfPtr)
00451 {
00452 return min;
00453 }
00454 }
00455
00456
00457
00458
00459 recvdata = sizeOfPtr - min;
00460
00461
00462
00463
00464 if ((session->internals.record_recv_buffer.length + recvdata)
00465 > MAX_RECV_SIZE)
00466 {
00467 MHD_gnutls_assert ();
00468 return GNUTLS_E_INVALID_REQUEST;
00469 }
00470
00471
00472
00473 alloc_size = recvdata + session->internals.record_recv_buffer.length;
00474 session->internals.record_recv_buffer.data =
00475 MHD_gtls_realloc_fast (session->internals.record_recv_buffer.data,
00476 alloc_size);
00477 if (session->internals.record_recv_buffer.data == NULL)
00478 {
00479 MHD_gnutls_assert ();
00480 return GNUTLS_E_MEMORY_ERROR;
00481 }
00482
00483 buf_pos = session->internals.record_recv_buffer.length;
00484 buf = session->internals.record_recv_buffer.data;
00485 *iptr = buf;
00486
00487
00488 if (recvdata - recvlowat > 0)
00489 {
00490 ret =
00491 MHD__gnutls_read (session, &buf[buf_pos], recvdata - recvlowat, 0);
00492
00493
00494
00495
00496 if (ret < 0 && MHD_gtls_error_is_fatal (ret) == 0)
00497 {
00498 return ret;
00499 }
00500 }
00501
00502
00503
00504 if (ret > 0)
00505 {
00506 MHD__gnutls_read_log
00507 ("RB: Have %d bytes into buffer. Adding %d bytes.\n",
00508 session->internals.record_recv_buffer.length, ret);
00509 MHD__gnutls_read_log ("RB: Requested %d bytes\n", sizeOfPtr);
00510 session->internals.record_recv_buffer.length += ret;
00511 }
00512
00513 buf_pos = session->internals.record_recv_buffer.length;
00514
00515
00516
00517
00518
00519
00520 if (ret == (recvdata - recvlowat) && recvlowat > 0)
00521 {
00522 ret2 = MHD__gnutls_read (session, &buf[buf_pos], recvlowat, MSG_PEEK);
00523
00524 if (ret2 < 0 && MHD_gtls_error_is_fatal (ret2) == 0)
00525 {
00526 return ret2;
00527 }
00528
00529 if (ret2 > 0)
00530 {
00531 MHD__gnutls_read_log ("RB-PEEK: Read %d bytes in PEEK MODE.\n",
00532 ret2);
00533 MHD__gnutls_read_log
00534 ("RB-PEEK: Have %d bytes into buffer. Adding %d bytes.\nRB: Requested %d bytes\n",
00535 session->internals.record_recv_buffer.length, ret2, sizeOfPtr);
00536 session->internals.have_peeked_data = 1;
00537 session->internals.record_recv_buffer.length += ret2;
00538
00539 }
00540 }
00541
00542 if (ret < 0 || ret2 < 0)
00543 {
00544 MHD_gnutls_assert ();
00545
00546 return MIN (ret, ret2);
00547 }
00548
00549 ret += ret2;
00550
00551 if (ret > 0 && ret < recvlowat)
00552 {
00553 MHD_gnutls_assert ();
00554 return GNUTLS_E_AGAIN;
00555 }
00556
00557 if (ret == 0)
00558 {
00559 MHD_gnutls_assert ();
00560 return 0;
00561 }
00562
00563 ret = session->internals.record_recv_buffer.length;
00564
00565 if ((ret > 0) && ((size_t) ret < sizeOfPtr))
00566 {
00567
00568 MHD_gnutls_assert ();
00569 return GNUTLS_E_AGAIN;
00570 }
00571 else
00572 {
00573 return ret;
00574 }
00575 }
00576
00577
00578
00579
00580
00581
00582 #define MEMSUB(x,y) ((ssize_t)((ptrdiff_t)x-(ptrdiff_t)y))
00583
00584 inline static int
00585 MHD__gnutls_buffer_insert (MHD_gtls_buffer * buffer,
00586 const opaque * _data, size_t data_size)
00587 {
00588
00589 if ((MEMSUB (_data, buffer->data) >= 0)
00590 && (MEMSUB (_data, buffer->data) < (ssize_t) buffer->length))
00591 {
00592
00593
00594 if (data_size > buffer->length)
00595 {
00596 MHD_gnutls_assert ();
00597
00598 return GNUTLS_E_INTERNAL_ERROR;
00599 }
00600
00601 if (_data == buffer->data)
00602 {
00603 buffer->length = data_size;
00604 return 0;
00605 }
00606
00607 memmove (buffer->data, _data, data_size);
00608 buffer->length = data_size;
00609
00610 return 0;
00611
00612 }
00613
00614 if (MHD_gtls_buffer_append (buffer, _data, data_size) < 0)
00615 {
00616 MHD_gnutls_assert ();
00617 return GNUTLS_E_MEMORY_ERROR;
00618 }
00619
00620 return 0;
00621 }
00622
00623 inline static int
00624 MHD__gnutls_buffer_get (MHD_gtls_buffer * buffer,
00625 const opaque ** ptr, size_t * ptr_size)
00626 {
00627 *ptr_size = buffer->length;
00628 *ptr = buffer->data;
00629
00630 return 0;
00631 }
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 ssize_t
00645 MHD_gtls_io_write_buffered (MHD_gtls_session_t session,
00646 const void *iptr, size_t n)
00647 {
00648 size_t left;
00649 unsigned j, x, sum = 0;
00650 ssize_t retval, i;
00651 const opaque *ptr;
00652 int ret;
00653 MHD_gnutls_transport_ptr_t fd = session->internals.transport_send_ptr;
00654
00655
00656
00657 session->internals.direction = 1;
00658
00659 ptr = iptr;
00660
00661
00662
00663
00664
00665 if (session->internals.record_send_buffer.length > 0 && iptr != NULL)
00666 {
00667 MHD_gnutls_assert ();
00668 return GNUTLS_E_INVALID_REQUEST;
00669 }
00670
00671
00672
00673 if (iptr == NULL)
00674 {
00675
00676 ret =
00677 MHD__gnutls_buffer_get (&session->internals.record_send_buffer, &ptr,
00678 &n);
00679 if (ret < 0)
00680 {
00681 MHD_gnutls_assert ();
00682 return ret;
00683 }
00684
00685 MHD__gnutls_write_log
00686 ("WRITE: Restoring old write. (%d bytes to send)\n", n);
00687 }
00688
00689 MHD__gnutls_write_log ("WRITE: Will write %d bytes to %d.\n", n, fd);
00690
00691 i = 0;
00692 left = n;
00693 while (left > 0)
00694 {
00695
00696 session->internals.errnum = 0;
00697
00698 if (session->internals.MHD__gnutls_push_func == NULL)
00699 {
00700 i = send (GNUTLS_POINTER_TO_INT (fd), &ptr[n - left], left, 0);
00701 #if HAVE_WINSOCK
00702 if (i < 0)
00703 {
00704 int tmperr = WSAGetLastError ();
00705 switch (tmperr)
00706 {
00707 case WSAEWOULDBLOCK:
00708 session->internals.errnum = EAGAIN;
00709 break;
00710
00711 case WSAEINTR:
00712 session->internals.errnum = EINTR;
00713 break;
00714
00715 default:
00716 session->internals.errnum = EIO;
00717 break;
00718 }
00719 WSASetLastError (tmperr);
00720 }
00721 #endif
00722 }
00723 else
00724 i =
00725 session->internals.MHD__gnutls_push_func (fd, &ptr[n - left], left);
00726
00727 if (i == -1)
00728 {
00729 int err = session->internals.errnum ? session->internals.errnum
00730 : errno;
00731
00732 if (err == EAGAIN || err == EINTR)
00733 {
00734 session->internals.record_send_buffer_prev_size += n - left;
00735
00736 retval =
00737 MHD__gnutls_buffer_insert (&session->
00738 internals.record_send_buffer,
00739 &ptr[n - left], left);
00740 if (retval < 0)
00741 {
00742 MHD_gnutls_assert ();
00743 return retval;
00744 }
00745
00746 MHD__gnutls_write_log
00747 ("WRITE: Interrupted. Stored %d bytes to buffer. Already sent %d bytes.\n",
00748 left, n - left);
00749
00750 if (err == EAGAIN)
00751 return GNUTLS_E_AGAIN;
00752 return GNUTLS_E_INTERRUPTED;
00753 }
00754 else
00755 {
00756 MHD_gnutls_assert ();
00757 return GNUTLS_E_PUSH_ERROR;
00758 }
00759 }
00760 left -= i;
00761
00762 if (MHD__gnutls_log_level >= 7)
00763 {
00764 char line[128];
00765 char tmp[16];
00766
00767 MHD__gnutls_write_log
00768 ("WRITE: wrote %d bytes to %d. Left %d bytes. Total %d bytes.\n",
00769 i, fd, left, n);
00770 for (x = 0; x < (unsigned) ((i) / 16) + 1; x++)
00771 {
00772 line[0] = 0;
00773
00774 if (sum > n - left)
00775 break;
00776
00777 sprintf (tmp, "%.4x - ", x);
00778 MHD_gtls_str_cat (line, sizeof (line), tmp);
00779
00780 for (j = 0; j < 16; j++)
00781 {
00782 if (sum < n - left)
00783 {
00784 sprintf (tmp, "%.2x ", ((unsigned char *) ptr)[sum++]);
00785 MHD_gtls_str_cat (line, sizeof (line), tmp);
00786 }
00787 else
00788 break;
00789 }
00790 MHD__gnutls_write_log ("%s\n", line);
00791 }
00792 }
00793 }
00794
00795 retval = n + session->internals.record_send_buffer_prev_size;
00796
00797 session->internals.record_send_buffer.length = 0;
00798 session->internals.record_send_buffer_prev_size = 0;
00799
00800 return retval;
00801
00802 }
00803
00804
00805
00806
00807
00808 ssize_t
00809 MHD_gtls_io_write_flush (MHD_gtls_session_t session)
00810 {
00811 ssize_t ret;
00812
00813 if (session->internals.record_send_buffer.length == 0)
00814 return 0;
00815
00816 ret = MHD_gtls_io_write_buffered (session, NULL, 0);
00817 MHD__gnutls_write_log ("WRITE FLUSH: %d [buffer: %d]\n", ret,
00818 session->internals.record_send_buffer.length);
00819
00820 return ret;
00821 }
00822
00823
00824
00825
00826
00827 ssize_t
00828 MHD_gtls_handshake_io_write_flush (MHD_gtls_session_t session)
00829 {
00830 ssize_t ret;
00831 ret = MHD_gtls_handshake_io_send_int (session, 0, 0, NULL, 0);
00832 if (ret < 0)
00833 {
00834 MHD_gnutls_assert ();
00835 return ret;
00836 }
00837
00838 MHD__gnutls_write_log ("HANDSHAKE_FLUSH: written[1] %d bytes\n", ret);
00839
00840 if (session->internals.handshake_send_buffer.length == 0)
00841 {
00842 ret = session->internals.handshake_send_buffer_prev_size;
00843 session->internals.handshake_send_buffer_prev_size = 0;
00844 }
00845
00846 return ret;
00847 }
00848
00849
00850
00851
00852 ssize_t
00853 MHD_gtls_handshake_io_send_int (MHD_gtls_session_t session,
00854 content_type_t type,
00855 MHD_gnutls_handshake_description_t htype,
00856 const void *iptr, size_t n)
00857 {
00858 size_t left;
00859 ssize_t ret = 0;
00860 const opaque *ptr;
00861 ssize_t retval = 0;
00862
00863 ptr = iptr;
00864
00865 if (session->internals.handshake_send_buffer.length > 0 && ptr == NULL && n
00866 == 0)
00867 {
00868
00869
00870 MHD_gnutls_assert ();
00871 ret = MHD__gnutls_buffer_get (&session->internals.handshake_send_buffer,
00872 &ptr, &n);
00873 if (ret < 0)
00874 {
00875 MHD_gnutls_assert ();
00876 return retval;
00877 }
00878
00879 type = session->internals.handshake_send_buffer_type;
00880 htype = session->internals.handshake_send_buffer_htype;
00881
00882 }
00883 else if (session->internals.handshake_send_buffer.length > 0)
00884 {
00885 MHD_gnutls_assert ();
00886 return GNUTLS_E_INTERNAL_ERROR;
00887 }
00888 #ifdef WRITE_DEBUG
00889 else
00890 {
00891 size_t sum = 0, x, j;
00892
00893 MHD__gnutls_write_log ("HWRITE: will write %d bytes to %d.\n", n,
00894 MHD_gnutls_transport_get_ptr (session));
00895 for (x = 0; x < ((n) / 16) + 1; x++)
00896 {
00897 if (sum > n)
00898 break;
00899
00900 MHD__gnutls_write_log ("%.4x - ", x);
00901 for (j = 0; j < 16; j++)
00902 {
00903 if (sum < n)
00904 {
00905 MHD__gnutls_write_log ("%.2x ",
00906 ((unsigned char *) ptr)[sum++]);
00907 }
00908 else
00909 break;
00910 }
00911 MHD__gnutls_write_log ("\n");
00912 }
00913 MHD__gnutls_write_log ("\n");
00914 }
00915 #endif
00916
00917 if (n == 0)
00918 {
00919 MHD_gnutls_assert ();
00920 return 0;
00921 }
00922 else if (ptr == NULL)
00923 {
00924 MHD_gnutls_assert ();
00925 return GNUTLS_E_INTERNAL_ERROR;
00926 }
00927
00928 left = n;
00929 while (left > 0)
00930 {
00931 ret = MHD_gtls_send_int (session, type, htype, &ptr[n - left], left);
00932
00933 if (ret <= 0)
00934 {
00935 if (ret == 0)
00936 {
00937 MHD_gnutls_assert ();
00938 ret = GNUTLS_E_INTERNAL_ERROR;
00939 }
00940
00941 if (left > 0 && (ret == GNUTLS_E_INTERRUPTED || ret
00942 == GNUTLS_E_AGAIN))
00943 {
00944 MHD_gnutls_assert ();
00945
00946 retval =
00947 MHD__gnutls_buffer_insert (&session->internals.
00948 handshake_send_buffer,
00949 &ptr[n - left], left);
00950 if (retval < 0)
00951 {
00952 MHD_gnutls_assert ();
00953 return retval;
00954 }
00955
00956 session->internals.handshake_send_buffer_prev_size += n - left;
00957
00958 session->internals.handshake_send_buffer_type = type;
00959 session->internals.handshake_send_buffer_htype = htype;
00960
00961 }
00962 else
00963 {
00964 session->internals.handshake_send_buffer_prev_size = 0;
00965 session->internals.handshake_send_buffer.length = 0;
00966 }
00967
00968 MHD_gnutls_assert ();
00969 return ret;
00970 }
00971 left -= ret;
00972 }
00973
00974 retval = n + session->internals.handshake_send_buffer_prev_size;
00975
00976 session->internals.handshake_send_buffer.length = 0;
00977 session->internals.handshake_send_buffer_prev_size = 0;
00978
00979 return retval;
00980
00981 }
00982
00983
00984
00985
00986 ssize_t
00987 MHD_gtls_handshake_io_recv_int (MHD_gtls_session_t session,
00988 content_type_t type,
00989 MHD_gnutls_handshake_description_t htype,
00990 void *iptr, size_t sizeOfPtr)
00991 {
00992 size_t left;
00993 ssize_t i;
00994 opaque *ptr;
00995 size_t dsize;
00996
00997 ptr = iptr;
00998 left = sizeOfPtr;
00999
01000 if (sizeOfPtr == 0 || iptr == NULL)
01001 {
01002 MHD_gnutls_assert ();
01003 return GNUTLS_E_INVALID_REQUEST;
01004 }
01005
01006 if (session->internals.handshake_recv_buffer.length > 0)
01007 {
01008
01009 if (sizeOfPtr <= session->internals.handshake_recv_buffer.length)
01010 {
01011
01012
01013 MHD_gnutls_assert ();
01014 memcpy (iptr, session->internals.handshake_recv_buffer.data,
01015 sizeOfPtr);
01016
01017 session->internals.handshake_recv_buffer.length -= sizeOfPtr;
01018
01019 memmove (session->internals.handshake_recv_buffer.data,
01020 &session->internals.handshake_recv_buffer.data[sizeOfPtr],
01021 session->internals.handshake_recv_buffer.length);
01022
01023 return sizeOfPtr;
01024 }
01025 MHD_gnutls_assert ();
01026 memcpy (iptr, session->internals.handshake_recv_buffer.data,
01027 session->internals.handshake_recv_buffer.length);
01028
01029 htype = session->internals.handshake_recv_buffer_htype;
01030 type = session->internals.handshake_recv_buffer_type;
01031
01032 left -= session->internals.handshake_recv_buffer.length;
01033
01034 session->internals.handshake_recv_buffer.length = 0;
01035 }
01036
01037 while (left > 0)
01038 {
01039 dsize = sizeOfPtr - left;
01040 i = MHD_gtls_recv_int (session, type, htype, &ptr[dsize], left);
01041 if (i < 0)
01042 {
01043
01044 if (dsize > 0 && (i == GNUTLS_E_INTERRUPTED || i == GNUTLS_E_AGAIN))
01045 {
01046 MHD_gnutls_assert ();
01047
01048 session->internals.handshake_recv_buffer.data
01049 =
01050 MHD_gtls_realloc_fast (session->internals.
01051 handshake_recv_buffer.data, dsize);
01052 if (session->internals.handshake_recv_buffer.data == NULL)
01053 {
01054 MHD_gnutls_assert ();
01055 return GNUTLS_E_MEMORY_ERROR;
01056 }
01057
01058 memcpy (session->internals.handshake_recv_buffer.data, iptr,
01059 dsize);
01060
01061 session->internals.handshake_recv_buffer_htype = htype;
01062 session->internals.handshake_recv_buffer_type = type;
01063
01064 session->internals.handshake_recv_buffer.length = dsize;
01065 }
01066 else
01067 session->internals.handshake_recv_buffer.length = 0;
01068
01069 MHD_gnutls_assert ();
01070
01071 return i;
01072 }
01073 else
01074 {
01075 if (i == 0)
01076 break;
01077 }
01078
01079 left -= i;
01080
01081 }
01082
01083 session->internals.handshake_recv_buffer.length = 0;
01084
01085 return sizeOfPtr - left;
01086 }
01087
01088
01089
01090
01091
01092 int
01093 MHD_gtls_handshake_buffer_put (MHD_gtls_session_t session, opaque * data,
01094 size_t length)
01095 {
01096
01097 if (length == 0)
01098 return 0;
01099
01100 if ((session->internals.max_handshake_data_buffer_size > 0) && ((length
01101 +
01102 session->
01103 internals.
01104 handshake_hash_buffer.
01105 length) >
01106 session->
01107 internals.
01108 max_handshake_data_buffer_size))
01109 {
01110 MHD_gnutls_assert ();
01111 return GNUTLS_E_MEMORY_ERROR;
01112 }
01113
01114 MHD__gnutls_buffers_log ("BUF[HSK]: Inserted %d bytes of Data\n", length);
01115
01116 if (MHD_gtls_buffer_append (&session->internals.handshake_hash_buffer, data,
01117 length) < 0)
01118 {
01119 MHD_gnutls_assert ();
01120 return GNUTLS_E_MEMORY_ERROR;
01121 }
01122
01123 return 0;
01124 }
01125
01126
01127
01128
01129 int
01130 MHD_gtls_handshake_buffer_get_ptr (MHD_gtls_session_t session,
01131 opaque ** data_ptr, size_t * length)
01132 {
01133 if (length != NULL)
01134 *length = session->internals.handshake_hash_buffer.length;
01135
01136 MHD__gnutls_buffers_log ("BUF[HSK]: Peeked %d bytes of Data\n",
01137 session->internals.handshake_hash_buffer.length);
01138
01139 if (data_ptr != NULL)
01140 *data_ptr = session->internals.handshake_hash_buffer.data;
01141
01142 return 0;
01143 }
01144
01145
01146
01147 int
01148 MHD_gtls_handshake_buffer_empty (MHD_gtls_session_t session)
01149 {
01150
01151 MHD__gnutls_buffers_log ("BUF[HSK]: Emptied buffer\n");
01152
01153 session->internals.handshake_hash_buffer.length = 0;
01154
01155 return 0;
01156 }
01157
01158 int
01159 MHD_gtls_handshake_buffer_clear (MHD_gtls_session_t session)
01160 {
01161 MHD__gnutls_buffers_log ("BUF[HSK]: Cleared Data from buffer\n");
01162 MHD_gtls_buffer_clear (&session->internals.handshake_hash_buffer);
01163 return 0;
01164 }