Develop and Download Open Source Software

Browse Subversion Repository

Diff of /trunk/ttssh2/ttxssh/pkt.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3221 by maya, Tue Mar 24 09:37:20 2009 UTC revision 10960 by zmatsuo, Sat Oct 7 17:40:35 2023 UTC
# Line 1  Line 1 
1  /*  /*
2  Copyright (c) 1998-2001, Robert O'Callahan   * Copyright (c) 1998-2001, Robert O'Callahan
3  All rights reserved.   * (C) 2004- TeraTerm Project
4     * All rights reserved.
5  Redistribution and use in source and binary forms, with or without modification,   *
6  are permitted provided that the following conditions are met:   * Redistribution and use in source and binary forms, with or without
7     * modification, are permitted provided that the following conditions
8  Redistributions of source code must retain the above copyright notice, this list of   * are met:
9  conditions and the following disclaimer.   *
10     * 1. Redistributions of source code must retain the above copyright
11  Redistributions in binary form must reproduce the above copyright notice, this list   *    notice, this list of conditions and the following disclaimer.
12  of conditions and the following disclaimer in the documentation and/or other materials   * 2. Redistributions in binary form must reproduce the above copyright
13  provided with the distribution.   *    notice, this list of conditions and the following disclaimer in the
14     *    documentation and/or other materials provided with the distribution.
15  The name of Robert O'Callahan may not be used to endorse or promote products derived from   * 3. The name of the author may not be used to endorse or promote products
16  this software without specific prior written permission.   *    derived from this software without specific prior written permission.
17     *
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND   * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,   * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  */   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28     */
29  /*  
30  This code is copyright (C) 1998-1999 Robert O'Callahan.  /*
31  See LICENSE.TXT for the license.  This code is copyright (C) 1998-1999 Robert O'Callahan.
32  */  See LICENSE.TXT for the license.
33    */
34  #include "ttxssh.h"  
35  #include "util.h"  #include "ttxssh.h"
36  #include "pkt.h"  #include "util.h"
37    #include "pkt.h"
38  //#define READAMOUNT 60000  
39  // 60000 -> 65536 へ拡張。SSH2ではwindow制御を行うため、SSH2のwindow sizeと  #define READAMOUNT CHAN_SES_WINDOW_DEFAULT
40  // 合わせておく必要がある。(2004.10.17 yutaka)  
41  //#define READAMOUNT 65536  void PKT_init(PTInstVar pvar)
42  // 65536 -> 131072 へ拡張。(2007.10.29 maya)  {
43  #define READAMOUNT CHAN_SES_WINDOW_DEFAULT          buf_create(&pvar->pkt_state.buf, &pvar->pkt_state.buflen);
44            pvar->pkt_state.datastart = 0;
45  void PKT_init(PTInstVar pvar)          pvar->pkt_state.datalen = 0;
46  {          pvar->pkt_state.seen_server_ID = FALSE;
47          buf_create(&pvar->pkt_state.buf, &pvar->pkt_state.buflen);          pvar->pkt_state.seen_newline = FALSE;
48          pvar->pkt_state.datastart = 0;          pvar->pkt_state.predecrypted_packet = FALSE;
49          pvar->pkt_state.datalen = 0;  }
50          pvar->pkt_state.seen_server_ID = FALSE;  
51          pvar->pkt_state.seen_newline = FALSE;  /* Read some data, leave no more than up_to_amount bytes in the buffer,
52          pvar->pkt_state.predecrypted_packet = FALSE;     return the number of bytes read or -1 on error or blocking. */
53  }  static int recv_data(PTInstVar pvar, unsigned long up_to_amount)
54    {
55  /* Read some data, leave no more than up_to_amount bytes in the buffer,          int amount_read;
56     return the number of bytes read or -1 on error or blocking. */  
57  static int recv_data(PTInstVar pvar, unsigned long up_to_amount)          /* Shuffle data to the start of the buffer */
58  {          if (pvar->pkt_state.datastart != 0) {
59          int amount_read;                  memmove(pvar->pkt_state.buf,
60                            pvar->pkt_state.buf + pvar->pkt_state.datastart,
61          /* Shuffle data to the start of the buffer */                          pvar->pkt_state.datalen);
62          if (pvar->pkt_state.datastart != 0) {                  pvar->pkt_state.datastart = 0;
63                  memmove(pvar->pkt_state.buf,          }
64                          pvar->pkt_state.buf + pvar->pkt_state.datastart,  
65                          pvar->pkt_state.datalen);          buf_ensure_size(&pvar->pkt_state.buf, &pvar->pkt_state.buflen, up_to_amount);
66                  pvar->pkt_state.datastart = 0;  
67          }          _ASSERT(pvar->pkt_state.buf != NULL);
68    
69          buf_ensure_size(&pvar->pkt_state.buf, &pvar->pkt_state.buflen,          amount_read = (pvar->Precv) (pvar->socket,
70                          up_to_amount);                                       pvar->pkt_state.buf + pvar->pkt_state.datalen,
71                                         up_to_amount - pvar->pkt_state.datalen,
72          _ASSERT(pvar->pkt_state.buf != NULL);                                       0);
73    
74          amount_read = (pvar->Precv) (pvar->socket,          if (amount_read > 0) {
75                                       pvar->pkt_state.buf +                  /* Update seen_newline if necessary */
76                                       pvar->pkt_state.datalen,                  if (!pvar->pkt_state.seen_server_ID && !pvar->pkt_state.seen_newline) {
77                                       up_to_amount - pvar->pkt_state.datalen,                          int i;
78                                       0);  
79                            for (i = 0; i < amount_read; i++) {
80          if (amount_read > 0) {                                  if (pvar->pkt_state.buf[pvar->pkt_state.datalen + i] == '\n') {
81                  /* Update seen_newline if necessary */                                          pvar->pkt_state.seen_newline = 1;
82                  if (!pvar->pkt_state.seen_server_ID                                  }
83                   && !pvar->pkt_state.seen_newline) {                          }
84                          int i;                  }
85                    pvar->pkt_state.datalen += amount_read;
86                          for (i = 0; i < amount_read; i++) {          }
87                                  if (pvar->pkt_state.buf[pvar->pkt_state.datalen + i] ==  
88                                      '\n') {          return amount_read;
89                                          pvar->pkt_state.seen_newline = 1;  }
90                                  }  
91                          }  // 改行コードが出てくるまで読む
92                  }  static int recv_line_data(PTInstVar pvar)
93    {
94                  pvar->pkt_state.datalen += amount_read;          int amount_read;
95          }          char buf[256];
96            size_t up_to_amount = sizeof(buf);
97          return amount_read;          int i;
98  }  
99            /* Shuffle data to the start of the buffer */
100            if (pvar->pkt_state.datastart != 0) {
101  // 改行コードが出てくるまで読む                  memmove(pvar->pkt_state.buf,
102  static int recv_line_data(PTInstVar pvar)                          pvar->pkt_state.buf + pvar->pkt_state.datastart,
103  {                          pvar->pkt_state.datalen);
104          int amount_read;                  pvar->pkt_state.datastart = 0;
105          char buf[256];          }
106          size_t up_to_amount = sizeof(buf);  
107          int i;          buf_ensure_size(&pvar->pkt_state.buf, &pvar->pkt_state.buflen, up_to_amount);
108    
109          /* Shuffle data to the start of the buffer */          for (i = 0 ; i < (int)up_to_amount ; i++) {
110          if (pvar->pkt_state.datastart != 0) {                  amount_read = (pvar->Precv) (pvar->socket, &buf[i], 1, 0);
111                  memmove(pvar->pkt_state.buf,                  if (amount_read != 1) {
112                          pvar->pkt_state.buf + pvar->pkt_state.datastart,                          return 0; // error
113                          pvar->pkt_state.datalen);                  }
114                  pvar->pkt_state.datastart = 0;  
115          }                  pvar->pkt_state.datalen += amount_read;
116    
117          buf_ensure_size(&pvar->pkt_state.buf, &pvar->pkt_state.buflen,                  if (buf[i] == '\n') { // 0x0a
118                          up_to_amount);                          buf[i+1] = 0;
119                            break;
120          for (i = 0 ; i < (int)up_to_amount ; i++) {                  }
121                  amount_read = (pvar->Precv) (pvar->socket,          }
122                                               &buf[i], 1, 0);          amount_read = i + 1; // 読み込みサイズ(LFも含む)
123                  if (amount_read != 1) {          memcpy(pvar->pkt_state.buf, buf, amount_read);
124                          return 0; // error  
125                  }          pvar->pkt_state.seen_newline = 1;
126    
127                  pvar->pkt_state.datalen += amount_read;          return amount_read;
128    }
129                  if (buf[i] == '\n') { // 0x0a  
130                          buf[i+1] = 0;  /* This function does two things:
131                          break;     -- reads data from the sshd and feeds the SSH protocol packets to ssh.c
132                  }     -- copies any available decrypted session data into the application buffer
133          }  */
134          amount_read = i + 1; // 読み込みサイズ(LFも含む)  int PKT_recv(PTInstVar pvar, char *buf, int buflen)
135          memcpy(pvar->pkt_state.buf, buf, amount_read);  {
136            int amount_in_buf = 0;
137          pvar->pkt_state.seen_newline = 1;          BOOL connection_closed = FALSE;
138    
139          return amount_read;          while (SSH_is_any_payload(pvar) ? buflen > 0 : !connection_closed) {
140  }                  if (SSH_is_any_payload(pvar)) {
141                            /* ssh.c has some session data for us to give to Tera Term. */
142                            int grabbed = SSH_extract_payload(pvar, buf, buflen);
143  /* This function does two things:  
144     -- reads data from the sshd and feeds the SSH protocol packets to ssh.c                          amount_in_buf += grabbed;
145     -- copies any available decrypted session data into the application buffer                          buf += grabbed;
146  */                          buflen -= grabbed;
147  int PKT_recv(PTInstVar pvar, char FAR * buf, int buflen)                  }
148  {                  else if (!pvar->pkt_state.seen_server_ID && (pvar->pkt_state.seen_newline || pvar->pkt_state.datalen >= 255)) {
149          int amount_in_buf = 0;                          /*
150          BOOL connection_closed = FALSE;                           * We're looking for the initial ID string and either we've seen the
151                             * terminating newline, or we've exceeded the limit at which we should see a newline.
152          while (SSH_is_any_payload(pvar) ? buflen > 0 : !connection_closed) {                           */
153                  if (SSH_is_any_payload(pvar)) {                          unsigned int i;
154                          /* ssh.c has some session data for us to give to Tera Term. */  
155                          int grabbed = SSH_extract_payload(pvar, buf, buflen);                          for (i = 0; pvar->pkt_state.buf[i] != '\n' && i < pvar->pkt_state.datalen; i++) {
156                            }
157                          amount_in_buf += grabbed;                          if (pvar->pkt_state.buf[i] == '\n') {
158                          buf += grabbed;                                  i++;
159                          buflen -= grabbed;                          }
160    
161                  } else if (!pvar->pkt_state.seen_server_ID &&                          // SSHサーバのバージョンチェックを行う
162                             (pvar->pkt_state.seen_newline                          if (SSH_handle_server_ID(pvar, pvar->pkt_state.buf, i)) {
163                              || pvar->pkt_state.datalen >= 255)) {                                  pvar->pkt_state.seen_server_ID = 1;
164                          /* We're looking for the initial ID string and either we've seen the  
165                             terminating newline, or we've exceeded the limit at which we should see                                  if (SSHv2(pvar)) {
166                             a newline. */                                          // send Key Exchange Init
167                          unsigned int i;                                          SSH2_send_kexinit(pvar);
168                                    }
169                          for (i = 0;                          } else {
170                               pvar->pkt_state.buf[i] != '\n'                                  // reset flag to re-read server ID (2008.1.24 yutaka)
171                               && i < pvar->pkt_state.datalen; i++) {                                  pvar->pkt_state.seen_newline = 0;
172                          }                          }
173                          if (pvar->pkt_state.buf[i] == '\n') {  
174                                  i++;                          pvar->pkt_state.datastart += i;
175                          }                          pvar->pkt_state.datalen -= i;
176                    }
177                          // SSHサーバのバージョンチェックを行う                  else if (pvar->pkt_state.seen_server_ID && pvar->pkt_state.datalen >= SSH_get_min_packet_size(pvar)) {
178                          if (SSH_handle_server_ID(pvar, pvar->pkt_state.buf, i)) {                          char *data = pvar->pkt_state.buf + pvar->pkt_state.datastart;
179                                  pvar->pkt_state.seen_server_ID = 1;                          uint32 padding_size = 0;
180                            uint32 pktsize = 0;
181                                  if (SSHv1(pvar)) {                          uint32 total_packet_size;
182                            struct Mac *mac = &pvar->ssh2_keys[MODE_IN].mac;
183                                  } else { // for SSH2(yutaka)                          struct Enc *enc = &pvar->ssh2_keys[MODE_IN].enc;
184                                          // send Key Exchange Init                          int authlen = 0, aadlen = 0;
185                                          SSH2_send_kexinit(pvar);  
186                                  }                          if (SSHv2(pvar)) {
187                                    /*
188                          } else {                                   * pktsize
189                                  // reset flag to re-read server ID (2008.1.24 yutaka)                                   *   uint32   packet_length
190                                  pvar->pkt_state.seen_newline = 0;                                   * は
191                                     *   byte     padding_length
192                          }                                   *   byte[n1] payload; n1 = packet_length - padding_length - 1
193                                     *   byte[n2] random padding; n2 = padding_length
194                          pvar->pkt_state.datastart += i;                                   * の長さの合計で
195                          pvar->pkt_state.datalen -= i;                                   *   byte[m]  mac (Message Authentication Code - MAC); m = mac_length
196                                     * の長さを含まない。
197                  } else if (pvar->pkt_state.seen_server_ID                                   * cf. RFC 4253 6. Binary Packet Protocol
198                             && pvar->pkt_state.datalen >=                                   */
199                             (unsigned int) SSH_get_min_packet_size(pvar)) {  
200                          char FAR *data =                                  if (enc && enc->auth_len > 0) {
201                                  pvar->pkt_state.buf + pvar->pkt_state.datastart;                                          authlen = enc->auth_len;
202                          uint32 padding;                                  }
203                          uint32 pktsize;  
204                          uint32 total_packet_size;                                  /*
205                                     *                      |          | lead 4 bytes are encrypted | aadlen |
206                          //debug_print(10, data, pvar->pkt_state.datalen);                                   * Encryption type
207                                     *   enc->auth_len >  0 | AEAD     | AES-GCM ... no             | 4      |     (2)
208                          // SSH2なら暗号化パケットの一部を復号化する。                                   *                      |          | chacha20-poly1305 ... yes  | 4      | (1) (2)
209                          if (!pvar->pkt_state.predecrypted_packet) {                                   *   enc->auth_len == 0 | not AEAD | depends on MAC type        | <-     |
210                                  //DEBUG_PRINT_TO_FILE(0, data, pvar->pkt_state.datalen);                                   * MAC type
211                                  SSH_predecrpyt_packet(pvar, data);                                   *   mac->etm == true   | EtM      | no                         | 4      |
212                                     *   mac->etm == false  | E&M      | yes                        | 0      |
213                                  if (SSHv1(pvar)) {                                   * (1) lead 4 bytes are encrypted separately from main part.
214                                          pvar->pkt_state.predecrypted_packet = TRUE;                                   * (2) implicit MAC type of AEAD is EtM
215                                  } else { // for SSH2(yutaka)                                   */
216                                          // do nothing                                  /*
217                                          pvar->pkt_state.predecrypted_packet = TRUE;                                   * aadlen: Additional Authenticated Data Length
218                                  }                                   *   MAC の対象となるデータと一緒に暗号化されない、"MAC の対象となるデータの長さ"のサイズ
219                          }                                   *   この部分は packet_length で、uint32 (4バイト)
220                                     *
221                          if (SSHv1(pvar)) {                                   * - 通常の MAC 方式 (E&M) ではパケット長部分が一緒に暗号化されるので aadlen は 0 となる。
222                                  uint32 realpktsize = get_uint32_MSBfirst(data);                                   * - EtM 方式の MAC や AEAD の AES-GCM では、パケット長部分が暗号化されないので
223                                     * aadlen は 4 となる。
224                                  padding = 8 - (realpktsize % 8);                                   * - AEAD の chacha20-poly1305 ではパケット長部分が暗号化されるが、MAC の対象となるデータ
225                                  pktsize = realpktsize + padding;                                   * とは別に暗号化されるので aadlen は 4 となる。
226                          } else {                                   *
227                                  // SSH2のパケットは先頭に packet-size(4)+padding(1)+type(1) が続く。                                   */
228                                  pktsize = get_uint32_MSBfirst(data);                                  if ((mac && mac->etm) || authlen > 0) {
229                                  padding = (unsigned char) data[4];                                          aadlen = 4;
230                          }                                  }
231    
232                          // パケット(TCPペイロード)の全体のサイズは、SSHペイロード+4(+MAC)となる。                                  if (authlen > 0 &&
233                          // +4は、SSHペイロードのサイズを格納している部分(int型)。                                      pvar->cc[MODE_IN]->cipher->id == SSH2_CIPHER_CHACHAPOLY) {
234                          total_packet_size = pktsize + 4 + SSH_get_clear_MAC_size(pvar);                                          /*
235                                             * AEAD の chacha20-poly1305 ではパケット長部分が別に暗号化されている。
236                          if (total_packet_size <= pvar->pkt_state.datalen) {                                           * この処理は長さを取得するが、data は暗号化されたままとなる。
237                                  /* the data must be 4 byte aligned. */                                           */
238                                  SSH_handle_packet(pvar, data, pktsize, padding);                                          chachapoly_get_length(pvar->cc[MODE_IN]->cp_ctx, &pktsize,
239                                  pvar->pkt_state.predecrypted_packet = FALSE;                                                                pvar->ssh_state.receiver_sequence_number,
240                                                                  data, pvar->pkt_state.datalen);
241                                  pvar->pkt_state.datastart += total_packet_size;                                  }
242                                  pvar->pkt_state.datalen -= total_packet_size;                                  else if (authlen == 0 &&
243                                             aadlen == 0 &&
244                          } else if (total_packet_size > PACKET_MAX_SIZE) {                                           !pvar->pkt_state.predecrypted_packet && aadlen == 0) {
245                                  // 4MBを超える巨大なパケットが届いたら、異常終了する。                                          /*
246                                  // 実際にはデータ化けで復号失敗時に、誤認識することが多い。                                           * AEAD でなく E&M (aadlen が 0) の時は、暗号化されているパケット長を
247                                  UTIL_get_lang_msg("MSG_PKT_OVERSIZED_ERROR", pvar,                                           * 知る必要が有るため、先頭の 1 ブロックだけ事前に復号する。
248                                                                    "Oversized packet received from server; connection will close.");                                           */
249                                  notify_fatal_error(pvar, pvar->ts->UIMsg);                                          SSH_predecrypt_packet(pvar, data);
250                          } else {                                          pvar->pkt_state.predecrypted_packet = TRUE;
251                                  int amount_read =  
252                                          recv_data(pvar, max(total_packet_size, READAMOUNT));                                          pktsize = get_uint32_MSBfirst(data);
253                                    }
254                                  if (amount_read == SOCKET_ERROR) {                                  else {
255                                          if (amount_in_buf == 0) {                                          /*
256                                                  return SOCKET_ERROR;                                           * EtM 方式の MAC や、AEAD で AES-GCM のときなどはそのまま読める。
257                                          } else {                                           */
258                                                  return amount_in_buf;                                          pktsize = get_uint32_MSBfirst(data);
259                                          }                                  }
260                                  } else {                          }
261                                          if (amount_read == 0) {                          else {
262                                                  connection_closed = TRUE;                                  pktsize = get_uint32_MSBfirst(data);
263                                          }                          }
264                                  }  
265                          }                          if (SSHv1(pvar)) {
266                                    // SSH1 ではパケット長の値には padding の長さが含まれていない。
267                                    // また padding の長さの情報もパケット上には無いので、パケット長の値から計算する。
268                  } else {                                  padding_size = 8 - (pktsize % 8);
269                          // パケットの受信(最大60KB)  
270                          int amount_read;                                  // 以降の処理は pktsize に padding_size の値が含まれている事が前提となっている。
271                                    pktsize += padding_size;
272                          if (pvar->pkt_state.seen_server_ID == 0) {                          }
273                                  //amount_read = recv_line_data(pvar);  
274                                  amount_read = recv_data(pvar, READAMOUNT);                          // パケット(TCPペイロード)の全体のサイズは、
275                            // 4(パケット長のサイズ)+パケット長(+MACのサイズ)となる。
276                          } else {                          total_packet_size = 4 + pktsize + SSH_get_authdata_size(pvar, MODE_IN);
277                                  amount_read = recv_data(pvar, READAMOUNT);  
278                            if (total_packet_size <= pvar->pkt_state.datalen) {
279                          }                                  // 受信済みデータが十分有る場合はパケットの実処理を行う
280                                    if (SSHv1(pvar)) {
281                          if (amount_read == SOCKET_ERROR) {                                          // SSH1 は EtM 非対応 (そもそも MAC ではなく CRC を使う)
282                                  if (amount_in_buf == 0) {                                          SSH1_handle_packet(pvar, data, pktsize, padding_size);
283                                          return SOCKET_ERROR;                                  }
284                                  } else {                                  else {
285                                          return amount_in_buf;                                          // SSH2 ではこの時点では padding 長部分が復号されていない場合があるので、
286                                  }                                          // padding 長は渡さずに、必要になった時に内部で取得する。
287                          } else if (amount_read == 0) {                                          SSH2_handle_packet(pvar, data, pktsize, aadlen, authlen);
288                                  connection_closed = TRUE;                                  }
289                          }  
290                  }                                  pvar->pkt_state.predecrypted_packet = FALSE;
291                                    pvar->pkt_state.datastart += total_packet_size;
292                  if (pvar->fatal_error) {                                  pvar->pkt_state.datalen -= total_packet_size;
293                          return amount_in_buf;  
294                  }                          }
295          }                          else if (total_packet_size > PACKET_MAX_SIZE) {
296                                    // パケット長が大きすぎる場合は異常終了する。
297          if (SSH_is_any_payload(pvar)) {                                  // 実際には何らかの要因で復号失敗⇒パケット長部分が壊れている事が多い。
298                  PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY,                                  UTIL_get_lang_msg("MSG_PKT_OVERSIZED_ERROR", pvar,
299                              pvar->socket, MAKELPARAM(FD_READ, 0));                                                    "Oversized packet received from server; connection will close.");
300          }                                  notify_fatal_error(pvar, pvar->UIMsg, TRUE);
301                            }
302          return amount_in_buf;                          else {
303  }                                  int amount_read = recv_data(pvar, max(total_packet_size, READAMOUNT));
304    
305  void PKT_end(PTInstVar pvar)                                  if (amount_read == SOCKET_ERROR) {
306  {                                          if (amount_in_buf == 0) {
307          buf_destroy(&pvar->pkt_state.buf, &pvar->pkt_state.buflen);                                                  return SOCKET_ERROR;
308  }                                          } else {
309                                                    return amount_in_buf;
310                                            }
311                                    } else {
312                                            if (amount_read == 0) {
313                                                    connection_closed = TRUE;
314                                            }
315                                    }
316                            }
317                    } else {
318                            // パケットの受信
319                            int amount_read;
320    
321                            // SCPファイル受信処理を一時停止中ならば、recv()をしない。
322                            if (pvar->recv.suspended) {
323                                    // それまでに受信したデータサイズをTera Term側に返す。
324                                    return amount_in_buf;
325    
326                            }
327    
328                            amount_read = recv_data(pvar, READAMOUNT);
329    
330                            if (amount_read == SOCKET_ERROR) {
331                                    if (amount_in_buf == 0) {
332                                            return SOCKET_ERROR;
333                                    } else {
334                                            return amount_in_buf;
335                                    }
336                            } else if (amount_read == 0) {
337                                    connection_closed = TRUE;
338                            }
339                    }
340    
341                    if (pvar->fatal_error) {
342                            return amount_in_buf;
343                    }
344            }
345    
346            if (SSH_is_any_payload(pvar)) {
347                    PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY, pvar->socket, MAKELPARAM(FD_READ, 0));
348            }
349    
350            return amount_in_buf;
351    }
352    
353    void PKT_end(PTInstVar pvar)
354    {
355            buf_destroy(&pvar->pkt_state.buf, &pvar->pkt_state.buflen);
356    }

Legend:
Removed from v.3221  
changed lines
  Added in v.10960

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26