updates.
authorPekka Riikonen <priikone@silcnet.org>
Fri, 2 Nov 2001 16:58:56 +0000 (16:58 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Fri, 2 Nov 2001 16:58:56 +0000 (16:58 +0000)
CHANGES
apps/irssi/docs/help/in/file.in
apps/irssi/src/silc/core/silc-servers.c
apps/silcd/server.c
lib/silcclient/client.c
lib/silcclient/client_ftp.c
lib/silcclient/silcapi.h
lib/silccore/silcpacket.c
lib/silcutil/silcnet.c
lib/silcutil/unix/silcunixnet.c

diff --git a/CHANGES b/CHANGES
index 1aff35ca6e504b8e80a215c5ebee1cf6ab50cf4e..a16325a958e8087af660a62e66623b4af89e296f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,11 @@
+Fri Nov  2 18:52:08 EST 2001  Pekka Riikonen <priikone@silcnet.org>
+
+       * 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 <priikone@silcnet.org>
 
        * Defined to WHOIS command reply the sending of fingerprint
 Thu Nov  1 22:10:07 EST 2001  Pekka Riikonen <priikone@silcnet.org>
 
        * Defined to WHOIS command reply the sending of fingerprint
index a7a07ee56c4747563e7bdec707e845672b0252bd..4e85a92c77d68184370d94c0ba8858beb69a2aca 100644 (file)
@@ -14,18 +14,27 @@ giving the FILE command without arguments.
 
 Commands:
 
 
 Commands:
 
-    SEND       <filepath> <nickname>
+    SEND     <filepath> <nickname> [<local IP> [<local port>]]
 
       Sends file transfer request to <nickname>.  This
       makes the <filepath> available to <nickname>.
 
 
       Sends file transfer request to <nickname>.  This
       makes the <filepath> available to <nickname>.
 
-    RECEIVE    [<nickname>]
+      If the <local IP> is provided then the key exchange
+      protocol listener will be bound to that address.  If
+      <local port> 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 <nickname> is assumed to provide the
+      listener.  If you do not know whether you need to
+      provide <local IP> or not, do not provide it.
+
+    RECEIVE  [<nickname>]
 
       Accepts the file transfer request and starts
       the file transfer session.  If the <nickname> is
       omitted the last received request is used.
 
 
       Accepts the file transfer request and starts
       the file transfer session.  If the <nickname> is
       omitted the last received request is used.
 
-    CLOSE      [<nickname>]
+    CLOSE    [<nickname>]
 
       Closes the file transfer session, or rejects
       file transfer request.  If this command is given
 
       Closes the file transfer session, or rejects
       file transfer request.  If this command is given
index 8da657014ab130e4c6ea6ec86bfe7c5a9fba4822..f9f5854f20f26d002658adeba1c513fc947f534d 100644 (file)
@@ -308,7 +308,7 @@ char *silc_server_get_channels(SILC_SERVER_REC *server)
 /* SYNTAX: PING */
 /* SYNTAX: SCONNECT <server> [<port>] */
 /* SYNTAX: USERS <channel> */
 /* SYNTAX: PING */
 /* SYNTAX: SCONNECT <server> [<port>] */
 /* SYNTAX: USERS <channel> */
-/* SYNTAX: FILE SEND <filepath> <nickname> */
+/* SYNTAX: FILE SEND <filepath> <nickname> [<local IP> [<local port>]] */
 /* SYNTAX: FILE RECEIVE [<nickname>] */
 /* SYNTAX: FILE CLOSE [<nickname>] */
 /* SYNTAX: FILE */
 /* SYNTAX: FILE RECEIVE [<nickname>] */
 /* SYNTAX: FILE CLOSE [<nickname>] */
 /* 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;
   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);
 
   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);
 
   /* 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)
   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);
 
     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, 
     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,
 
     printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
                       SILCTXT_FILE_SEND, client_entry->nickname,
index 33b93d63132c59b706204afd35ee7cd44c5a04d7..31ae88774e476c065cd8b322172ff6f0be89bfdb 100644 (file)
@@ -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);
 
     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;
       goto err0;
+    }
 
     sock = silc_realloc(sock, (sizeof(int *) * (sock_count + 1)));
     sock[sock_count] = tmp;
 
     sock = silc_realloc(sock, (sizeof(int *) * (sock_count + 1)));
     sock[sock_count] = tmp;
index 8c950acb0f8baa70ea47720479f0bf730aef3145..67dfff2b78b622a05e791036977e6b9759ddda66 100644 (file)
@@ -778,7 +778,7 @@ static bool silc_client_packet_parse(SilcPacketParserContext *parser_context,
   SilcPacketContext *packet = parser_context->packet;
   SilcPacketType ret;
 
   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 */
     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;
 
 {
   int del = FALSE;
 
+  SILC_LOG_DEBUG(("Start"));
+
   if (!sock || (sock && conn->sock == sock))
     del = TRUE;
   if (!sock)
   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);
 }
 
   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. */
 /* 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_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. 
 }
 
 /* Received error message from server. Display it on the screen. 
index 1ea2dc908ff7e3b463a7d1c8852aea7a8e3215ac..7f85a8db9e03b6176e6fe8f18c20bd6b3eec8e89 100644 (file)
@@ -477,13 +477,22 @@ SILC_TASK_CALLBACK(silc_client_ftp_key_agreement_final)
                                   ctx->ske->prop->group,
                                   ctx->responder);
 
                                   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 (!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);
     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 */
   }
 
   /* 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);
 
   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));
   /* 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,
                             SilcClientConnection conn,
                             SilcClientFileMonitor monitor,
                             void *monitor_context,
+                            const char *local_ip,
+                            uint32 local_port,
                             SilcClientEntry client_entry,
                             const char *filepath)
 {
                             SilcClientEntry client_entry,
                             const char *filepath)
 {
@@ -822,8 +822,29 @@ uint32 silc_client_file_send(SilcClient client,
 
   session->filesize = silc_file_size(filepath);
 
 
   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 */
   /* 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));
 
   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"));
     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);
       return SILC_CLIENT_FILE_ERROR;
     }
     session->port = silc_net_get_local_port(session->listener);
index ccc360e562a011ed33a18d81eee3d5d9133698eb..175af9bca4bcbeea53e56a4f803a485249af37cc 100644 (file)
@@ -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.
  *
  *    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
  *    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,
                             SilcClientConnection conn,
                             SilcClientFileMonitor monitor,
                             void *monitor_context,
+                            const char *local_ip,
+                            uint32 local_port,
                             SilcClientEntry client_entry,
                             const char *filepath);
 
                             SilcClientEntry client_entry,
                             const char *filepath);
 
index d18781a4807725c2c92a506742356e41df9eee12..639794738e8d712e36ba61a8ea8cd03b4f01d9ab 100644 (file)
@@ -332,8 +332,11 @@ void silc_packet_receive_process(SilcSocketConnection sock,
 {
   SilcPacketParserContext *parse_ctx;
   int packetlen, paddedlen, mac_len = 0;
 {
   SilcPacketParserContext *parse_ctx;
   int packetlen, paddedlen, mac_len = 0;
-  int block_len = cipher ? silc_cipher_get_block_len(cipher) : 0;
   bool cont = TRUE;
   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;
   
   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", 
                    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 */
                     sock->inbuf->data, paddedlen + mac_len);
 
     /* Check whether this is normal or special packet */
index 2cdac41ab2e0063f1b4bbb8827489d47cd3cc72a..24cd562641286d6ad6e90937a41e1de74791c419 100644 (file)
@@ -246,7 +246,7 @@ char *silc_net_localip(void)
   if (!dest)
     return NULL;
 
   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);
   ips = inet_ntoa(ip);
 
   return strdup(ips);
index f2390057f013544f51ade6952df92117ed488ba0..cc8a26b63ff38a8f89af9d65739a88b7dcaef98f 100644 (file)
@@ -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) {
   /* 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;
   }
 
     return -1;
   }