static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages) { PseudoSSLPriv *priv = sock->priv; /* Socket has been closed: */ if (sock->priv == NULL) return 0; if (priv->handshaken) { if (priv->base_socket) { /* Fast path: once we’ve done the handshake, pass straight through to the * base socket. */ return nice_socket_recv_messages (priv->base_socket, recv_messages, n_recv_messages); } } else { guint8 data[MAX(sizeof(SSL_SERVER_GOOGLE_HANDSHAKE), sizeof(SSL_SERVER_MSOC_HANDSHAKE))]; gint ret = -1; GInputVector local_recv_buf = { data, sizeof(data) }; NiceInputMessage local_recv_message = { &local_recv_buf, 1, NULL, 0 }; if (priv->compatibility == NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_MSOC) { local_recv_buf.size = sizeof(SSL_SERVER_MSOC_HANDSHAKE); } else { local_recv_buf.size = sizeof(SSL_SERVER_GOOGLE_HANDSHAKE); } if (priv->base_socket) { ret = nice_socket_recv_messages (priv->base_socket, &local_recv_message, 1); } if (ret <= 0) { return ret; } else if (ret == 1 && server_handshake_valid(sock, &local_recv_buf, local_recv_message.length)) { priv->handshaken = TRUE; nice_socket_flush_send_queue (priv->base_socket, &priv->send_queue); } else { if (priv->base_socket) nice_socket_free (priv->base_socket); priv->base_socket = NULL; return -1; } } return 0; }
/** * Checks whether given header is valid. */ inline bool valid(header& hdr) { switch (hdr.operation) { default: return false; // invalid operation field case server_handshake: return server_handshake_valid(hdr); case client_handshake: return client_handshake_valid(hdr); case dispatch_message: return dispatch_message_valid(hdr); case announce_proxy_instance: return announce_proxy_instance_valid(hdr); case kill_proxy_instance: return kill_proxy_instance_valid(hdr); } }