Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3215 - (hide annotations) (download) (as text)
Wed Mar 4 11:40:44 2009 UTC (15 years, 1 month ago) by yutakapon
File MIME type: text/x-csrc
File size: 8983 byte(s)
最大パケットサイズをマクロ定義した。

1 yutakakn 2728 /*
2     Copyright (c) 1998-2001, Robert O'Callahan
3     All rights reserved.
4    
5     Redistribution and use in source and binary forms, with or without modification,
6     are permitted provided that the following conditions are met:
7    
8     Redistributions of source code must retain the above copyright notice, this list of
9     conditions and the following disclaimer.
10    
11     Redistributions in binary form must reproduce the above copyright notice, this list
12     of conditions and the following disclaimer in the documentation and/or other materials
13     provided with the distribution.
14    
15     The name of Robert O'Callahan may not be used to endorse or promote products derived from
16     this software without specific prior written permission.
17    
18     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19     ANY EXPRESS OR 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
21     THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27     */
28    
29     /*
30     This code is copyright (C) 1998-1999 Robert O'Callahan.
31     See LICENSE.TXT for the license.
32     */
33    
34     #include "ttxssh.h"
35     #include "util.h"
36 yutakapon 3215 #include "pkt.h"
37 yutakakn 2728
38     //#define READAMOUNT 60000
39     // 60000 -> 65536 ���g���BSSH2����window�������s�������ASSH2��window size��
40     // �������������K�v�������B(2004.10.17 yutaka)
41 maya 3057 //#define READAMOUNT 65536
42     // 65536 -> 131072 ���g���B(2007.10.29 maya)
43     #define READAMOUNT CHAN_SES_WINDOW_DEFAULT
44 yutakakn 2728
45     void PKT_init(PTInstVar pvar)
46     {
47     buf_create(&pvar->pkt_state.buf, &pvar->pkt_state.buflen);
48     pvar->pkt_state.datastart = 0;
49     pvar->pkt_state.datalen = 0;
50     pvar->pkt_state.seen_server_ID = FALSE;
51     pvar->pkt_state.seen_newline = FALSE;
52     pvar->pkt_state.predecrypted_packet = FALSE;
53     }
54    
55     /* Read some data, leave no more than up_to_amount bytes in the buffer,
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)
58     {
59     int amount_read;
60    
61     /* Shuffle data to the start of the buffer */
62     if (pvar->pkt_state.datastart != 0) {
63     memmove(pvar->pkt_state.buf,
64 maya 3003 pvar->pkt_state.buf + pvar->pkt_state.datastart,
65     pvar->pkt_state.datalen);
66 yutakakn 2728 pvar->pkt_state.datastart = 0;
67     }
68    
69     buf_ensure_size(&pvar->pkt_state.buf, &pvar->pkt_state.buflen,
70 maya 3003 up_to_amount);
71 yutakakn 2728
72     _ASSERT(pvar->pkt_state.buf != NULL);
73    
74     amount_read = (pvar->Precv) (pvar->socket,
75 maya 3003 pvar->pkt_state.buf +
76     pvar->pkt_state.datalen,
77     up_to_amount - pvar->pkt_state.datalen,
78     0);
79 yutakakn 2728
80     if (amount_read > 0) {
81     /* Update seen_newline if necessary */
82     if (!pvar->pkt_state.seen_server_ID
83 maya 3003 && !pvar->pkt_state.seen_newline) {
84 yutakakn 2728 int i;
85    
86     for (i = 0; i < amount_read; i++) {
87     if (pvar->pkt_state.buf[pvar->pkt_state.datalen + i] ==
88 maya 3003 '\n') {
89 yutakakn 2728 pvar->pkt_state.seen_newline = 1;
90     }
91     }
92     }
93    
94     pvar->pkt_state.datalen += amount_read;
95     }
96    
97     return amount_read;
98     }
99    
100    
101     // ���s�R�[�h���o��������������
102     static int recv_line_data(PTInstVar pvar)
103     {
104     int amount_read;
105     char buf[256];
106     size_t up_to_amount = sizeof(buf);
107     int i;
108    
109     /* Shuffle data to the start of the buffer */
110     if (pvar->pkt_state.datastart != 0) {
111     memmove(pvar->pkt_state.buf,
112 maya 3003 pvar->pkt_state.buf + pvar->pkt_state.datastart,
113     pvar->pkt_state.datalen);
114 yutakakn 2728 pvar->pkt_state.datastart = 0;
115     }
116    
117     buf_ensure_size(&pvar->pkt_state.buf, &pvar->pkt_state.buflen,
118 maya 3003 up_to_amount);
119 yutakakn 2728
120     for (i = 0 ; i < (int)up_to_amount ; i++) {
121     amount_read = (pvar->Precv) (pvar->socket,
122 maya 3003 &buf[i], 1, 0);
123 yutakakn 2728 if (amount_read != 1) {
124     return 0; // error
125     }
126    
127     pvar->pkt_state.datalen += amount_read;
128    
129     if (buf[i] == '\n') { // 0x0a
130     buf[i+1] = 0;
131     break;
132     }
133     }
134     amount_read = i + 1; // ���������T�C�Y�iLF�������j
135     memcpy(pvar->pkt_state.buf, buf, amount_read);
136    
137     pvar->pkt_state.seen_newline = 1;
138    
139     return amount_read;
140     }
141    
142    
143     /* This function does two things:
144     -- reads data from the sshd and feeds the SSH protocol packets to ssh.c
145     -- copies any available decrypted session data into the application buffer
146     */
147     int PKT_recv(PTInstVar pvar, char FAR * buf, int buflen)
148     {
149     int amount_in_buf = 0;
150     BOOL connection_closed = FALSE;
151    
152     while (SSH_is_any_payload(pvar) ? buflen > 0 : !connection_closed) {
153     if (SSH_is_any_payload(pvar)) {
154 doda 3134 /* ssh.c has some session data for us to give to Tera Term. */
155 yutakakn 2728 int grabbed = SSH_extract_payload(pvar, buf, buflen);
156    
157     amount_in_buf += grabbed;
158     buf += grabbed;
159     buflen -= grabbed;
160    
161     } else if (!pvar->pkt_state.seen_server_ID &&
162 maya 3003 (pvar->pkt_state.seen_newline
163     || pvar->pkt_state.datalen >= 255)) {
164 yutakakn 2728 /* 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
166     a newline. */
167     unsigned int i;
168    
169     for (i = 0;
170 maya 3003 pvar->pkt_state.buf[i] != '\n'
171     && i < pvar->pkt_state.datalen; i++) {
172 yutakakn 2728 }
173     if (pvar->pkt_state.buf[i] == '\n') {
174     i++;
175     }
176    
177     // SSH�T�[�o���o�[�W�����`�F�b�N���s��
178     if (SSH_handle_server_ID(pvar, pvar->pkt_state.buf, i)) {
179     pvar->pkt_state.seen_server_ID = 1;
180    
181     if (SSHv1(pvar)) {
182    
183     } else { // for SSH2(yutaka)
184     // send Key Exchange Init
185     SSH2_send_kexinit(pvar);
186     }
187    
188 yutakapon 3101 } else {
189     // reset flag to re-read server ID (2008.1.24 yutaka)
190     pvar->pkt_state.seen_newline = 0;
191    
192 yutakakn 2728 }
193    
194     pvar->pkt_state.datastart += i;
195     pvar->pkt_state.datalen -= i;
196    
197     } else if (pvar->pkt_state.seen_server_ID
198 maya 3003 && pvar->pkt_state.datalen >=
199     (unsigned int) SSH_get_min_packet_size(pvar)) {
200 yutakakn 2728 char FAR *data =
201     pvar->pkt_state.buf + pvar->pkt_state.datastart;
202     uint32 padding;
203     uint32 pktsize;
204     uint32 total_packet_size;
205    
206     //debug_print(10, data, pvar->pkt_state.datalen);
207    
208     // SSH2�����������p�P�b�g�������������������B
209     if (!pvar->pkt_state.predecrypted_packet) {
210 yutakapon 2922 //DEBUG_PRINT_TO_FILE(0, data, pvar->pkt_state.datalen);
211 yutakakn 2728 SSH_predecrpyt_packet(pvar, data);
212    
213     if (SSHv1(pvar)) {
214     pvar->pkt_state.predecrypted_packet = TRUE;
215     } else { // for SSH2(yutaka)
216     // do nothing
217     pvar->pkt_state.predecrypted_packet = TRUE;
218     }
219     }
220    
221     if (SSHv1(pvar)) {
222     uint32 realpktsize = get_uint32_MSBfirst(data);
223    
224     padding = 8 - (realpktsize % 8);
225     pktsize = realpktsize + padding;
226     } else {
227     // SSH2���p�P�b�g�������� packet-size(4)+padding(1)+type(1) �������B
228     pktsize = get_uint32_MSBfirst(data);
229     padding = (unsigned char) data[4];
230     }
231    
232     // �p�P�b�g(TCP�y�C���[�h)���S�����T�C�Y���ASSH�y�C���[�h�{4�i�{MAC�j�������B
233     // +4���ASSH�y�C���[�h���T�C�Y���i�[�������������iint�^�j�B
234     total_packet_size = pktsize + 4 + SSH_get_clear_MAC_size(pvar);
235    
236     if (total_packet_size <= pvar->pkt_state.datalen) {
237     /* the data must be 4 byte aligned. */
238     SSH_handle_packet(pvar, data, pktsize, padding);
239     pvar->pkt_state.predecrypted_packet = FALSE;
240    
241     pvar->pkt_state.datastart += total_packet_size;
242     pvar->pkt_state.datalen -= total_packet_size;
243    
244 yutakapon 3215 } else if (total_packet_size > PACKET_MAX_SIZE) {
245 yutakakn 2728 // 4MB���������������p�P�b�g�����������A�����I�������B
246     // ���������f�[�^�������������s�����A���F�����������������B
247 maya 2994 UTIL_get_lang_msg("MSG_PKT_OVERSIZED_ERROR", pvar,
248     "Oversized packet received from server; connection will close.");
249 maya 2937 notify_fatal_error(pvar, pvar->ts->UIMsg);
250 yutakakn 2728 } else {
251     int amount_read =
252     recv_data(pvar, max(total_packet_size, READAMOUNT));
253    
254     if (amount_read == SOCKET_ERROR) {
255     if (amount_in_buf == 0) {
256     return SOCKET_ERROR;
257     } else {
258     return amount_in_buf;
259     }
260     } else {
261     if (amount_read == 0) {
262     connection_closed = TRUE;
263     }
264     }
265     }
266    
267    
268     } else {
269     // �p�P�b�g�����M�i����60KB�j
270     int amount_read;
271    
272     if (pvar->pkt_state.seen_server_ID == 0) {
273     //amount_read = recv_line_data(pvar);
274     amount_read = recv_data(pvar, READAMOUNT);
275    
276     } else {
277     amount_read = recv_data(pvar, READAMOUNT);
278    
279     }
280    
281     if (amount_read == SOCKET_ERROR) {
282     if (amount_in_buf == 0) {
283     return SOCKET_ERROR;
284     } else {
285     return amount_in_buf;
286     }
287     } else if (amount_read == 0) {
288     connection_closed = TRUE;
289     }
290     }
291    
292     if (pvar->fatal_error) {
293     return amount_in_buf;
294     }
295     }
296    
297     if (SSH_is_any_payload(pvar)) {
298     PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY,
299 maya 3003 pvar->socket, MAKELPARAM(FD_READ, 0));
300 yutakakn 2728 }
301    
302     return amount_in_buf;
303     }
304    
305     void PKT_end(PTInstVar pvar)
306     {
307     buf_destroy(&pvar->pkt_state.buf, &pvar->pkt_state.buflen);
308     }

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