From 157f4732888e39853b3de6617eeeffd910a4a06d Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Fri, 2 Nov 2001 16:58:56 +0000 Subject: [PATCH] updates. --- CHANGES | 8 ++++ apps/irssi/docs/help/in/file.in | 15 +++++-- apps/irssi/src/silc/core/silc-servers.c | 14 +++++-- apps/silcd/server.c | 6 ++- lib/silcclient/client.c | 27 ++++++++++++- lib/silcclient/client_ftp.c | 52 ++++++++++++++++++------- lib/silcclient/silcapi.h | 10 +++++ lib/silccore/silcpacket.c | 8 +++- lib/silcutil/silcnet.c | 2 +- lib/silcutil/unix/silcunixnet.c | 2 +- 10 files changed, 117 insertions(+), 27 deletions(-) diff --git a/CHANGES b/CHANGES index 1aff35ca..a16325a9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +Fri Nov 2 18:52:08 EST 2001 Pekka Riikonen + + * Do not process packet for disconnected socket connection. + Affected file lib/silccore/silcpacket.c. + + * Process the DISCONNECT packet through scheduler in the + client library. Affected file lib/silcclient/client.c. + Thu Nov 1 22:10:07 EST 2001 Pekka Riikonen * Defined to WHOIS command reply the sending of fingerprint diff --git a/apps/irssi/docs/help/in/file.in b/apps/irssi/docs/help/in/file.in index a7a07ee5..4e85a92c 100644 --- a/apps/irssi/docs/help/in/file.in +++ b/apps/irssi/docs/help/in/file.in @@ -14,18 +14,27 @@ giving the FILE command without arguments. Commands: - SEND + SEND [ []] Sends file transfer request to . This makes the available to . - RECEIVE [] + If the is provided then the key exchange + protocol listener will be bound to that address. If + is defined it is bound to that port. + If they are not defined then the local IP address + of your machine is used to bind the listener. If that + fails then the is assumed to provide the + listener. If you do not know whether you need to + provide or not, do not provide it. + + RECEIVE [] Accepts the file transfer request and starts the file transfer session. If the is omitted the last received request is used. - CLOSE [] + CLOSE [] Closes the file transfer session, or rejects file transfer request. If this command is given diff --git a/apps/irssi/src/silc/core/silc-servers.c b/apps/irssi/src/silc/core/silc-servers.c index 8da65701..f9f5854f 100644 --- a/apps/irssi/src/silc/core/silc-servers.c +++ b/apps/irssi/src/silc/core/silc-servers.c @@ -308,7 +308,7 @@ char *silc_server_get_channels(SILC_SERVER_REC *server) /* SYNTAX: PING */ /* SYNTAX: SCONNECT [] */ /* SYNTAX: USERS */ -/* SYNTAX: FILE SEND */ +/* SYNTAX: FILE SEND [ []] */ /* SYNTAX: FILE RECEIVE [] */ /* SYNTAX: FILE CLOSE [] */ /* SYNTAX: FILE */ @@ -573,6 +573,8 @@ static void command_file(const char *data, SILC_SERVER_REC *server, uint32 *argv_lens, *argv_types; int type = 0; FtpSession ftp; + char *local_ip = NULL; + uint32 local_port = 0; if (!server || !IS_SILC_SERVER(server) || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED); @@ -581,7 +583,7 @@ static void command_file(const char *data, SILC_SERVER_REC *server, /* Now parse all arguments */ tmp = g_strconcat("FILE", " ", data, NULL); - silc_parse_command_line(tmp, &argv, &argv_lens, &argv_types, &argc, 4); + silc_parse_command_line(tmp, &argv, &argv_lens, &argv_types, &argc, 6); g_free(tmp); if (argc == 1) @@ -627,10 +629,16 @@ static void command_file(const char *data, SILC_SERVER_REC *server, client_entry = entrys[0]; silc_free(entrys); + if (argc >= 5) + local_ip = argv[4]; + if (argc >= 6) + local_port = atoi(argv[5]); + ftp = silc_calloc(1, sizeof(*ftp)); ftp->session_id = silc_client_file_send(silc_client, conn, silc_client_file_monitor, - server, client_entry, argv[2]); + server, local_ip, local_port, + client_entry, argv[2]); printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, SILCTXT_FILE_SEND, client_entry->nickname, diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 33b93d63..31ae8877 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -181,8 +181,12 @@ int silc_server_init(SilcServer server) tmp = silc_net_create_server(server->config->listen_port->port, server->config->listen_port->listener_ip); - if (tmp < 0) + if (tmp < 0) { + SILC_LOG_ERROR(("Could not create server listener: %s on %d", + server->config->listen_port->listener_ip, + server->config->listen_port->port)); goto err0; + } sock = silc_realloc(sock, (sizeof(int *) * (sock_count + 1))); sock[sock_count] = tmp; diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index 8c950acb..67dfff2b 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -778,7 +778,7 @@ static bool silc_client_packet_parse(SilcPacketParserContext *parser_context, SilcPacketContext *packet = parser_context->packet; SilcPacketType ret; - if (conn && conn->hmac_receive) + if (conn && conn->hmac_receive && conn->sock == sock) conn->psn_receive = parser_context->packet->sequence + 1; /* Parse the packet immediately */ @@ -1231,6 +1231,8 @@ void silc_client_close_connection(SilcClient client, { int del = FALSE; + SILC_LOG_DEBUG(("Start")); + if (!sock || (sock && conn->sock == sock)) del = TRUE; if (!sock) @@ -1339,6 +1341,22 @@ void silc_client_close_connection(SilcClient client, silc_socket_free(sock); } +/* Called when we receive disconnection packet from server. This + closes our end properly and displays the reason of the disconnection + on the screen. */ + +SILC_TASK_CALLBACK(silc_client_disconnected_by_server_later) +{ + SilcClient client = (SilcClient)context; + SilcSocketConnection sock; + + SILC_CLIENT_GET_SOCK(client, fd, sock); + if (sock == NULL) + return; + + silc_client_close_connection(client, sock, sock->user_data); +} + /* Called when we receive disconnection packet from server. This closes our end properly and displays the reason of the disconnection on the screen. */ @@ -1357,7 +1375,12 @@ void silc_client_disconnected_by_server(SilcClient client, silc_free(msg); SILC_SET_DISCONNECTED(sock); - silc_client_close_connection(client, sock, sock->user_data); + + /* 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. diff --git a/lib/silcclient/client_ftp.c b/lib/silcclient/client_ftp.c index 1ea2dc90..7f85a8db 100644 --- a/lib/silcclient/client_ftp.c +++ b/lib/silcclient/client_ftp.c @@ -477,13 +477,22 @@ SILC_TASK_CALLBACK(silc_client_ftp_key_agreement_final) ctx->ske->prop->group, ctx->responder); - /* If we are the SFTP client then start the SFTP session and retrieve - the info about the file available for download. */ if (!session->server) { + /* If we are the SFTP client then start the SFTP session and retrieve + the info about the file available for download. */ session->sftp = silc_sftp_client_start(conn->sock, silc_client_ftp_send_packet, session, silc_client_ftp_version, session); + } else { + /* Start SFTP server */ + session->sftp = silc_sftp_server_start(conn->sock, + silc_client_ftp_send_packet, + session, session->fs); + + /* Monitor transmission */ + silc_sftp_server_set_monitor(session->sftp, SILC_SFTP_MONITOR_READ, + silc_client_ftp_monitor, session); } /* Set this as active session */ @@ -532,17 +541,6 @@ static void silc_client_ftp_start_key_agreement(SilcClientFtpSession session, conn->sock->port = silc_net_get_remote_port(sock); session->sock = silc_socket_dup(conn->sock); - /* Allocate the SFTP */ - if (session->server) { - session->sftp = silc_sftp_server_start(conn->sock, - silc_client_ftp_send_packet, - session, session->fs); - - /* Monitor transmission */ - silc_sftp_server_set_monitor(session->sftp, SILC_SFTP_MONITOR_READ, - silc_client_ftp_monitor, session); - } - /* Allocate internal context for key exchange protocol. This is sent as context for the protocol. */ proto_ctx = silc_calloc(1, sizeof(*proto_ctx)); @@ -777,6 +775,8 @@ uint32 silc_client_file_send(SilcClient client, SilcClientConnection conn, SilcClientFileMonitor monitor, void *monitor_context, + const char *local_ip, + uint32 local_port, SilcClientEntry client_entry, const char *filepath) { @@ -822,8 +822,29 @@ uint32 silc_client_file_send(SilcClient client, session->filesize = silc_file_size(filepath); + /* Create the listener for incoming key exchange protocol. */ + if (local_ip) + session->hostname = strdup(local_ip); + else + session->hostname = silc_net_localip(); + session->listener = silc_net_create_server(local_port, session->hostname); + if (session->listener < 0) { + /* Could not create listener. Do the second best thing; send empty + key agreement packet and let the remote client provide the point + for the key exchange. */ + SILC_LOG_DEBUG(("Could not create listener")); + silc_free(session->hostname); + session->hostname = NULL; + } else { + /* Listener ready */ + session->port = silc_net_get_local_port(session->listener); + silc_schedule_task_add(client->schedule, session->listener, + silc_client_ftp_process_key_agreement, session, + 0, 0, SILC_TASK_FD, SILC_TASK_PRI_NORMAL); + } + /* Send the key agreement inside FTP packet */ - keyagr = silc_key_agreement_payload_encode(NULL, 0); + keyagr = silc_key_agreement_payload_encode(session->hostname, session->port); ftp = silc_buffer_alloc(1 + keyagr->len); silc_buffer_pull_tail(ftp, SILC_BUFFER_END(ftp)); @@ -897,6 +918,9 @@ silc_client_file_receive(SilcClient client, session->listener = silc_net_create_server(0, session->hostname); if (session->listener < 0) { SILC_LOG_DEBUG(("Could not create listener")); + client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR, + "Cannot create listener on %s: %s", + session->hostname, strerror(errno)); return SILC_CLIENT_FILE_ERROR; } session->port = silc_net_get_local_port(session->listener); diff --git a/lib/silcclient/silcapi.h b/lib/silcclient/silcapi.h index ccc360e5..175af9bc 100644 --- a/lib/silcclient/silcapi.h +++ b/lib/silcclient/silcapi.h @@ -1847,6 +1847,14 @@ typedef void (*SilcClientFileMonitor)(SilcClient client, * file indicated by the `filepath' is being transmitted to the remote * client indicated by the `client_entry', already. * + * If the `local_ip' is provided then this will try to bind the + * listener for key exchange protocol to that IP. If `local_port' is + * non-zero that port is used. If `local_ip' is NULL then this will + * automatically attempt to bind it to local IP address of the machine. + * If that fails then this does not bind to any address and port, and + * assume that the remote client will provide the listener for the + * key exchange protocol. + * * If error will occur during the file transfer process the error * status will be returned in the monitor callback. In this case * the application must call silc_client_file_close to close the @@ -1857,6 +1865,8 @@ uint32 silc_client_file_send(SilcClient client, SilcClientConnection conn, SilcClientFileMonitor monitor, void *monitor_context, + const char *local_ip, + uint32 local_port, SilcClientEntry client_entry, const char *filepath); diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index d18781a4..63979473 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -332,8 +332,11 @@ void silc_packet_receive_process(SilcSocketConnection sock, { SilcPacketParserContext *parse_ctx; int packetlen, paddedlen, mac_len = 0; - int block_len = cipher ? silc_cipher_get_block_len(cipher) : 0; bool cont = TRUE; + + /* Do not process for disconnected connection */ + if (SILC_IS_DISCONNECTED(sock)) + return; if (sock->inbuf->len < SILC_PACKET_MIN_HEADER_LEN) return; @@ -386,7 +389,8 @@ void silc_packet_receive_process(SilcSocketConnection sock, paddedlen + mac_len); SILC_LOG_HEXDUMP(("Incoming packet (%d) (%dB decrypted), len %d", - sequence - 1, block_len, paddedlen + mac_len), + sequence - 1, SILC_PACKET_MIN_HEADER_LEN, + paddedlen + mac_len), sock->inbuf->data, paddedlen + mac_len); /* Check whether this is normal or special packet */ diff --git a/lib/silcutil/silcnet.c b/lib/silcutil/silcnet.c index 2cdac41a..24cd5626 100644 --- a/lib/silcutil/silcnet.c +++ b/lib/silcutil/silcnet.c @@ -246,7 +246,7 @@ char *silc_net_localip(void) if (!dest) return NULL; - SILC_GET32_LSB(ip.s_addr, dest->h_addr_list[0]); + memcpy(&ip.s_addr, dest->h_addr_list[0], 4); ips = inet_ntoa(ip); return strdup(ips); diff --git a/lib/silcutil/unix/silcunixnet.c b/lib/silcutil/unix/silcunixnet.c index f2390057..cc8a26b6 100644 --- a/lib/silcutil/unix/silcunixnet.c +++ b/lib/silcutil/unix/silcunixnet.c @@ -66,7 +66,7 @@ int silc_net_create_server(int port, char *ip_addr) /* Bind the server socket */ rval = bind(sock, (struct sockaddr *)&server, sizeof(server)); if (rval < 0) { - SILC_LOG_ERROR(("Cannot bind socket: %s", strerror(errno))); + SILC_LOG_DEBUG(("Cannot bind socket: %s", strerror(errno))); return -1; } -- 2.24.0