source: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.c@ 321

Last change on this file since 321 was 321, checked in by coas-nagasima, 7 years ago

文字コードを設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 21.2 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
5 * Tomakomai National College of Technology, JAPAN
6 *
7 * 上記著作権者は,以下の (1)~(4) の条件か,Free Software Foundation
8 * によって公表されている GNU General Public License の Version 2 に記
9 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
10 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
11 * 利用と呼ぶ)することを無償で許諾する.
12 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
13 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
14 * スコード中に含まれていること.
15 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
16 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
17 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
18 * の無保証規定を掲載すること.
19 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
20 * 用できない形で再配布する場合には,次の条件を満たすこと.
21 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
22 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 *
26 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
27 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
28 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
29 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
30 *
31 * @(#) $Id$
32 */
33
34/*
35 * TCP ECHO サーバ #1
36 *
37 * ・送受信タスク同一型
38 * ・ノンブロッキングコール
39 * ・省コピー API
40 * ・IPv4/IPv6
41 * ・緊急データの受信
42 */
43
44#include <string.h>
45
46#ifdef TARGET_KERNEL_ASP
47
48#include <kernel.h>
49#include <sil.h>
50#include <t_syslog.h>
51#include "kernel_cfg.h"
52#include "tinet_cfg.h"
53
54#endif /* of #ifdef TARGET_KERNEL_ASP */
55
56#ifdef TARGET_KERNEL_JSP
57
58#include <t_services.h>
59#include "kernel_id.h"
60#include "tinet_id.h"
61
62#endif /* of #ifdef TARGET_KERNEL_JSP */
63
64#include <tinet_defs.h>
65#include <tinet_config.h>
66
67#include <net/if.h>
68#include <net/if_ppp.h>
69#include <net/if_loop.h>
70#include <net/ethernet.h>
71#include <net/net.h>
72#include <net/net_timer.h>
73
74#include <netinet/in.h>
75#include <netinet/in_itron.h>
76#include <netinet/ip.h>
77#include <netinet/ip6.h>
78#include <netinet/tcp.h>
79
80#include <netapp/netapp.h>
81#include <netapp/netapp_var.h>
82#include <netapp/echo.h>
83
84#ifdef USE_TCP_ECHO_SRV1
85
86/*
87 * 表示
88 */
89
90//#define SHOW_RCV_RANGE
91
92/*
93 * コネクション切断方法の指定
94 */
95
96#define USE_TCP_SHT_CEP
97
98/*
99 * タイムアウト
100 */
101
102//#define CLS_TMO TMO_FEVR /* Close Wait は標準で 60秒 */
103#define CLS_TMO (70*SYSTIM_HZ+(net_rand()%SYSTIM_HZ)*10)
104//#define RCV_TMO TMO_FEVR
105#define RCV_TMO (30*SYSTIM_HZ+(net_rand()%SYSTIM_HZ)*30)
106//#define SND_TMO TMO_FEVR
107#define SND_TMO (40*SYSTIM_HZ+(net_rand()%SYSTIM_HZ)*20)
108
109/*
110 * 全域変数
111 */
112
113/* TCP 送受信ウィンドバッファ */
114
115#ifndef TCP_CFG_SWBUF_CSAVE
116uint8_t tcp_echo_srv_swbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_SWBUF_SIZE];
117#endif
118
119#ifndef TCP_CFG_RWBUF_CSAVE
120uint8_t tcp_echo_srv_rwbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_RWBUF_SIZE];
121#endif
122
123/*
124 * 変数
125 */
126
127/*
128 * 注意:
129 *
130 * BUF_SIZE は TCP の
131 * 送信ウインドウバッファサイズ + 受信ウインドウバッファサイズの
132 * 3/2 倍以上の大きさがなければ、デッドロックする可能性がある。
133 */
134
135#define BUF_SIZE ((TCP_ECHO_SRV_SWBUF_SIZE + \
136 TCP_ECHO_SRV_RWBUF_SIZE) * 3 / 2)
137
138static T_IPEP dst; /* 接続相手 */
139
140#ifdef USE_TCP_NON_BLOCKING
141
142static char buffer[BUF_SIZE];
143static ER nblk_error = E_OK;
144static ER_UINT nblk_slen = 0;
145static ER_UINT nblk_rlen = 0;
146
147#else /* of #ifdef USE_TCP_NON_BLOCKING */
148
149#ifdef USE_COPYSAVE_API
150
151#else /* of #ifdef USE_COPYSAVE_API */
152
153static char buffer[BUF_SIZE];
154
155#endif /* of #ifdef USE_COPYSAVE_API */
156
157#endif /* of #ifdef USE_TCP_NON_BLOCKING */
158
159#ifdef USE_TCP_NON_BLOCKING
160
161/*
162 * ノンブロッキングコールのコールバック関数
163 */
164
165ER
166callback_nblk_tcp_echo_srv (ID cepid, FN fncd, void *p_parblk)
167{
168 ER error = E_OK;
169
170 switch (fncd) {
171
172 case TFN_TCP_ACP_CEP:
173 nblk_error = *(ER*)p_parblk;
174 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
175 break;
176
177 case TFN_TCP_RCV_DAT:
178 if ((nblk_rlen = *(ER*)p_parblk) < 0)
179 syslog(LOG_NOTICE, "[TES:%02d CBN] recv error: %s", cepid, itron_strerror(nblk_rlen));
180 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
181 break;
182
183 case TFN_TCP_SND_DAT:
184 if ((nblk_slen = *(ER*)p_parblk) < 0)
185 syslog(LOG_NOTICE, "[TES:%02d CBN] send error: %s", cepid, itron_strerror(nblk_slen));
186 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
187 break;
188
189 case TFN_TCP_CLS_CEP:
190 if ((nblk_error = *(ER*)p_parblk) < 0)
191 syslog(LOG_NOTICE, "[TES:%02d CBN] close error: %s", cepid, itron_strerror(nblk_error));
192 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
193 break;
194
195 case TFN_TCP_RCV_BUF:
196 if ((nblk_rlen = *(ER*)p_parblk) < 0)
197 syslog(LOG_NOTICE, "[TES:%02d CBN] rbuf error: %s", cepid, itron_strerror(nblk_rlen));
198 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
199 break;
200
201 case TFN_TCP_GET_BUF:
202 if ((nblk_slen = *(ER*)p_parblk) < 0)
203 syslog(LOG_NOTICE, "[TES:%02d CBN] sbuf error: %s", cepid, itron_strerror(nblk_slen));
204 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
205 break;
206
207#ifdef USE_TCP_EXTENTIONS
208
209 case TEV_TCP_RCV_OOB:
210 if ((nblk_rlen = *(ER*)p_parblk) < 0)
211 syslog(LOG_NOTICE, "[TES:%02d OOB] callback error: %s", cepid, itron_strerror(nblk_rlen));
212 else if (nblk_rlen > 0) {
213 char ch;
214
215 if ((nblk_rlen = tcp_rcv_oob(cepid, &ch, sizeof(ch))) > 0)
216 syslog(LOG_NOTICE, "[TES:%02d OOB] recv oob: 0x%02x", cepid, ch);
217 else if (nblk_rlen < 0)
218 syslog(LOG_NOTICE, "[TES:%02d OOB] recv error: %s", cepid, itron_strerror(nblk_rlen));
219 }
220 break;
221
222#endif /* of #ifdef USE_TCP_EXTENTIONS */
223
224 case TFN_TCP_CON_CEP:
225 case TFN_TCP_SND_OOB:
226 default:
227 error = E_PAR;
228 break;
229 }
230 return error;
231 }
232
233#ifdef USE_COPYSAVE_API
234
235static ER
236tcp_echo_srv (ID cepid, ID repid)
237{
238 ER error;
239 SYSTIM now;
240 uint32_t total;
241 uint16_t rblen, sblen, rlen, slen, soff, scount, rcount;
242 char *rbuf, *sbuf, head, tail;
243
244 if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_NBLK)) != E_WBLK) {
245 syslog(LOG_NOTICE, "[TES:%02d ACP] error: %s", cepid, itron_strerror(error));
246 return error;
247 }
248
249 /* 相手から接続されるまで待つ。*/
250 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
251
252 if (nblk_error == E_OK) {
253 syscall(get_tim(&now));
254 syslog(LOG_NOTICE, "[TES:%02d ACP] connected: %6lu, from: %s.%u",
255 cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
256 }
257 else {
258 syslog(LOG_NOTICE, "[TES:%02d ACP] error: %s", cepid, itron_strerror(nblk_error));
259 return nblk_error;
260 }
261
262#ifdef USE_TCP_EXTENTIONS
263 if ((error = free_tcp_rep(repid, true)) != E_OK)
264 syslog(LOG_NOTICE, "[TES:%02d DEL] REP delete error: %s", cepid, itron_strerror(error));
265#endif /* of #ifdef USE_TCP_EXTENTIONS */
266
267 rlen = scount = rcount = total = 0;
268 while (true) {
269 if ((error = tcp_rcv_buf(cepid, (void**)&rbuf, TMO_NBLK)) != E_WBLK) {
270 syslog(LOG_NOTICE, "[TES:%02d RCV] error: %s", cepid, itron_strerror(error));
271 break;
272 }
273
274 /* 受信するまで待つ。*/
275 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
276
277 if (nblk_rlen < 0) { /* エラー */
278 syslog(LOG_NOTICE, "[TES:%02d RCV] error: %s",
279 cepid, itron_strerror(nblk_rlen));
280 break;
281 }
282 else if (nblk_rlen == 0) /* 受信終了 */
283 break;
284
285 rblen = nblk_rlen;
286
287 /* バッファの残りにより、受信長を調整する。*/
288 if (rblen > BUF_SIZE - rlen)
289 rblen = BUF_SIZE - rlen;
290 total += rblen;
291 rlen = rblen;
292
293 head = *rbuf;
294 tail = *(rbuf + rblen - 1);
295 rcount ++;
296
297#ifdef SHOW_RCV_RANGE
298 syslog(LOG_NOTICE, "[TES:%02d RCV] "
299 "rcount: %4d, len: %4d, data %02x -> %02x",
300 cepid, rcount, rblen, head, tail);
301#endif /* of #ifdef SHOW_RCV_RANGE */
302
303 memcpy(buffer, rbuf, rblen);
304
305 if ((error = tcp_rel_buf(cepid, rlen)) < 0) {
306 syslog(LOG_NOTICE, "[TES:%02d REL] error: %s",
307 cepid, itron_strerror(error));
308 break;
309 }
310
311 soff = 0;
312 while (rlen > 0) {
313
314 if ((error = tcp_get_buf(cepid, (void**)&sbuf, TMO_NBLK)) != E_WBLK) {
315 syslog(LOG_NOTICE, "[TES:%02d GET] error: %s",
316 cepid, itron_strerror(error));
317 goto err_fin;
318 }
319
320 /* 送信バッファの獲得が完了するまで待つ。*/
321 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
322
323 if (nblk_slen < 0) {
324 syslog(LOG_NOTICE, "[TES:%02d GET] error: %s",
325 cepid, itron_strerror(nblk_slen));
326 goto err_fin;
327 }
328
329 sblen = nblk_slen;
330 scount ++;
331 slen = sblen < rlen ? sblen : rlen;
332 memcpy(sbuf, buffer + soff, slen);
333
334 if ((error = tcp_snd_buf(cepid, slen)) != E_OK) {
335 syslog(LOG_NOTICE, "[TES:%02d SND] error: %s",
336 cepid, itron_strerror(error));
337 goto err_fin;
338 }
339#ifdef SHOW_RCV_RANGE
340 syslog(LOG_NOTICE, "[TES:%02d SND] scount: %4d, len: %4d",
341 cepid, scount, slen);
342#endif /* of #ifdef SHOW_RCV_RANGE */
343
344 rlen -= slen;
345 soff += slen;
346 }
347 }
348err_fin:
349
350#ifdef USE_TCP_SHT_CEP
351 if ((error = tcp_sht_cep(cepid)) != E_OK)
352 syslog(LOG_NOTICE, "[TES:%02d SHT] error: %s", cepid, itron_strerror(error));
353#endif /* of #ifdef USE_TCP_SHT_CEP */
354
355 if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK)
356 syslog(LOG_NOTICE, "[TES:%02d CLS] error: %s", cepid, itron_strerror(error));
357
358 /* 開放が完了するまで待つ。*/
359 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
360
361 syscall(get_tim(&now));
362 syslog(LOG_NOTICE, "[TES:%02d FIN] finished: %6lu, snd: %4u, rcv: %4u, len: %lu",
363 cepid, now / SYSTIM_HZ, scount, rcount, total);
364
365 return error == E_WBLK ? E_OK : error;
366 }
367
368#else /* of #ifdef USE_COPYSAVE_API */
369
370static ER
371tcp_echo_srv (ID cepid, ID repid)
372{
373 SYSTIM now;
374 ER error;
375 uint32_t total;
376 uint16_t rlen, slen, soff, scount, rcount;
377 char head, tail;
378
379 if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_NBLK)) != E_WBLK) {
380 syslog(LOG_NOTICE, "[TES:%02d ACP] error: %s", cepid, itron_strerror(error));
381 return error;
382 }
383
384 /* 相手から接続されるまで待つ。*/
385 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
386
387 if (nblk_error == E_OK) {
388 syscall(get_tim(&now));
389 syslog(LOG_NOTICE, "[TES:%02d ACP] connected: %6lu, from: %s.%u",
390 cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
391 }
392 else {
393 syslog(LOG_NOTICE, "[TES:%02d ACP] error: %s", cepid, itron_strerror(nblk_error));
394 return nblk_error;
395 }
396
397#ifdef USE_TCP_EXTENTIONS
398 if ((error = free_tcp_rep(repid, true)) != E_OK)
399 syslog(LOG_NOTICE, "[TES:%02d DEL] REP delete error: %s", cepid, itron_strerror(error));
400#endif /* of #ifdef USE_TCP_EXTENTIONS */
401
402 scount = rcount = total = 0;
403 while (true) {
404 if ((error = tcp_rcv_dat(cepid, buffer, BUF_SIZE - 1, TMO_NBLK)) != E_WBLK) {
405 syslog(LOG_NOTICE, "[TES:%02d RCV] error: %s",
406 cepid, itron_strerror(error));
407 break;
408 }
409
410 /* 受信完了まで待つ。*/
411 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
412
413 if (nblk_rlen < 0) {
414 syslog(LOG_NOTICE, "[TES:%02d RCV] error: %s",
415 cepid, itron_strerror(nblk_rlen));
416 break;
417 }
418 else if (nblk_rlen == 0)
419 break;
420
421 rlen = nblk_rlen;
422 head = *buffer;
423 tail = *(buffer + rlen - 1);
424 rcount ++;
425
426#ifdef SHOW_RCV_RANGE
427 syslog(LOG_NOTICE, "[TES:%02d RCV] rcount: %4d, len: %4d, data %02x -> %02x",
428 cepid, rcount, rlen, head, tail);
429#endif /* of #ifdef SHOW_RCV_RANGE */
430
431 total += rlen;
432 soff = 0;
433 while (rlen > 0) {
434 scount ++;
435 if ((error = tcp_snd_dat(cepid, &buffer[soff], rlen, TMO_NBLK)) != E_WBLK) {
436 syslog(LOG_NOTICE, "[TES:%02d SND] error: %s",
437 cepid, itron_strerror(error));
438 goto err_fin;
439 }
440
441 /* 送信完了まで待つ。*/
442 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
443
444 if (nblk_slen < 0) {
445 syslog(LOG_NOTICE, "[TES:%02d SND] error: %s",
446 cepid, itron_strerror(nblk_slen));
447 goto err_fin;
448 }
449
450 slen = nblk_slen;
451
452#ifdef SHOW_RCV_RANGE
453 syslog(LOG_NOTICE, "[TES:%02d SND] scount: %4d, len: %4d",
454 cepid, scount, slen);
455#endif /* of #ifdef SHOW_RCV_RANGE */
456
457 rlen -= slen;
458 soff += slen;
459 }
460 }
461err_fin:
462
463#ifdef USE_TCP_SHT_CEP
464 if ((error = tcp_sht_cep(cepid)) != E_OK)
465 syslog(LOG_NOTICE, "[TES:%02d SHT] error: %s", cepid, itron_strerror(error));
466#endif /* of #ifdef USE_TCP_SHT_CEP */
467
468 if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK)
469 syslog(LOG_NOTICE, "[TES:%02d CLS] error: %s", cepid, itron_strerror(error));
470
471 /* 開放が完了するまで待つ。*/
472 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
473
474 syscall(get_tim(&now));
475 syslog(LOG_NOTICE, "[TES:%02d FIN] finished: %6lu, snd: %4u, rcv: %4u, len: %lu",
476 cepid, now / SYSTIM_HZ, scount, rcount, total);
477
478 return error == E_WBLK ? E_OK : error;
479 }
480
481#endif /* of #ifdef USE_COPYSAVE_API */
482
483#else /* of #ifdef USE_TCP_NON_BLOCKING */
484
485#ifdef USE_COPYSAVE_API
486
487static ER
488tcp_echo_srv (ID cepid, ID repid)
489{
490 ER_UINT rblen, sblen;
491 SYSTIM now;
492 ER error;
493 uint32_t total;
494 uint16_t rlen, slen, soff, scount, rcount;
495 char *rbuf, *sbuf, head, tail;
496
497 if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_FEVR)) != E_OK) {
498 syslog(LOG_NOTICE, "[TES:%02d ACP] error: %s", cepid, itron_strerror(error));
499 return error;
500 }
501
502#ifdef USE_TCP_EXTENTIONS
503 if ((error = free_tcp_rep(repid, true)) != E_OK)
504 syslog(LOG_NOTICE, "[TES:%02d DEL] REP delete error: %s", cepid, itron_strerror(error));
505#endif /* of #ifdef USE_TCP_EXTENTIONS */
506
507 scount = rcount = total = 0;
508 syscall(get_tim(&now));
509 syslog(LOG_NOTICE, "[TES:%02d ACP] connected: %6lu, from: %s.%u",
510 cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
511 while (true) {
512 if ((rblen = tcp_rcv_buf(cepid, (void**)&rbuf, RCV_TMO)) <= 0) {
513 if (rblen != E_OK)
514 syslog(LOG_NOTICE, "[TES:%02d RCV] error: %s",
515 cepid, itron_strerror(rblen));
516 break;
517 }
518
519 head = *rbuf;
520 tail = *(rbuf + rblen - 1);
521 rcount ++;
522
523 //syslog(LOG_NOTICE, "[TES:%02d RCV] len: %4d", cepid, (uint16_t)rblen);
524#ifdef SHOW_RCV_RANGE
525 syslog(LOG_NOTICE, "[TES:%02d RCV] rcount: %4d, len: %4d, data %02x -> %02x",
526 cepid, rcount, (uint16_t)rblen, head, tail);
527#endif /* of #ifdef SHOW_RCV_RANGE */
528
529 rlen = (uint16_t)rblen;
530 total += rblen;
531 soff = 0;
532 while (rlen > 0) {
533
534 if ((sblen = tcp_get_buf(cepid, (void**)&sbuf, SND_TMO)) < 0) {
535 syslog(LOG_NOTICE, "[TES:%02d GET] error: %s",
536 cepid, itron_strerror(sblen));
537 goto err_fin;
538 }
539
540 //syslog(LOG_NOTICE, "[TES:%02d SND] len: %4d", cepid, (uint16_t)sblen);
541 scount ++;
542 slen = rlen < (uint16_t)sblen ? rlen : (uint16_t)sblen;
543 memcpy(sbuf, rbuf + soff, slen);
544 if ((error = tcp_snd_buf(cepid, slen)) != E_OK) {
545 syslog(LOG_NOTICE, "[TES:%02d SND] error: %s",
546 cepid, itron_strerror(error));
547 goto err_fin;
548 }
549#ifdef SHOW_RCV_RANGE
550 syslog(LOG_NOTICE, "[TES:%02d SND] scount: %4d, len: %4d", cepid, scount, slen);
551#endif /* of #ifdef SHOW_RCV_RANGE */
552
553 rlen -= slen;
554 soff += slen;
555 }
556
557 if ((error = tcp_rel_buf(cepid, rblen)) < 0) {
558 syslog(LOG_NOTICE, "[TES:%02d REL] error: %s", cepid, itron_strerror(error));
559 break;
560 }
561 }
562err_fin:
563
564#ifdef USE_TCP_SHT_CEP
565 if ((error = tcp_sht_cep(cepid)) != E_OK)
566 syslog(LOG_NOTICE, "[TES:%02d SHT] error: %s", cepid, itron_strerror(error));
567#endif /* of #ifdef USE_TCP_SHT_CEP */
568
569 if ((error = tcp_cls_cep(cepid, CLS_TMO)) != E_OK)
570 syslog(LOG_NOTICE, "[TES:%02d CLS] error: %s", cepid, itron_strerror(error));
571
572 syscall(get_tim(&now));
573 syslog(LOG_NOTICE, "[TES:%02d FIN] finished: %6lu, snd: %4u, rcv: %4u, len: %lu",
574 cepid, now / SYSTIM_HZ, scount, rcount, total);
575
576 return error;
577 }
578
579#else /* of #ifdef USE_COPYSAVE_API */
580
581/*
582 * tcp_echo_srv -- TCP エコーサーバ
583 */
584
585static ER
586tcp_echo_srv (ID cepid, ID repid)
587{
588 ER_UINT rlen, slen;
589 ER error = E_OK;
590 SYSTIM now;
591 uint32_t total;
592 uint16_t soff, scount, rcount;
593
594 if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_FEVR)) != E_OK) {
595 syslog(LOG_NOTICE, "[TES:%02d ACP] error: %s", cepid, itron_strerror(error));
596 return error;
597 }
598
599#ifdef USE_TCP_EXTENTIONS
600 if ((error = free_tcp_rep(repid, true)) != E_OK)
601 syslog(LOG_NOTICE, "[TES:%02d DEL] REP delete error: %s", cepid, itron_strerror(error));
602#endif /* of #ifdef USE_TCP_EXTENTIONS */
603
604 scount = rcount = total = 0;
605 syscall(get_tim(&now));
606 syslog(LOG_NOTICE, "[TES:%02d ACP] connected: %6lu, from: %s.%u",
607 cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
608 while (true) {
609 if ((rlen = tcp_rcv_dat(cepid, buffer, BUF_SIZE - 1, RCV_TMO)) <= 0) {
610 if (rlen != E_OK)
611 syslog(LOG_NOTICE, "[TES:%02d RCV] error: %s",
612 cepid, itron_strerror(rlen));
613 break;
614 }
615
616 rcount ++;
617#ifdef SHOW_RCV_RANGE
618 syslog(LOG_NOTICE, "[TES:%02d RCV] rcount: %4d, len: %4d, data %02x -> %02x",
619 cepid, rcount, (uint16_t)rlen, *buffer, *(buffer + rlen - 1));
620#endif /* of #ifdef SHOW_RCV_RANGE */
621
622 total += rlen;
623 soff = 0;
624 while (rlen > 0) {
625 scount ++;
626 if ((slen = tcp_snd_dat(cepid, &buffer[soff], rlen, SND_TMO)) < 0) {
627 syslog(LOG_NOTICE, "[TES:%02d SND] error: %s",
628 cepid, itron_strerror(slen));
629 goto err_fin;
630 }
631#ifdef SHOW_RCV_RANGE
632 syslog(LOG_NOTICE, "[TES:%02d SND] scount: %4d, len: %4d", cepid, scount, (uint16_t)slen);
633#endif /* of #ifdef SHOW_RCV_RANGE */
634
635 rlen -= slen;
636 soff += slen;
637 }
638 }
639err_fin:
640
641#ifdef USE_TCP_SHT_CEP
642 if ((error = tcp_sht_cep(cepid)) != E_OK)
643 syslog(LOG_NOTICE, "[TES:%02d SHT] error: %s", cepid, itron_strerror(error));
644#endif /* of #ifdef USE_TCP_SHT_CEP */
645
646 if ((error = tcp_cls_cep(cepid, CLS_TMO)) != E_OK)
647 syslog(LOG_NOTICE, "[TES:%02d CLS] error: %s", cepid, itron_strerror(error));
648
649 syscall(get_tim(&now));
650 syslog(LOG_NOTICE, "[TES:%02d FIN] finished: %6lu, snd: %4u, rcv: %4u, len: %lu",
651 cepid, now / SYSTIM_HZ, scount, rcount, total);
652
653 return error;
654 }
655
656#endif /* of #ifdef USE_COPYSAVE_API */
657
658#endif /* of #ifdef USE_TCP_NON_BLOCKING */
659
660#ifdef USE_TCP_EXTENTIONS
661
662/*
663 * get_tcp_rep -- TCP 受付口を獲得する。
664 */
665
666static ER
667get_tcp_rep (ID *repid)
668{
669 ID tskid;
670 T_TCP_CREP crep;
671
672 get_tid(&tskid);
673
674 crep.repatr = UINT_C(0);
675 crep.myaddr.portno = UINT_C(7);
676
677#if defined(SUPPORT_INET4)
678 crep.myaddr.ipaddr = IPV4_ADDRANY;
679#endif
680
681#if defined(SUPPORT_INET6)
682 memcpy(&crep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
683#endif
684
685 return alloc_tcp_rep(repid, tskid, &crep);
686 }
687
688/*
689 * get_tcp_cep -- TCP 通信端点とを獲得する。
690 */
691
692static ER
693get_tcp_cep (ID *cepid)
694{
695 ID tskid;
696 T_TCP_CCEP ccep;
697
698 get_tid(&tskid);
699
700 ccep.cepatr = UINT_C(0);
701 ccep.sbufsz = TCP_ECHO_SRV_SWBUF_SIZE;
702 ccep.rbufsz = TCP_ECHO_SRV_RWBUF_SIZE;
703
704#ifdef TCP_CFG_SWBUF_CSAVE
705 ccep.sbuf = NADR;
706#else
707 ccep.sbuf = tcp_echo_srv_swbuf;
708#endif
709#ifdef TCP_CFG_RWBUF_CSAVE
710 ccep.rbuf = NADR;
711#else
712 ccep.rbuf = tcp_echo_srv_rwbuf;
713#endif
714#ifdef USE_TCP_NON_BLOCKING
715 ccep.callback = (FP)callback_nblk_tcp_echo_srv;
716#else
717 ccep.callback = NULL;
718#endif
719
720 return alloc_tcp_cep(cepid, tskid, &ccep);
721 }
722
723/*
724 * tcp_echo_srv_task -- TCP エコーサーバタスク
725 */
726
727void
728tcp_echo_srv_task (intptr_t exinf)
729{
730 ID tskid, cepid, repid;
731 ER error = E_OK;
732
733 syscall(get_tid(&tskid));
734 syslog(LOG_NOTICE, "[TCP ECHO SRV:%d] started.", tskid);
735 while (true) {
736
737 syscall(slp_tsk());
738 if ((error = get_tcp_cep (&cepid)) != E_OK) {
739 syslog(LOG_NOTICE, "[TES:00 EXT] CEP create error: %s", itron_strerror(error));
740 continue;
741 }
742
743 while (true) {
744
745 if ((error = get_tcp_rep (&repid)) != E_OK) {
746 syslog(LOG_NOTICE, "[TES:00 EXT] REP create error: %s", itron_strerror(error));
747 break;
748 }
749 else if ((error = tcp_echo_srv(cepid, repid)) != E_OK) {
750 error = free_tcp_rep(repid, error != E_DLT);
751 break;
752 }
753 }
754
755 if ((error = free_tcp_cep(cepid)) != E_OK)
756 syslog(LOG_NOTICE, "[TES:%02d EXT] CEP delete error: %s", cepid, itron_strerror(error));
757
758 }
759 }
760
761#else /* of #ifdef USE_TCP_EXTENTIONS */
762
763/*
764 * tcp_echo_srv_task -- TCP エコーサーバタスク
765 */
766
767void
768tcp_echo_srv_task(intptr_t exinf)
769{
770 ID tskid;
771 ER error;
772
773 syscall(get_tid(&tskid));
774 syslog(LOG_NOTICE, "[TCP ECHO SRV:%d,%d] started.", tskid, (ID)exinf);
775 while (true) {
776 while ((error = tcp_echo_srv((ID)exinf, TCP_ECHO_SRV_REPID)) == E_OK)
777 ;
778 syslog(LOG_NOTICE, "[TES:%02d] goto sleep 60[s], error: %s", (ID)exinf, itron_strerror(error));
779 tslp_tsk(60 * 1000);
780 }
781 }
782
783#endif /* of #ifdef USE_TCP_EXTENTIONS */
784
785#endif /* of #ifdef USE_TCP_ECHO_SRV1 */
Note: See TracBrowser for help on using the repository browser.