-/* Packet processing callback. This is used to send and receive packets
- from network. This is generic task. */
-
-SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process)
-{
- SilcClient client = (SilcClient)context;
- SilcClientConnection conn = NULL;
- SilcClientConnection conn;
- int ret;
-
- SILC_LOG_DEBUG(("Processing packet"));
-
- SILC_CLIENT_GET_SOCK(client, fd, sock);
- if (sock == NULL)
- return;
-
- conn = (SilcClientConnection)sock->user_data;
-
- /* Packet sending */
- if (type == SILC_TASK_WRITE) {
- /* Do not send data to disconnected connection */
- if (SILC_IS_DISCONNECTED(sock))
- return;
-
- ret = silc_packet_send(sock, TRUE);
-
- /* If returned -2 could not write to connection now, will do
- it later. */
- if (ret == -2)
- return;
-
- /* Error */
- if (ret == -1)
- return;
-
- /* The packet has been sent and now it is time to set the connection
- back to only for input. When there is again some outgoing data
- available for this connection it will be set for output as well.
- This call clears the output setting and sets it only for input. */
- SILC_CLIENT_SET_CONNECTION_FOR_INPUT(client->schedule, fd);
- SILC_UNSET_OUTBUF_PENDING(sock);
-
- silc_buffer_clear(sock->outbuf);
- return;
- }
-
- /* Packet receiving */
- if (type == SILC_TASK_READ) {
- /* Read data from network */
- ret = silc_packet_receive(sock);
- if (ret < 0)
- return;
-
- /* EOF */
- if (ret == 0) {
- SILC_LOG_DEBUG(("Read EOF"));
-
- /* If connection is disconnecting already we will finally
- close the connection */
- if (SILC_IS_DISCONNECTING(sock)) {
- if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
- client->internal->ops->disconnected(client, conn, 0, NULL);
- silc_client_close_connection_real(client, sock, conn);
- return;
- }
-
- SILC_LOG_DEBUG(("EOF from connection %d", sock->sock));
- if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
- client->internal->ops->disconnected(client, conn, 0, NULL);
- silc_client_close_connection_real(client, sock, conn);
- return;
- }
-
- /* Process the packet. This will call the parser that will then
- decrypt and parse the packet. */
- if (sock->type != SILC_SOCKET_TYPE_UNKNOWN)
- silc_packet_receive_process(sock, FALSE, conn->internal->receive_key,
- conn->internal->hmac_receive,
- conn->internal->psn_receive,
- silc_client_packet_parse, client);
- else
- silc_packet_receive_process(sock, FALSE, NULL, NULL, 0,
- silc_client_packet_parse, client);
- }
-}
-
-/* Parser callback called by silc_packet_receive_process. Thie merely
- registers timeout that will handle the actual parsing when appropriate. */
-
-static SilcBool silc_client_packet_parse(SilcPacketParserContext *parser_context,
- void *context)
-{
- SilcClient client = (SilcClient)context;
- SilcClientConnection conn = parser_context->sock;
- SilcClientConnection conn = (SilcClientConnection)sock->user_data;
- SilcPacketContext *packet = parser_context->packet;
- SilcPacketType ret;
-
- if (conn && conn->internal->hmac_receive && conn->sock == sock)
- conn->internal->psn_receive = parser_context->packet->sequence + 1;
-
- /* Parse the packet immediately */
- if (parser_context->normal)
- ret = silc_packet_parse(packet, conn->internal->receive_key);
- else
- ret = silc_packet_parse_special(packet, conn->internal->receive_key);
-
- if (ret == SILC_PACKET_NONE) {
- silc_packet_context_free(packet);
- silc_free(parser_context);
- return FALSE;
- }
-
- /* If protocol for this connection is key exchange or rekey then we'll
- process all packets synchronously, since there might be packets in
- queue that we are not able to decrypt without first processing the
- packets before them. */
- if (sock->protocol && sock->protocol->protocol &&
- (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
- sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
-
- /* Parse the incoming packet type */
- silc_client_packet_parse_type(client, sock, packet);
-
- /* Reprocess the buffer since we'll return FALSE. This is because
- the `conn->internal->receive_key' might have become valid by processing
- the previous packet */
- if (sock->type != SILC_SOCKET_TYPE_UNKNOWN)
- silc_packet_receive_process(sock, FALSE, conn->internal->receive_key,
- conn->internal->hmac_receive,
- conn->internal->psn_receive,
- silc_client_packet_parse, client);
- else
- silc_packet_receive_process(sock, FALSE, NULL, NULL, 0,
- silc_client_packet_parse, client);
-
- silc_packet_context_free(packet);
- silc_free(parser_context);
-
- return FALSE;
- }
-
- /* Parse the incoming packet type */
- silc_client_packet_parse_type(client, sock, packet);
- silc_packet_context_free(packet);
- silc_free(parser_context);
- return TRUE;
-}
-#endif /* 0 */
-
-/* Closes connection to remote end. Free's all allocated data except
- for some information such as nickname etc. that are valid at all time.
- If the `sock' is NULL then the conn->sock will be used. If `sock' is
- provided it will be checked whether the sock and `conn->sock' are the
- same (they can be different, ie. a socket can use `conn' as its
- connection but `conn->sock' might be actually a different connection
- than the `sock'). */
-
-#if 0
-void silc_client_close_connection_real(SilcClient client,
- SilcClientConnection conn)
-{
- int del = FALSE;
-
- SILC_LOG_DEBUG(("Start"));
-
- if (!sock && !conn)
- return;
-
- if (!sock || (sock && conn->sock == sock))
- del = TRUE;
- if (!sock)
- sock = conn->sock;
-
- if (!sock) {
- if (del && conn)
- silc_client_del_connection(client, conn);
- return;
- }
-
- /* We won't listen for this connection anymore */
- silc_schedule_unset_listen_fd(client->schedule, sock->sock);
-
- /* Unregister all tasks */
- silc_schedule_task_del_by_fd(client->schedule, sock->sock);
-
- /* Close the actual connection */
- silc_net_close_connection(sock->sock);
-
- /* Cancel any active protocol */
- if (sock->protocol) {
- if (sock->protocol->protocol->type ==
- SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
- sock->protocol->protocol->type ==
- SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {
- sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
- silc_protocol_execute_final(sock->protocol, client->schedule);
- /* The application will recall this function with these protocols
- (the ops->connected client operation). */
- return;
- } else {
- sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
- silc_protocol_execute_final(sock->protocol, client->schedule);
- sock->protocol = NULL;
- }
- }
-
- /* Free everything */
- if (del && sock->user_data)
- silc_client_del_connection(client, conn);
-
- silc_socket_free(sock);
-}
-
-/* Closes the connection to the remote end */
-
-void silc_client_close_connection(SilcClient client,
- SilcClientConnection conn)
-{
- // silc_client_close_connection_real(client, NULL, conn);
-}
-
-/* Called when we receive disconnection packet from server. This
- closes our end properly and displays the reason of the disconnection
- on the screen. */
-
-void silc_client_disconnect(SilcClient client,
- SilcClientConnection conn,
- SilcBuffer packet)
-{
- SilcClientConnection conn;
- SilcStatus status;
- char *message = NULL;
-
- SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
-
- if (packet->len < 1)
- return;
-
- status = (SilcStatus)packet->data[0];
-
- if (packet->len > 1 &&
- silc_utf8_valid(packet->data + 1, packet->len - 1))
- message = silc_memdup(packet->data + 1, packet->len - 1);
-
- conn = (SilcClientConnection)sock->user_data;
- if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
- client->internal->ops->disconnected(client, conn, status, message);
-
- silc_free(message);
-
- SILC_SET_DISCONNECTED(sock);
-
- /* Close connection through scheduler. */
- silc_schedule_task_add(client->schedule, sock->sock,
- silc_client_disconnected_by_server_later,
- client, 0, 1, SILC_TASK_TIMEOUT,
- SILC_TASK_PRI_NORMAL);
-}
-
-/* Received error message from server. Display it on the screen.
- We don't take any action what so ever of the error message. */
-
-void silc_client_error_by_server(SilcClient client,
- SilcClientConnection conn,
- SilcBuffer message)
-{
- char *msg;
-
- msg = silc_memdup(message->data, message->len);
- client->internal->ops->say(client, sock->user_data,
- SILC_CLIENT_MESSAGE_AUDIT, msg);
- silc_free(msg);
-}
-
-/* Auto-nicking callback to send NICK command to server. */
-
-SILC_TASK_CALLBACK(silc_client_send_auto_nick)
-{
- SilcClientConnection conn = (SilcClientConnection)context;
- SilcClient client = conn->client;
- if (client)
- silc_client_command_send(client, conn, SILC_COMMAND_NICK,
- ++conn->cmd_ident, 1, 1,
- client->nickname, strlen(client->nickname));
-}
-