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
index a7a07ee56c4747563e7bdec707e845672b0252bd..4e85a92c77d68184370d94c0ba8858beb69a2aca 100644 (file)
@@ -14,18 +14,27 @@ giving the FILE command without arguments.
 
 Commands:
 
-    SEND       <filepath> <nickname>
+    SEND     <filepath> <nickname> [<local IP> [<local port>]]
 
       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.
 
-    CLOSE      [<nickname>]
+    CLOSE    [<nickname>]
 
       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: FILE SEND <filepath> <nickname> */
+/* SYNTAX: FILE SEND <filepath> <nickname> [<local IP> [<local port>]] */
 /* 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;
+  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,
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);
-    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;
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;
 
-  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. 
index 1ea2dc908ff7e3b463a7d1c8852aea7a8e3215ac..7f85a8db9e03b6176e6fe8f18c20bd6b3eec8e89 100644 (file)
@@ -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);
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.
  *
+ *    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);
 
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;
-  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 */
index 2cdac41ab2e0063f1b4bbb8827489d47cd3cc72a..24cd562641286d6ad6e90937a41e1de74791c419 100644 (file)
@@ -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);
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) {
-    SILC_LOG_ERROR(("Cannot bind socket: %s", strerror(errno)));
+    SILC_LOG_DEBUG(("Cannot bind socket: %s", strerror(errno)));
     return -1;
   }