diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 281 |
1 files changed, 173 insertions, 108 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 5646fcfb..e0d0b522 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -681,82 +681,179 @@ MHD_get_fdset (struct MHD_Daemon *daemon, | |||
681 | * @param urh upgrade handle to wait for | 681 | * @param urh upgrade handle to wait for |
682 | * @param[out] rs read set to initialize | 682 | * @param[out] rs read set to initialize |
683 | * @param[out] ws write set to initialize | 683 | * @param[out] ws write set to initialize |
684 | * @param[out] es except set to initialize | ||
684 | * @param[out] max_fd maximum FD to update | 685 | * @param[out] max_fd maximum FD to update |
685 | * @param fd_setsize value of FD_SETSIZE | 686 | * @param fd_setsize value of FD_SETSIZE |
686 | * @return #MHD_YES on success, #MHD_NO on error | 687 | * @return true on success, false on error |
687 | */ | 688 | */ |
688 | static int | 689 | static bool |
689 | urh_to_fdset (struct MHD_UpgradeResponseHandle *urh, | 690 | urh_to_fdset (struct MHD_UpgradeResponseHandle *urh, |
690 | fd_set *rs, | 691 | fd_set *rs, |
691 | fd_set *ws, | 692 | fd_set *ws, |
693 | fd_set *es, | ||
692 | MHD_socket *max_fd, | 694 | MHD_socket *max_fd, |
693 | unsigned int fd_setsize) | 695 | unsigned int fd_setsize) |
694 | { | 696 | { |
695 | if ( (urh->out_buffer_used < urh->out_buffer_size) && | 697 | const MHD_socket conn_sckt = urh->connection->socket_fd; |
696 | (MHD_INVALID_SOCKET != urh->mhd.socket) && | 698 | const MHD_socket mhd_sckt = urh->mhd.socket; |
697 | (! MHD_add_to_fd_set_ (urh->mhd.socket, | 699 | bool res = true; |
698 | rs, | 700 | |
699 | max_fd, | 701 | if (MHD_INVALID_SOCKET != conn_sckt) |
700 | fd_setsize)) ) | 702 | { |
701 | return MHD_NO; | 703 | if ( (urh->in_buffer_used < urh->in_buffer_size) && |
702 | if ( (0 != urh->in_buffer_used) && | 704 | (! MHD_add_to_fd_set_ (conn_sckt, |
703 | (! urh->was_closed) && | 705 | rs, |
704 | (MHD_INVALID_SOCKET != urh->mhd.socket) && | 706 | max_fd, |
705 | (! MHD_add_to_fd_set_ (urh->mhd.socket, | 707 | fd_setsize)) ) |
706 | ws, | 708 | res = false; |
707 | max_fd, | 709 | if ( (0 != urh->out_buffer_used) && |
708 | fd_setsize)) ) | 710 | (! MHD_add_to_fd_set_ (conn_sckt, |
709 | return MHD_NO; | 711 | ws, |
710 | if ( (urh->in_buffer_used < urh->in_buffer_size) && | 712 | max_fd, |
711 | (! urh->was_closed) && | 713 | fd_setsize)) ) |
712 | (MHD_INVALID_SOCKET != urh->connection->socket_fd) && | 714 | res = false; |
713 | (! MHD_add_to_fd_set_ (urh->connection->socket_fd, | 715 | if (0 != urh->in_buffer_size) |
714 | rs, | 716 | MHD_add_to_fd_set_ (conn_sckt, |
715 | max_fd, | 717 | es, |
716 | fd_setsize)) ) | 718 | max_fd, |
717 | return MHD_NO; | 719 | fd_setsize); |
718 | if ( (0 != urh->out_buffer_used) && | 720 | } |
719 | (MHD_INVALID_SOCKET != urh->connection->socket_fd) && | 721 | if (MHD_INVALID_SOCKET != mhd_sckt) |
720 | (! MHD_add_to_fd_set_ (urh->connection->socket_fd, | 722 | { |
721 | ws, | 723 | if ( (urh->out_buffer_used < urh->out_buffer_size) && |
722 | max_fd, | 724 | (! MHD_add_to_fd_set_ (mhd_sckt, |
723 | fd_setsize)) ) | 725 | rs, |
724 | return MHD_NO; | 726 | max_fd, |
725 | return MHD_YES; | 727 | fd_setsize)) ) |
728 | res = false; | ||
729 | if ( (0 != urh->in_buffer_used) && | ||
730 | (! MHD_add_to_fd_set_ (mhd_sckt, | ||
731 | ws, | ||
732 | max_fd, | ||
733 | fd_setsize)) ) | ||
734 | res = false; | ||
735 | if (0 != urh->out_buffer_size) | ||
736 | MHD_add_to_fd_set_ (mhd_sckt, | ||
737 | es, | ||
738 | max_fd, | ||
739 | fd_setsize); | ||
740 | } | ||
741 | |||
742 | return res; | ||
726 | } | 743 | } |
727 | 744 | ||
728 | 745 | ||
729 | /** | 746 | /** |
730 | * Update the @a urh based on the ready FDs in the @a rs and @a ws. | 747 | * Update the @a urh based on the ready FDs in |
748 | * the @a rs, @a ws, and @a es. | ||
731 | * | 749 | * |
732 | * @param urh upgrade handle to update | 750 | * @param urh upgrade handle to update |
733 | * @param rs read result from select() | 751 | * @param rs read result from select() |
734 | * @param ws write result from select() | 752 | * @param ws write result from select() |
753 | * @param ws except result from select() | ||
735 | */ | 754 | */ |
736 | static void | 755 | static void |
737 | urh_from_fdset (struct MHD_UpgradeResponseHandle *urh, | 756 | urh_from_fdset (struct MHD_UpgradeResponseHandle *urh, |
738 | const fd_set *rs, | 757 | const fd_set *rs, |
739 | const fd_set *ws) | 758 | const fd_set *ws, |
759 | const fd_set *es,) | ||
740 | { | 760 | { |
741 | const MHD_socket mhd_sckt = urh->mhd.socket; | ||
742 | const MHD_socket conn_sckt = urh->connection->socket_fd; | 761 | const MHD_socket conn_sckt = urh->connection->socket_fd; |
762 | const MHD_socket mhd_sckt = urh->mhd.socket; | ||
763 | |||
764 | urh->app.celi = MHD_EPOLL_STATE_UNREADY; | ||
765 | urh->mhd.celi = MHD_EPOLL_STATE_UNREADY; | ||
766 | |||
767 | if (MHD_INVALID_SOCKET != conn_sckt) | ||
768 | { | ||
769 | if (FD_ISSET (conn_sckt, rs)) | ||
770 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; | ||
771 | if (FD_ISSET (conn_sckt, ws)) | ||
772 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; | ||
773 | if (FD_ISSET (conn_sckt, es)) | ||
774 | urh->app.celi |= MHD_EPOLL_STATE_ERROR; | ||
775 | } | ||
776 | if ((MHD_INVALID_SOCKET != mhd_sckt)) | ||
777 | { | ||
778 | if (FD_ISSET (mhd_sckt, rs)) | ||
779 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | ||
780 | if (FD_ISSET (mhd_sckt, ws)) | ||
781 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; | ||
782 | if (FD_ISSET (mhd_sckt, es)) | ||
783 | urh->mhd.celi |= MHD_EPOLL_STATE_ERROR; | ||
784 | } | ||
785 | } | ||
786 | |||
787 | |||
788 | /** | ||
789 | * Set required 'event' members in 'pollfd' elements, | ||
790 | * assuming that @a p[0].fd is MHD side of socketpair | ||
791 | * and @a p[1].fd is TLS connected socket. | ||
792 | * | ||
793 | * @param urh upgrade handle to watch for | ||
794 | * @param p pollfd array to update | ||
795 | */ | ||
796 | static void | ||
797 | urh_update_pollfd(struct MHD_UpgradeResponseHandle *urh, | ||
798 | struct pollfd p[2]) | ||
799 | { | ||
800 | p[0].events = 0; | ||
801 | p[1].events = 0; | ||
802 | if (urh->in_buffer_used < urh->in_buffer_size) | ||
803 | p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; | ||
804 | if (0 != urh->out_buffer_used) | ||
805 | p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; | ||
806 | if (0 != urh->in_buffer_size) | ||
807 | p[0].events |= MHD_POLL_EVENTS_ERR_DISC; | ||
808 | if (urh->out_buffer_used < urh->out_buffer_size) | ||
809 | p[1].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; | ||
810 | if (0 != urh->in_buffer_used) | ||
811 | p[1].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; | ||
812 | if (0 != urh->out_buffer_size) | ||
813 | p[1].events |= MHD_POLL_EVENTS_ERR_DISC; | ||
814 | } | ||
815 | |||
743 | 816 | ||
744 | if ((MHD_INVALID_SOCKET != conn_sckt) && | 817 | /** |
745 | FD_ISSET (conn_sckt, rs)) | 818 | * Set @a p to watch for @a urh. |
819 | * | ||
820 | * @param urh upgrade handle to watch for | ||
821 | * @param p pollfd array to set | ||
822 | */ | ||
823 | static void | ||
824 | urh_to_pollfd(struct MHD_UpgradeResponseHandle *urh, | ||
825 | struct pollfd p[2]) | ||
826 | { | ||
827 | p[0].fd = urh->connection->socket_fd; | ||
828 | p[1].fd = urh->mhd.socket; | ||
829 | urh_update_pollfd(urh, p); | ||
830 | } | ||
831 | |||
832 | |||
833 | /** | ||
834 | * Update ready state in @a urh based on pollfd. | ||
835 | * @param urh upgrade handle to update | ||
836 | * @param p 'poll()' processed pollfd. | ||
837 | */ | ||
838 | static void | ||
839 | urh_from_pollfd(struct MHD_UpgradeResponseHandle *urh, | ||
840 | struct pollfd p[2]) | ||
841 | { | ||
842 | if (0 != (p[0].revents & POLLIN)) | ||
746 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; | 843 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; |
747 | if ((MHD_INVALID_SOCKET != conn_sckt) && | 844 | if (0 != (p[0].revents & POLLOUT)) |
748 | FD_ISSET (conn_sckt, ws)) | ||
749 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; | 845 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; |
750 | if ((MHD_INVALID_SOCKET != mhd_sckt) && | 846 | if (0 != (p[0].revents & MHD_POLL_REVENTS_ERR_DISC)) |
751 | FD_ISSET (mhd_sckt, rs)) | 847 | urh->app.celi |= MHD_EPOLL_STATE_ERROR; |
848 | if (0 != (p[1].revents & POLLIN)) | ||
752 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | 849 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; |
753 | if ((MHD_INVALID_SOCKET != mhd_sckt) && | 850 | if (0 != (p[1].revents & POLLOUT)) |
754 | FD_ISSET (mhd_sckt, ws)) | ||
755 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; | 851 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; |
852 | if (0 != (p[1].revents & MHD_POLL_REVENTS_ERR_DISC)) | ||
853 | urh->mhd.celi |= MHD_EPOLL_STATE_ERROR; | ||
756 | } | 854 | } |
757 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 855 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
758 | 856 | ||
759 | |||
760 | /** | 857 | /** |
761 | * Obtain the `select()` sets for this daemon. | 858 | * Obtain the `select()` sets for this daemon. |
762 | * Daemon's FDs will be added to fd_sets. To get only | 859 | * Daemon's FDs will be added to fd_sets. To get only |
@@ -891,6 +988,7 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon, | |||
891 | urh_to_fdset (urh, | 988 | urh_to_fdset (urh, |
892 | read_fd_set, | 989 | read_fd_set, |
893 | write_fd_set, | 990 | write_fd_set, |
991 | except_fd_set, | ||
894 | max_fd, | 992 | max_fd, |
895 | fd_setsize)) | 993 | fd_setsize)) |
896 | result = MHD_NO; | 994 | result = MHD_NO; |
@@ -1362,19 +1460,22 @@ thread_main_connection_upgrade (struct MHD_Connection *con) | |||
1362 | /* use select */ | 1460 | /* use select */ |
1363 | fd_set rs; | 1461 | fd_set rs; |
1364 | fd_set ws; | 1462 | fd_set ws; |
1463 | fd_set es; | ||
1365 | MHD_socket max_fd; | 1464 | MHD_socket max_fd; |
1366 | int num_ready; | 1465 | int num_ready; |
1367 | int result; | 1466 | bool result; |
1368 | 1467 | ||
1369 | FD_ZERO (&rs); | 1468 | FD_ZERO (&rs); |
1370 | FD_ZERO (&ws); | 1469 | FD_ZERO (&ws); |
1470 | FD_ZERO (&es); | ||
1371 | max_fd = MHD_INVALID_SOCKET; | 1471 | max_fd = MHD_INVALID_SOCKET; |
1372 | result = urh_to_fdset (urh, | 1472 | result = urh_to_fdset (urh, |
1373 | &rs, | 1473 | &rs, |
1374 | &ws, | 1474 | &ws, |
1475 | &es, | ||
1375 | &max_fd, | 1476 | &max_fd, |
1376 | FD_SETSIZE); | 1477 | FD_SETSIZE); |
1377 | if (MHD_NO == result) | 1478 | if (! result) |
1378 | { | 1479 | { |
1379 | #ifdef HAVE_MESSAGES | 1480 | #ifdef HAVE_MESSAGES |
1380 | MHD_DLOG (con->daemon, | 1481 | MHD_DLOG (con->daemon, |
@@ -1399,7 +1500,7 @@ thread_main_connection_upgrade (struct MHD_Connection *con) | |||
1399 | num_ready = MHD_SYS_select_ (max_fd + 1, | 1500 | num_ready = MHD_SYS_select_ (max_fd + 1, |
1400 | &rs, | 1501 | &rs, |
1401 | &ws, | 1502 | &ws, |
1402 | NULL, | 1503 | &es, |
1403 | tvp); | 1504 | tvp); |
1404 | } | 1505 | } |
1405 | else | 1506 | else |
@@ -1420,7 +1521,8 @@ thread_main_connection_upgrade (struct MHD_Connection *con) | |||
1420 | } | 1521 | } |
1421 | urh_from_fdset (urh, | 1522 | urh_from_fdset (urh, |
1422 | &rs, | 1523 | &rs, |
1423 | &ws); | 1524 | &ws |
1525 | &es); | ||
1424 | process_urh (urh); | 1526 | process_urh (urh); |
1425 | if ( (0 == urh->in_buffer_size) && | 1527 | if ( (0 == urh->in_buffer_size) && |
1426 | (0 == urh->out_buffer_size) && | 1528 | (0 == urh->out_buffer_size) && |
@@ -1433,38 +1535,29 @@ thread_main_connection_upgrade (struct MHD_Connection *con) | |||
1433 | else if (0 != (daemon->options & MHD_USE_TLS)) | 1535 | else if (0 != (daemon->options & MHD_USE_TLS)) |
1434 | { | 1536 | { |
1435 | /* use poll() */ | 1537 | /* use poll() */ |
1538 | struct pollfd p[2]; | ||
1539 | memset (p, | ||
1540 | 0, | ||
1541 | sizeof (p)); | ||
1542 | p[0].fd = urh->connection->socket_fd; | ||
1543 | p[1].fd = urh->mhd.socket; | ||
1436 | 1544 | ||
1437 | while ( (MHD_CONNECTION_UPGRADE == con->state) || | 1545 | while ( (MHD_CONNECTION_UPGRADE == con->state) || |
1438 | (0 != urh->out_buffer_used) ) | 1546 | (0 != urh->out_buffer_used) ) |
1439 | { | 1547 | { |
1440 | struct pollfd p[2]; | 1548 | int timeout; |
1441 | unsigned int timeout; | ||
1442 | 1549 | ||
1443 | memset (p, | 1550 | urh_update_pollfd(urh, p); |
1444 | 0, | ||
1445 | sizeof (struct pollfd) * 2); | ||
1446 | p[0].fd = urh->connection->socket_fd; | ||
1447 | p[1].fd = urh->mhd.socket; | ||
1448 | if (urh->in_buffer_used < urh->in_buffer_size) | ||
1449 | p[0].events |= POLLIN; | ||
1450 | if (0 != urh->out_buffer_used) | ||
1451 | p[0].events |= POLLOUT; | ||
1452 | if (urh->out_buffer_used < urh->out_buffer_size) | ||
1453 | p[1].events |= POLLIN; | ||
1454 | if (0 != urh->in_buffer_used) | ||
1455 | p[1].events |= POLLOUT; | ||
1456 | 1551 | ||
1457 | if ( (con->tls_read_ready) && | 1552 | if ( (con->tls_read_ready) && |
1458 | (urh->in_buffer_used < urh->in_buffer_size)) | 1553 | (urh->in_buffer_used < urh->in_buffer_size)) |
1459 | timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */ | 1554 | timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */ |
1460 | else | 1555 | else |
1461 | timeout = UINT_MAX; | 1556 | timeout = -1; |
1462 | 1557 | ||
1463 | /* FIXME: does this check really needed? */ | 1558 | if (MHD_sys_poll_ (p, |
1464 | if ( (0 != (p[0].events | p[1].events)) && | 1559 | 2, |
1465 | (MHD_sys_poll_ (p, | 1560 | timeout) < 0) |
1466 | 2, | ||
1467 | timeout) < 0) ) | ||
1468 | { | 1561 | { |
1469 | const int err = MHD_socket_get_error_ (); | 1562 | const int err = MHD_socket_get_error_ (); |
1470 | 1563 | ||
@@ -1477,14 +1570,7 @@ thread_main_connection_upgrade (struct MHD_Connection *con) | |||
1477 | #endif | 1570 | #endif |
1478 | break; | 1571 | break; |
1479 | } | 1572 | } |
1480 | if (0 != (p[0].revents & POLLIN)) | 1573 | urh_from_pollfd(urh, p); |
1481 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; | ||
1482 | if (0 != (p[0].revents & POLLOUT)) | ||
1483 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; | ||
1484 | if (0 != (p[1].revents & POLLIN)) | ||
1485 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | ||
1486 | if (0 != (p[1].revents & POLLOUT)) | ||
1487 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; | ||
1488 | process_urh (urh); | 1574 | process_urh (urh); |
1489 | if ( (0 == urh->in_buffer_size) && | 1575 | if ( (0 == urh->in_buffer_size) && |
1490 | (0 == urh->out_buffer_size) && | 1576 | (0 == urh->out_buffer_size) && |
@@ -3153,7 +3239,8 @@ MHD_run_from_select (struct MHD_Daemon *daemon, | |||
3153 | /* update urh state based on select() output */ | 3239 | /* update urh state based on select() output */ |
3154 | urh_from_fdset (urh, | 3240 | urh_from_fdset (urh, |
3155 | read_fd_set, | 3241 | read_fd_set, |
3156 | write_fd_set); | 3242 | write_fd_set, |
3243 | except_fd_set); | ||
3157 | /* call generic forwarding function for passing data */ | 3244 | /* call generic forwarding function for passing data */ |
3158 | process_urh (urh); | 3245 | process_urh (urh); |
3159 | /* Finished forwarding? */ | 3246 | /* Finished forwarding? */ |
@@ -3448,18 +3535,8 @@ MHD_poll_all (struct MHD_Daemon *daemon, | |||
3448 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 3535 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
3449 | for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) | 3536 | for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) |
3450 | { | 3537 | { |
3451 | p[poll_server+i].fd = urh->connection->socket_fd; | 3538 | urh_to_pollfd(urh, &(p[poll_server+i])); |
3452 | if (urh->in_buffer_used < urh->in_buffer_size) | 3539 | i += 2; |
3453 | p[poll_server+i].events |= POLLIN; | ||
3454 | if (0 != urh->out_buffer_used) | ||
3455 | p[poll_server+i].events |= POLLOUT; | ||
3456 | i++; | ||
3457 | p[poll_server+i].fd = urh->mhd.socket; | ||
3458 | if (urh->out_buffer_used < urh->out_buffer_size) | ||
3459 | p[poll_server+i].events |= POLLIN; | ||
3460 | if (0 != urh->in_buffer_used) | ||
3461 | p[poll_server+i].events |= POLLOUT; | ||
3462 | i++; | ||
3463 | } | 3540 | } |
3464 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 3541 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
3465 | if (0 == poll_server + num_connections) | 3542 | if (0 == poll_server + num_connections) |
@@ -3528,23 +3605,11 @@ MHD_poll_all (struct MHD_Daemon *daemon, | |||
3528 | * from 'daemon->urh_head' list. */ | 3605 | * from 'daemon->urh_head' list. */ |
3529 | urhn = urh->prev; | 3606 | urhn = urh->prev; |
3530 | /* Check for fd mismatch. FIXME: required for safety? */ | 3607 | /* Check for fd mismatch. FIXME: required for safety? */ |
3531 | if (p[poll_server+i].fd == urh->connection->socket_fd) | 3608 | if ((p[poll_server+i].fd != urh->connection->socket_fd) || |
3532 | { | 3609 | (p[poll_server+i+1].fd != urh->mhd.socket)) |
3533 | if (0 != (p[poll_server+i].revents & POLLIN)) | 3610 | break; |
3534 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; | 3611 | urh_from_pollfd(urh, &(p[poll_server+i])); |
3535 | if (0 != (p[poll_server+i].revents & POLLOUT)) | 3612 | i += 2; |
3536 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; | ||
3537 | } | ||
3538 | i++; | ||
3539 | /* Check for fd mismatch. FIXME: required for safety? */ | ||
3540 | if (p[poll_server+i].fd == urh->mhd.socket) | ||
3541 | { | ||
3542 | if (0 != (p[poll_server+i].revents & POLLIN)) | ||
3543 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | ||
3544 | if (0 != (p[poll_server+i].revents & POLLOUT)) | ||
3545 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; | ||
3546 | } | ||
3547 | i++; | ||
3548 | process_urh (urh); | 3613 | process_urh (urh); |
3549 | /* Finished forwarding? */ | 3614 | /* Finished forwarding? */ |
3550 | if ( (0 == urh->in_buffer_size) && | 3615 | if ( (0 == urh->in_buffer_size) && |