| 7085 | |
| 7086 | |
| 7087 | SSHORT rem_port::asyncReceive(PACKET* asyncPacket, const UCHAR* buffer, SSHORT dataSize) |
| 7088 | { |
| 7089 | /************************************** |
| 7090 | * |
| 7091 | * a s y n c R e c e i v e |
| 7092 | * |
| 7093 | ************************************** |
| 7094 | * |
| 7095 | * Functional description |
| 7096 | * If possible, accept incoming data asynchronously |
| 7097 | * |
| 7098 | **************************************/ |
| 7099 | if (! port_async_receive) |
| 7100 | { |
| 7101 | return 0; |
| 7102 | } |
| 7103 | if (haveRecvData()) |
| 7104 | { |
| 7105 | // We have no reliable way to distinguish network packet that start |
| 7106 | // from the beginning of XDR packet or in the middle of it. |
| 7107 | // Therefore try to process asynchronously only if there is no data |
| 7108 | // waiting in port queue. This can lead to fallback to synchronous |
| 7109 | // processing of async command (i.e. with some delay), but reliably |
| 7110 | // protects from spurious protocol breakage. |
| 7111 | return 0; |
| 7112 | } |
| 7113 | |
| 7114 | SLONG original_op = xdr_peek_long(port_async_receive->port_receive, buffer, dataSize); |
| 7115 | |
| 7116 | switch (original_op) |
| 7117 | { |
| 7118 | case op_cancel: |
| 7119 | case op_abort_aux_connection: |
| 7120 | case op_crypt_key_callback: |
| 7121 | break; |
| 7122 | default: |
| 7123 | return 0; |
| 7124 | } |
| 7125 | |
| 7126 | { // scope for guard |
| 7127 | static GlobalPtr<Mutex> mutex; |
| 7128 | MutexLockGuard guard(mutex, FB_FUNCTION); |
| 7129 | |
| 7130 | port_async_receive->clearRecvQue(); |
| 7131 | port_async_receive->port_receive->x_handy = 0; |
| 7132 | port_async_receive->port_protocol = port_protocol; |
| 7133 | memcpy(port_async_receive->port_queue.add().getBuffer(dataSize), buffer, dataSize); |
| 7134 | |
| 7135 | // It's required, that async packets follow simple rule: |
| 7136 | // xdr packet fits into network packet. |
| 7137 | port_async_receive->receive(asyncPacket); |
| 7138 | } |
| 7139 | |
| 7140 | const SSHORT asyncSize = dataSize - port_async_receive->port_receive->x_handy; |
| 7141 | fb_assert(asyncSize >= 0); |
| 7142 | |
| 7143 | switch (asyncPacket->p_operation) |
| 7144 | { |
no test coverage detected