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 MHD_gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;
00226
00227 session->internals.direction = 0;
00228
00229 left = sizeOfPtr;
00230 while (left > 0)
00231 {
00232 session->internals.errnum = 0;
00233 if (session->internals.MHD__gnutls_pull_func == NULL)
00234 {
00235 i =
00236 recv (GNUTLS_POINTER_TO_INT (fd), &ptr[sizeOfPtr - left], left,
00237 flags);
00238 #if HAVE_WINSOCK
00239 if (i < 0)
00240 {
00241 int tmperr = WSAGetLastError ();
00242 switch (tmperr)
00243 {
00244 case WSAEWOULDBLOCK:
00245 session->internals.errnum = EAGAIN;
00246 break;
00247
00248 case WSAEINTR:
00249 session->internals.errnum = EINTR;
00250 break;
00251
00252 default:
00253 session->internals.errnum = EIO;
00254 break;
00255 }
00256 WSASetLastError (tmperr);
00257 }
00258 #endif
00259 }
00260 else
00261 i = session->internals.MHD__gnutls_pull_func (fd,
00262 &ptr[sizeOfPtr - left],
00263 left);
00264 if (i < 0)
00265 {
00266 int err = session->internals.errnum ? session->internals.errnum
00267 : errno;
00268 if ( (err == EAGAIN) || (err == EINTR) )
00269 {
00270 if (sizeOfPtr - left > 0)
00271 goto finish;
00272 MHD_gnutls_assert ();
00273 if (err == EAGAIN)
00274 return GNUTLS_E_AGAIN;
00275 return GNUTLS_E_INTERRUPTED;
00276 }
00277 else
00278 {
00279 MHD_gnutls_assert ();
00280 return GNUTLS_E_PULL_ERROR;
00281 }
00282 }
00283 else
00284 {
00285 if (i == 0)
00286 break;
00287 }
00288 left -= i;
00289 }
00290
00291 finish:
00292 return (sizeOfPtr - left);
00293 }
00294
00295 #define RCVLOWAT session->internals.lowat
00296
00297
00298
00299
00300 int
00301 MHD_gtls_io_clear_peeked_data (MHD_gtls_session_t session)
00302 {
00303 char *peekdata;
00304 int ret, sum;
00305
00306 if (session->internals.have_peeked_data == 0 || RCVLOWAT == 0)
00307 return 0;
00308
00309 peekdata = MHD_gnutls_alloca (RCVLOWAT);
00310 if (peekdata == NULL)
00311 {
00312 MHD_gnutls_assert ();
00313 return GNUTLS_E_MEMORY_ERROR;
00314 }
00315
00316
00317 sum = 0;
00318 do
00319 {
00320 ret = MHD__gnutls_read (session, peekdata, RCVLOWAT - sum, 0);
00321 if (ret > 0)
00322 sum += ret;
00323 }
00324 while ( (ret == GNUTLS_E_INTERRUPTED) ||
00325 (ret == GNUTLS_E_AGAIN) ||
00326 (sum < RCVLOWAT) );
00327
00328 MHD_gnutls_afree (peekdata);
00329
00330 if (ret < 0)
00331 {
00332 MHD_gnutls_assert ();
00333 return ret;
00334 }
00335
00336 session->internals.have_peeked_data = 0;
00337
00338 return 0;
00339 }
00340
00341 void
00342 MHD_gtls_io_clear_read_buffer (MHD_gtls_session_t session)
00343 {
00344 session->internals.record_recv_buffer.length = 0;
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 ssize_t
00357 MHD_gtls_io_read_buffered (MHD_gtls_session_t session, opaque ** iptr,
00358 size_t sizeOfPtr, content_type_t recv_type)
00359 {
00360 ssize_t ret = 0, ret2 = 0;
00361 size_t min;
00362 int buf_pos;
00363 opaque *buf;
00364 int recvlowat;
00365 int recvdata, alloc_size;
00366
00367 *iptr = session->internals.record_recv_buffer.data;
00368
00369 if (sizeOfPtr > MAX_RECV_SIZE || sizeOfPtr == 0)
00370 {
00371 MHD_gnutls_assert ();
00372 return GNUTLS_E_INVALID_REQUEST;
00373 }
00374
00375
00376
00377
00378 if (session->internals.MHD__gnutls_pull_func != NULL)
00379 {
00380 recvlowat = 0;
00381 }
00382 else
00383 {
00384
00385
00386
00387
00388 if (recv_type != GNUTLS_APPLICATION_DATA
00389 && session->internals.have_peeked_data == 0)
00390 recvlowat = 0;
00391 else
00392 recvlowat = RCVLOWAT;
00393 }
00394
00395
00396
00397
00398 min = MIN (session->internals.record_recv_buffer.length, sizeOfPtr);
00399 if (min > 0)
00400 {
00401
00402
00403
00404 if (min == sizeOfPtr)
00405 {
00406 return min;
00407 }
00408 }
00409
00410
00411
00412
00413 recvdata = sizeOfPtr - min;
00414
00415
00416
00417
00418 if ((session->internals.record_recv_buffer.length + recvdata)
00419 > MAX_RECV_SIZE)
00420 {
00421 MHD_gnutls_assert ();
00422 return GNUTLS_E_INVALID_REQUEST;
00423 }
00424
00425
00426
00427 alloc_size = recvdata + session->internals.record_recv_buffer.length;
00428 session->internals.record_recv_buffer.data =
00429 MHD_gtls_realloc_fast (session->internals.record_recv_buffer.data,
00430 alloc_size);
00431 if (session->internals.record_recv_buffer.data == NULL)
00432 {
00433 MHD_gnutls_assert ();
00434 return GNUTLS_E_MEMORY_ERROR;
00435 }
00436
00437 buf_pos = session->internals.record_recv_buffer.length;
00438 buf = session->internals.record_recv_buffer.data;
00439 *iptr = buf;
00440
00441
00442 if (recvdata - recvlowat > 0)
00443 {
00444 ret =
00445 MHD__gnutls_read (session, &buf[buf_pos], recvdata - recvlowat, 0);
00446
00447
00448
00449
00450 if (ret < 0 && MHD_gtls_error_is_fatal (ret) == 0)
00451 {
00452 return ret;
00453 }
00454 }
00455
00456
00457
00458 if (ret > 0)
00459 {
00460 MHD__gnutls_read_log
00461 ("RB: Have %d bytes into buffer. Adding %d bytes.\n",
00462 session->internals.record_recv_buffer.length, ret);
00463 MHD__gnutls_read_log ("RB: Requested %d bytes\n", sizeOfPtr);
00464 session->internals.record_recv_buffer.length += ret;
00465 }
00466
00467 buf_pos = session->internals.record_recv_buffer.length;
00468
00469
00470
00471
00472
00473
00474 if (ret == (recvdata - recvlowat) && recvlowat > 0)
00475 {
00476 ret2 = MHD__gnutls_read (session, &buf[buf_pos], recvlowat, MSG_PEEK);
00477
00478 if (ret2 < 0 && MHD_gtls_error_is_fatal (ret2) == 0)
00479 {
00480 return ret2;
00481 }
00482
00483 if (ret2 > 0)
00484 {
00485 MHD__gnutls_read_log ("RB-PEEK: Read %d bytes in PEEK MODE.\n",
00486 ret2);
00487 MHD__gnutls_read_log
00488 ("RB-PEEK: Have %d bytes into buffer. Adding %d bytes.\nRB: Requested %d bytes\n",
00489 session->internals.record_recv_buffer.length, ret2, sizeOfPtr);
00490 session->internals.have_peeked_data = 1;
00491 session->internals.record_recv_buffer.length += ret2;
00492
00493 }
00494 }
00495
00496 if (ret < 0 || ret2 < 0)
00497 {
00498 MHD_gnutls_assert ();
00499
00500 return MIN (ret, ret2);
00501 }
00502
00503 ret += ret2;
00504
00505 if (ret > 0 && ret < recvlowat)
00506 {
00507 MHD_gnutls_assert ();
00508 return GNUTLS_E_AGAIN;
00509 }
00510
00511 if (ret == 0)
00512 {
00513 MHD_gnutls_assert ();
00514 return 0;
00515 }
00516
00517 ret = session->internals.record_recv_buffer.length;
00518
00519 if ((ret > 0) && ((size_t) ret < sizeOfPtr))
00520 {
00521
00522 MHD_gnutls_assert ();
00523 return GNUTLS_E_AGAIN;
00524 }
00525 else
00526 {
00527 return ret;
00528 }
00529 }
00530
00531
00532
00533
00534
00535
00536 #define MEMSUB(x,y) ((ssize_t)((ptrdiff_t)x-(ptrdiff_t)y))
00537
00538 inline static int
00539 MHD__gnutls_buffer_insert (MHD_gtls_buffer * buffer,
00540 const opaque * _data, size_t data_size)
00541 {
00542
00543 if ((MEMSUB (_data, buffer->data) >= 0)
00544 && (MEMSUB (_data, buffer->data) < (ssize_t) buffer->length))
00545 {
00546
00547
00548 if (data_size > buffer->length)
00549 {
00550 MHD_gnutls_assert ();
00551
00552 return GNUTLS_E_INTERNAL_ERROR;
00553 }
00554
00555 if (_data == buffer->data)
00556 {
00557 buffer->length = data_size;
00558 return 0;
00559 }
00560
00561 memmove (buffer->data, _data, data_size);
00562 buffer->length = data_size;
00563
00564 return 0;
00565
00566 }
00567
00568 if (MHD_gtls_buffer_append (buffer, _data, data_size) < 0)
00569 {
00570 MHD_gnutls_assert ();
00571 return GNUTLS_E_MEMORY_ERROR;
00572 }
00573
00574 return 0;
00575 }
00576
00577 inline static int
00578 MHD__gnutls_buffer_get (MHD_gtls_buffer * buffer,
00579 const opaque ** ptr, size_t * ptr_size)
00580 {
00581 *ptr_size = buffer->length;
00582 *ptr = buffer->data;
00583
00584 return 0;
00585 }
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 ssize_t
00599 MHD_gtls_io_write_buffered (MHD_gtls_session_t session,
00600 const void *iptr, size_t n)
00601 {
00602 size_t left;
00603 unsigned j, x, sum = 0;
00604 ssize_t retval, i;
00605 const opaque *ptr;
00606 int ret;
00607 MHD_gnutls_transport_ptr_t fd = session->internals.transport_send_ptr;
00608
00609
00610
00611 session->internals.direction = 1;
00612
00613 ptr = iptr;
00614
00615
00616
00617
00618
00619 if (session->internals.record_send_buffer.length > 0 && iptr != NULL)
00620 {
00621 MHD_gnutls_assert ();
00622 return GNUTLS_E_INVALID_REQUEST;
00623 }
00624
00625
00626
00627 if (iptr == NULL)
00628 {
00629
00630 ret =
00631 MHD__gnutls_buffer_get (&session->internals.record_send_buffer, &ptr,
00632 &n);
00633 if (ret < 0)
00634 {
00635 MHD_gnutls_assert ();
00636 return ret;
00637 }
00638
00639 MHD__gnutls_write_log
00640 ("WRITE: Restoring old write. (%d bytes to send)\n", n);
00641 }
00642
00643 MHD__gnutls_write_log ("WRITE: Will write %d bytes to %d.\n", n, fd);
00644
00645 i = 0;
00646 left = n;
00647 while (left > 0)
00648 {
00649
00650 session->internals.errnum = 0;
00651
00652 if (session->internals.MHD__gnutls_push_func == NULL)
00653 {
00654 i = send (GNUTLS_POINTER_TO_INT (fd), &ptr[n - left], left, 0);
00655 #if HAVE_WINSOCK
00656 if (i < 0)
00657 {
00658 int tmperr = WSAGetLastError ();
00659 switch (tmperr)
00660 {
00661 case WSAEWOULDBLOCK:
00662 session->internals.errnum = EAGAIN;
00663 break;
00664
00665 case WSAEINTR:
00666 session->internals.errnum = EINTR;
00667 break;
00668
00669 default:
00670 session->internals.errnum = EIO;
00671 break;
00672 }
00673 WSASetLastError (tmperr);
00674 }
00675 #endif
00676 }
00677 else
00678 i = session->internals.MHD__gnutls_push_func (fd, &ptr[n - left], left);
00679 if (i == -1)
00680 {
00681 int err = session->internals.errnum ? session->internals.errnum
00682 : errno;
00683
00684 if ( (err == EAGAIN) || (err == EINTR) )
00685 {
00686 session->internals.record_send_buffer_prev_size += n - left;
00687
00688 retval =
00689 MHD__gnutls_buffer_insert (&session->
00690 internals.record_send_buffer,
00691 &ptr[n - left], left);
00692 if (retval < 0)
00693 {
00694 MHD_gnutls_assert ();
00695 return retval;
00696 }
00697 if (err == EAGAIN)
00698 return GNUTLS_E_AGAIN;
00699 return GNUTLS_E_INTERRUPTED;
00700 }
00701 else
00702 {
00703 MHD_gnutls_assert ();
00704 return GNUTLS_E_PUSH_ERROR;
00705 }
00706 }
00707 left -= i;
00708
00709 if (MHD__gnutls_log_level >= 7)
00710 {
00711 char line[128];
00712 char tmp[16];
00713
00714 MHD__gnutls_write_log
00715 ("WRITE: wrote %d bytes to %d. Left %d bytes. Total %d bytes.\n",
00716 i, fd, left, n);
00717 for (x = 0; x < (unsigned) ((i) / 16) + 1; x++)
00718 {
00719 line[0] = 0;
00720
00721 if (sum > n - left)
00722 break;
00723
00724 sprintf (tmp, "%.4x - ", x);
00725 MHD_gtls_str_cat (line, sizeof (line), tmp);
00726
00727 for (j = 0; j < 16; j++)
00728 {
00729 if (sum < n - left)
00730 {
00731 sprintf (tmp, "%.2x ", ((unsigned char *) ptr)[sum++]);
00732 MHD_gtls_str_cat (line, sizeof (line), tmp);
00733 }
00734 else
00735 break;
00736 }
00737 MHD__gnutls_write_log ("%s\n", line);
00738 }
00739 }
00740 }
00741
00742 retval = n + session->internals.record_send_buffer_prev_size;
00743
00744 session->internals.record_send_buffer.length = 0;
00745 session->internals.record_send_buffer_prev_size = 0;
00746
00747 return retval;
00748
00749 }
00750
00751
00752
00753
00754
00755 ssize_t
00756 MHD_gtls_io_write_flush (MHD_gtls_session_t session)
00757 {
00758 ssize_t ret;
00759
00760 if (session->internals.record_send_buffer.length == 0)
00761 return 0;
00762
00763 ret = MHD_gtls_io_write_buffered (session, NULL, 0);
00764 MHD__gnutls_write_log ("WRITE FLUSH: %d [buffer: %d]\n", ret,
00765 session->internals.record_send_buffer.length);
00766
00767 return ret;
00768 }
00769
00770
00771
00772
00773
00774 ssize_t
00775 MHD_gtls_handshake_io_write_flush (MHD_gtls_session_t session)
00776 {
00777 ssize_t ret;
00778 ret = MHD_gtls_handshake_io_send_int (session, 0, 0, NULL, 0);
00779 if (ret < 0)
00780 {
00781 MHD_gnutls_assert ();
00782 return ret;
00783 }
00784
00785 MHD__gnutls_write_log ("HANDSHAKE_FLUSH: written[1] %d bytes\n", ret);
00786
00787 if (session->internals.handshake_send_buffer.length == 0)
00788 {
00789 ret = session->internals.handshake_send_buffer_prev_size;
00790 session->internals.handshake_send_buffer_prev_size = 0;
00791 }
00792
00793 return ret;
00794 }
00795
00796
00797
00798
00799 ssize_t
00800 MHD_gtls_handshake_io_send_int (MHD_gtls_session_t session,
00801 content_type_t type,
00802 MHD_gnutls_handshake_description_t htype,
00803 const void *iptr, size_t n)
00804 {
00805 size_t left;
00806 ssize_t ret = 0;
00807 const opaque *ptr;
00808 ssize_t retval = 0;
00809
00810 ptr = iptr;
00811
00812 if (session->internals.handshake_send_buffer.length > 0 && ptr == NULL && n
00813 == 0)
00814 {
00815
00816
00817 MHD_gnutls_assert ();
00818 ret = MHD__gnutls_buffer_get (&session->internals.handshake_send_buffer,
00819 &ptr, &n);
00820 if (ret < 0)
00821 {
00822 MHD_gnutls_assert ();
00823 return retval;
00824 }
00825
00826 type = session->internals.handshake_send_buffer_type;
00827 htype = session->internals.handshake_send_buffer_htype;
00828
00829 }
00830 else if (session->internals.handshake_send_buffer.length > 0)
00831 {
00832 MHD_gnutls_assert ();
00833 return GNUTLS_E_INTERNAL_ERROR;
00834 }
00835 #ifdef WRITE_DEBUG
00836 else
00837 {
00838 size_t sum = 0, x, j;
00839
00840 MHD__gnutls_write_log ("HWRITE: will write %d bytes to %d.\n", n,
00841 MHD_gnutls_transport_get_ptr (session));
00842 for (x = 0; x < ((n) / 16) + 1; x++)
00843 {
00844 if (sum > n)
00845 break;
00846
00847 MHD__gnutls_write_log ("%.4x - ", x);
00848 for (j = 0; j < 16; j++)
00849 {
00850 if (sum < n)
00851 {
00852 MHD__gnutls_write_log ("%.2x ",
00853 ((unsigned char *) ptr)[sum++]);
00854 }
00855 else
00856 break;
00857 }
00858 MHD__gnutls_write_log ("\n");
00859 }
00860 MHD__gnutls_write_log ("\n");
00861 }
00862 #endif
00863
00864 if (n == 0)
00865 {
00866 MHD_gnutls_assert ();
00867 return 0;
00868 }
00869 else if (ptr == NULL)
00870 {
00871 MHD_gnutls_assert ();
00872 return GNUTLS_E_INTERNAL_ERROR;
00873 }
00874
00875 left = n;
00876 while (left > 0)
00877 {
00878 ret = MHD_gtls_send_int (session, type, htype, &ptr[n - left], left);
00879
00880 if (ret <= 0)
00881 {
00882 if (ret == 0)
00883 {
00884 MHD_gnutls_assert ();
00885 ret = GNUTLS_E_INTERNAL_ERROR;
00886 }
00887
00888 if (left > 0 && (ret == GNUTLS_E_INTERRUPTED || ret
00889 == GNUTLS_E_AGAIN))
00890 {
00891 MHD_gnutls_assert ();
00892
00893 retval =
00894 MHD__gnutls_buffer_insert (&session->internals.
00895 handshake_send_buffer,
00896 &ptr[n - left], left);
00897 if (retval < 0)
00898 {
00899 MHD_gnutls_assert ();
00900 return retval;
00901 }
00902
00903 session->internals.handshake_send_buffer_prev_size += n - left;
00904
00905 session->internals.handshake_send_buffer_type = type;
00906 session->internals.handshake_send_buffer_htype = htype;
00907
00908 }
00909 else
00910 {
00911 session->internals.handshake_send_buffer_prev_size = 0;
00912 session->internals.handshake_send_buffer.length = 0;
00913 }
00914
00915 MHD_gnutls_assert ();
00916 return ret;
00917 }
00918 left -= ret;
00919 }
00920
00921 retval = n + session->internals.handshake_send_buffer_prev_size;
00922
00923 session->internals.handshake_send_buffer.length = 0;
00924 session->internals.handshake_send_buffer_prev_size = 0;
00925
00926 return retval;
00927
00928 }
00929
00930
00931
00932
00933 ssize_t
00934 MHD_gtls_handshake_io_recv_int (MHD_gtls_session_t session,
00935 content_type_t type,
00936 MHD_gnutls_handshake_description_t htype,
00937 void *iptr, size_t sizeOfPtr)
00938 {
00939 size_t left;
00940 ssize_t i;
00941 opaque *ptr;
00942 size_t dsize;
00943
00944 ptr = iptr;
00945 left = sizeOfPtr;
00946
00947 if (sizeOfPtr == 0 || iptr == NULL)
00948 {
00949 MHD_gnutls_assert ();
00950 return GNUTLS_E_INVALID_REQUEST;
00951 }
00952
00953 if (session->internals.handshake_recv_buffer.length > 0)
00954 {
00955
00956 if (sizeOfPtr <= session->internals.handshake_recv_buffer.length)
00957 {
00958
00959
00960 MHD_gnutls_assert ();
00961 memcpy (iptr, session->internals.handshake_recv_buffer.data,
00962 sizeOfPtr);
00963
00964 session->internals.handshake_recv_buffer.length -= sizeOfPtr;
00965
00966 memmove (session->internals.handshake_recv_buffer.data,
00967 &session->internals.handshake_recv_buffer.data[sizeOfPtr],
00968 session->internals.handshake_recv_buffer.length);
00969
00970 return sizeOfPtr;
00971 }
00972 MHD_gnutls_assert ();
00973 memcpy (iptr, session->internals.handshake_recv_buffer.data,
00974 session->internals.handshake_recv_buffer.length);
00975
00976 htype = session->internals.handshake_recv_buffer_htype;
00977 type = session->internals.handshake_recv_buffer_type;
00978
00979 left -= session->internals.handshake_recv_buffer.length;
00980
00981 session->internals.handshake_recv_buffer.length = 0;
00982 }
00983
00984 while (left > 0)
00985 {
00986 dsize = sizeOfPtr - left;
00987 i = MHD_gtls_recv_int (session, type, htype, &ptr[dsize], left);
00988 if (i < 0)
00989 {
00990
00991 if (dsize > 0 && (i == GNUTLS_E_INTERRUPTED || i == GNUTLS_E_AGAIN))
00992 {
00993 MHD_gnutls_assert ();
00994
00995 session->internals.handshake_recv_buffer.data
00996 =
00997 MHD_gtls_realloc_fast (session->internals.
00998 handshake_recv_buffer.data, dsize);
00999 if (session->internals.handshake_recv_buffer.data == NULL)
01000 {
01001 MHD_gnutls_assert ();
01002 return GNUTLS_E_MEMORY_ERROR;
01003 }
01004
01005 memcpy (session->internals.handshake_recv_buffer.data, iptr,
01006 dsize);
01007
01008 session->internals.handshake_recv_buffer_htype = htype;
01009 session->internals.handshake_recv_buffer_type = type;
01010
01011 session->internals.handshake_recv_buffer.length = dsize;
01012 }
01013 else
01014 session->internals.handshake_recv_buffer.length = 0;
01015
01016 MHD_gnutls_assert ();
01017
01018 return i;
01019 }
01020 else
01021 {
01022 if (i == 0)
01023 break;
01024 }
01025
01026 left -= i;
01027
01028 }
01029
01030 session->internals.handshake_recv_buffer.length = 0;
01031
01032 return sizeOfPtr - left;
01033 }
01034
01035
01036
01037
01038
01039 int
01040 MHD_gtls_handshake_buffer_put (MHD_gtls_session_t session, opaque * data,
01041 size_t length)
01042 {
01043
01044 if (length == 0)
01045 return 0;
01046
01047 if ((session->internals.max_handshake_data_buffer_size > 0) && ((length
01048 +
01049 session->
01050 internals.
01051 handshake_hash_buffer.
01052 length) >
01053 session->
01054 internals.
01055 max_handshake_data_buffer_size))
01056 {
01057 MHD_gnutls_assert ();
01058 return GNUTLS_E_MEMORY_ERROR;
01059 }
01060
01061 MHD__gnutls_buffers_log ("BUF[HSK]: Inserted %d bytes of Data\n", length);
01062
01063 if (MHD_gtls_buffer_append (&session->internals.handshake_hash_buffer, data,
01064 length) < 0)
01065 {
01066 MHD_gnutls_assert ();
01067 return GNUTLS_E_MEMORY_ERROR;
01068 }
01069
01070 return 0;
01071 }
01072
01073
01074
01075
01076 int
01077 MHD_gtls_handshake_buffer_get_ptr (MHD_gtls_session_t session,
01078 opaque ** data_ptr, size_t * length)
01079 {
01080 if (length != NULL)
01081 *length = session->internals.handshake_hash_buffer.length;
01082
01083 MHD__gnutls_buffers_log ("BUF[HSK]: Peeked %d bytes of Data\n",
01084 session->internals.handshake_hash_buffer.length);
01085
01086 if (data_ptr != NULL)
01087 *data_ptr = session->internals.handshake_hash_buffer.data;
01088
01089 return 0;
01090 }
01091
01092
01093
01094 int
01095 MHD_gtls_handshake_buffer_empty (MHD_gtls_session_t session)
01096 {
01097
01098 MHD__gnutls_buffers_log ("BUF[HSK]: Emptied buffer\n");
01099
01100 session->internals.handshake_hash_buffer.length = 0;
01101
01102 return 0;
01103 }
01104
01105 int
01106 MHD_gtls_handshake_buffer_clear (MHD_gtls_session_t session)
01107 {
01108 MHD__gnutls_buffers_log ("BUF[HSK]: Cleared Data from buffer\n");
01109 MHD_gtls_buffer_clear (&session->internals.handshake_hash_buffer);
01110 return 0;
01111 }