| 1766 | } |
| 1767 | |
| 1768 | static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer, char *buffer, size_t max_len) |
| 1769 | { |
| 1770 | pni_ssl_t *ssl = transport->ssl; |
| 1771 | if (!ssl) return PN_EOS; |
| 1772 | ssl_log( transport, PN_LEVEL_TRACE, "process_output_ssl( max_len=%zu )",max_len ); |
| 1773 | |
| 1774 | ssize_t written = 0; |
| 1775 | ssize_t total_app_bytes = 0; |
| 1776 | bool work_pending; |
| 1777 | |
| 1778 | if (ssl->state == CLIENT_HELLO) { |
| 1779 | // output buffers eclusively for internal handshake use until negotiation complete |
| 1780 | client_handshake_init(transport); |
| 1781 | if (ssl->state == SSL_CLOSED) |
| 1782 | return PN_EOS; |
| 1783 | ssl->state = NEGOTIATING; |
| 1784 | } |
| 1785 | |
| 1786 | do { |
| 1787 | work_pending = false; |
| 1788 | |
| 1789 | if (ssl->network_out_pending > 0) { |
| 1790 | size_t wcount = _pni_min(ssl->network_out_pending, max_len); |
| 1791 | memmove(buffer, ssl->network_outp, wcount); |
| 1792 | ssl->network_outp += wcount; |
| 1793 | ssl->network_out_pending -= wcount; |
| 1794 | buffer += wcount; |
| 1795 | max_len -= wcount; |
| 1796 | written += wcount; |
| 1797 | } |
| 1798 | |
| 1799 | if (ssl->network_out_pending == 0 && ssl->state == RUNNING && !ssl->app_output_closed) { |
| 1800 | // refill the buffer with app data and encrypt it |
| 1801 | |
| 1802 | char *app_data = ssl->sc_outbuf + ssl->sc_sizes.cbHeader; |
| 1803 | char *app_outp = app_data; |
| 1804 | size_t remaining = ssl->max_data_size; |
| 1805 | ssize_t app_bytes; |
| 1806 | do { |
| 1807 | app_bytes = transport->io_layers[layer+1]->process_output(transport, layer+1, app_outp, remaining); |
| 1808 | if (app_bytes > 0) { |
| 1809 | app_outp += app_bytes; |
| 1810 | remaining -= app_bytes; |
| 1811 | ssl_log( transport, PN_LEVEL_TRACE, "Gathered %zd bytes from app to send to peer", app_bytes ); |
| 1812 | } else { |
| 1813 | if (app_bytes < 0) { |
| 1814 | ssl_log(transport, PN_LEVEL_WARNING, "Application layer closed its output, error=%d (%d bytes pending send)", |
| 1815 | (int) app_bytes, (int) ssl->network_out_pending); |
| 1816 | ssl->app_output_closed = app_bytes; |
| 1817 | if (ssl->app_input_closed) |
| 1818 | ssl->state = SHUTTING_DOWN; |
| 1819 | } else if (total_app_bytes == 0 && ssl->app_input_closed) { |
| 1820 | // We've drained all the App layer can provide |
| 1821 | ssl_log(transport, PN_LEVEL_WARNING, "Application layer blocked on input, closing"); |
| 1822 | ssl->state = SHUTTING_DOWN; |
| 1823 | ssl->app_output_closed = PN_ERR; |
| 1824 | } |
| 1825 | } |
nothing calls this directly
no test coverage detected