source: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_usrreq.c@ 270

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

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 50.3 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 * 上記著作権者
8は,以下の (1)~(4) の条件か,Free Software Foundation
9 * によってå…
10¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
11 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12 * を改変したものを含む.以下同じ)を使用・複製・改変・再é…
13å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
14 * 利用と呼ぶ)することを無償で許諾する.
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * スコード中に含まれていること.
18 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19 * 用できる形で再é…
20å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
21å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
22 * 者
23マニュアルなど)に,上記の著作権表示,この利用条件および下記
24 * の無保証規定を掲載すること.
25 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
26 * 用できない形で再é…
27å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®æ¡ä»¶ã‚’満たすこと.
28 * (a) 再é…
29å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
30マニュアルなど)に,上記の著
31 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
32 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
33 * 害からも,上記著作権者
34およびTOPPERSプロジェクトをå…
35è²¬ã™ã‚‹ã“と.
36 *
37 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
38お
39 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
40 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
41 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
42 *
43 * @(#) $Id: tcp_usrreq.c 270 2017-02-09 04:03:47Z coas-nagasima $
44 */
45
46/*
47 * Copyright (c) 1982, 1986, 1988, 1993
48 * The Regents of the University of California. All rights reserved.
49 *
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 * 1. Redistributions of source code must retain the above copyright
54 * notice, this list of conditions and the following disclaimer.
55 * 2. Redistributions in binary form must reproduce the above copyright
56 * notice, this list of conditions and the following disclaimer in the
57 * documentation and/or other materials provided with the distribution.
58 * 3. All advertising materials mentioning features or use of this software
59 * must display the following acknowledgement:
60 * This product includes software developed by the University of
61 * California, Berkeley and its contributors.
62 * 4. Neither the name of the University nor the names of its contributors
63 * may be used to endorse or promote products derived from this software
64 * without specific prior written permission.
65 *
66 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
67 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
68 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
69 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
70 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
71 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
72 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
73 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
74 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
75 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
76 * SUCH DAMAGE.
77 *
78 * From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94
79 * $FreeBSD: src/sys/netinet/tcp_usrreq.c,v 1.40.2.3 1999/08/29 16:29:57 peter Exp $
80 */
81
82#include <string.h>
83
84#ifdef TARGET_KERNEL_ASP
85
86#include <kernel.h>
87#include <sil.h>
88#include "kernel_cfg.h"
89
90#endif /* of #ifdef TARGET_KERNEL_ASP */
91
92#ifdef TARGET_KERNEL_JSP
93
94#include <s_services.h>
95#include <t_services.h>
96#include "kernel_id.h"
97
98#endif /* of #ifdef TARGET_KERNEL_JSP */
99
100#include <tinet_defs.h>
101#include <tinet_config.h>
102
103#include <net/if.h>
104#include <net/if_ppp.h>
105#include <net/if_loop.h>
106#include <net/ethernet.h>
107#include <net/ppp_ipcp.h>
108#include <net/net.h>
109#include <net/net_var.h>
110#include <net/net_buf.h>
111#include <net/net_timer.h>
112#include <net/net_count.h>
113
114#include <netinet/in.h>
115#include <netinet/in_var.h>
116#include <netinet6/in6.h>
117#include <netinet6/in6_var.h>
118#include <netinet/in_itron.h>
119#include <netinet/ip.h>
120#include <netinet/ip_var.h>
121#include <netinet/ip6.h>
122#include <netinet6/ip6_var.h>
123#include <netinet/tcp.h>
124#include <netinet/tcp_timer.h>
125#include <netinet/tcp_var.h>
126#include <netinet/tcp_fsm.h>
127#include <netinet/tcp_seq.h>
128
129#include <net/if_var.h>
130
131#ifdef SUPPORT_TCP
132
133/*
134 * IPv4 と IPv6 の切り替えマクロ
135 */
136
137#if defined(SUPPORT_INET4)
138
139#define TCP_CRE_REP tcp_cre_rep
140#define TCP_ACP_CEP tcp_acp_cep
141#define TCP_CON_CEP tcp_con_cep
142
143#endif /* of #if defined(SUPPORT_INET4) */
144
145#if defined(SUPPORT_INET6)
146
147#define TCP_CRE_REP tcp6_cre_rep
148#define TCP_ACP_CEP tcp6_acp_cep
149#define TCP_CON_CEP tcp6_con_cep
150
151#endif /* of #if defined(SUPPORT_INET6) */
152
153/*
154 * TINET をライブラリ化しない場合は、å…
155¨ã¦ã®æ©Ÿèƒ½ã‚’
156 * オブジェクトファイルに出力するため、マクロを有効にする。
157 */
158
159#ifndef TCP_CFG_LIBRARY
160
161#define __tcp_cre_rep
162#define __tcp_del_rep
163#define __tcp_cre_cep
164#define __tcp_del_cep
165#define __tcp_acp_cep
166#define __tcp_con_cep
167#define __tcp_sht_cep
168#define __tcp_cls_cep
169#define __tcp_snd_dat
170#define __tcp_rcv_dat
171#define __tcp_snd_oob
172#define __tcp_rcv_oob
173#define __tcp_get_buf
174#define __tcp_snd_buf
175#define __tcp_rcv_buf
176#define __tcp_rel_buf
177#define __tcp_can_cep
178#define __tcp_set_opt
179#define __tcp_get_opt
180
181#endif /* of #ifndef TCP_CFG_LIBRARY */
182
183/*
184 * tcp_cre_rep -- TCP 受付口の生成【拡張機能】
185 */
186
187#ifdef __tcp_cre_rep
188
189#ifdef TCP_CFG_EXTENTIONS
190
191ER
192TCP_CRE_REP (ID repid, T_TCP_CREP *pk_crep)
193{
194 T_TCP_REP *rep;
195 ER error;
196
197 /* TCP 受付口 ID をチェックする。*/
198 if (!VAID_TCP_REPID(repid))
199 return E_ID;
200
201 /* pk_crep が NULL ならエラー */
202 if (pk_crep == NULL)
203 return E_PAR;
204
205 /* TCP 受付口を得る。*/
206 rep = GET_TCP_REP(repid);
207
208 /* TCP 受付口が、動的生成用でなければエラー */
209 if (!DYNAMIC_TCP_REP(rep))
210 return E_ID;
211
212 /* 受付口をロックする。*/
213 syscall(wai_sem(rep->semid_lock));
214
215 /*
216 * TCP 受付口をチェックする。生成済みであればエラー
217 */
218 if (VALID_TCP_REP(rep))
219 error = E_OBJ;
220 else {
221
222 /* TCP 受付口生成情
223報をコピーする。*/
224 rep->repatr = pk_crep->repatr; /* 受付口属性 */
225 rep->myaddr = pk_crep->myaddr; /* 自分のアドレス */
226
227 /* TCP 受付口を生成済みにする。*/
228 rep->flags |= TCP_REP_FLG_VALID;
229 error = E_OK;
230 }
231
232 /* 受付口のロックを解除する。*/
233 syscall(sig_sem(rep->semid_lock));
234
235 return error;
236 }
237
238#endif /* of #ifdef TCP_CFG_EXTENTIONS */
239
240#endif /* of #ifdef __tcp_cre_cep */
241
242#ifdef __tcp_del_rep
243
244#ifdef TCP_CFG_EXTENTIONS
245
246/*
247 * tcp_find_cep_rep -- TCP 受付口をリンクしている TCP 通信端点を得る。
248 */
249
250static T_TCP_CEP*
251tcp_find_cep_rep (T_TCP_REP* rep)
252{
253 T_TCP_CEP* cep;
254
255 for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; ) {
256 if (cep->rep == rep)
257 return cep;
258 }
259
260 return NULL;
261 }
262
263/*
264 * tcp_del_rep -- TCP 受付口の削除【拡張機能】
265 */
266
267
268ER
269tcp_del_rep (ID repid)
270{
271 T_TCP_CEP *cep;
272 T_TCP_REP *rep;
273 ER error = E_OK;
274
275 /* TCP 受付口 ID をチェックする。*/
276 if (!VAID_TCP_REPID(repid))
277 return E_ID;
278
279 /* TCP 受付口を得る。*/
280 rep = GET_TCP_REP(repid);
281
282 /* TCP 受付口が、動的生成用でなければエラー */
283 if (!DYNAMIC_TCP_REP(rep))
284 return E_ID;
285
286 /* 受付口をロックする。*/
287 syscall(wai_sem(rep->semid_lock));
288
289 /* TCP 受付口をチェックする。未生成の場合はエラー */
290 if (!VALID_TCP_REP(rep))
291 error = E_NOEXS;
292 else {
293 if ((cep = tcp_find_cep_rep(rep)) != NULL) {
294 /*
295 * すでに受動オープンしているとき
296 *(tcp_acp_cep が呼ばれているとき)は、
297 * tcp_acp_cep を終了させる。
298 */
299
300 /* 通信端点をロックする。*/
301 syscall(wai_sem(cep->semid_lock));
302
303 /*
304 * 通信端点から受付口を解放し、
305 * イベントフラグをクローズに設定する。
306 */
307 cep->rep = NULL;
308 cep->fsm_state = TCP_FSM_CLOSED;
309 cep->error = E_DLT;
310 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
311
312#ifdef TCP_CFG_NON_BLOCKING
313
314 if (cep->rcv_nblk_tfn != TFN_TCP_UNDEF) {
315 if (IS_PTR_DEFINED(cep->callback)) {
316
317#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
318
319 (*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)E_DLT);
320
321#else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
322
323 ER error = E_DLT;
324
325 (*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&error);
326
327#endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
328
329 }
330 else
331 error = E_OBJ;
332 cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
333 }
334
335#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
336
337 cep->rcv_tskid = TA_NULL;
338 cep->rcv_tfn = TFN_TCP_UNDEF;
339
340 /* 通信端点のロックを解除する。*/
341 syscall(sig_sem(cep->semid_lock));
342
343 }
344 else
345 error = E_OK;
346
347 /* TCP 受付口を未生成にする。*/
348 rep->flags &= ~TCP_REP_FLG_VALID;
349 }
350
351 /* 受付口のロックを解除する。*/
352 syscall(sig_sem(rep->semid_lock));
353
354 return error;
355 }
356
357#endif /* of #ifdef TCP_CFG_EXTENTIONS */
358
359#endif /* of #ifdef __tcp_del_rep */
360
361/*
362 * tcp_cre_cep -- TCP 通信端点の生成【拡張機能】
363 */
364
365#ifdef __tcp_cre_cep
366
367#ifdef TCP_CFG_EXTENTIONS
368
369ER
370tcp_cre_cep (ID cepid, T_TCP_CCEP *pk_ccep)
371{
372 T_TCP_CEP *cep;
373 ER error;
374
375 /* TCP 通信端点 ID をチェックする。*/
376 if (!VAID_TCP_CEPID(cepid))
377 return E_ID;
378
379 /* pk_ccep が NULL ならエラー */
380 if (pk_ccep == NULL)
381 return E_PAR;
382
383 /* TCP 通信端点を得る。*/
384 cep = GET_TCP_CEP(cepid);
385
386 /* TCP 通信端点が、動的生成用でなければエラー */
387 if (!DYNAMIC_TCP_CEP(cep))
388 return E_ID;
389
390 /* 通信端点をロックする。*/
391 syscall(wai_sem(cep->semid_lock));
392
393 /*
394 * TCP 通信端点をチェックする。生成済みであればエラー
395 */
396 if (VALID_TCP_CEP(cep))
397 error = E_OBJ;
398 else {
399
400 /* TCP 通信端点生成情
401報をコピーする。*/
402 cep->cepatr = pk_ccep->cepatr; /* 通信端点属性 */
403 cep->sbuf = pk_ccep->sbuf; /* 送信用ウィンドバッファ */
404 cep->sbufsz = pk_ccep->sbufsz; /* 送信用ウィンドバッファサイズ */
405 cep->rbuf = pk_ccep->rbuf; /* 受信用ウィンドバッファ */
406 cep->rbufsz = pk_ccep->rbufsz; /* 受信用ウィンドバッファサイズ */
407 cep->callback = (void*)pk_ccep->callback; /* コールバック */
408
409 /* TCP 通信端点を生成済みにする。*/
410 cep->flags |= TCP_CEP_FLG_VALID;
411 error = E_OK;
412 }
413
414 /* 通信端点のロックを解除する。*/
415 syscall(sig_sem(cep->semid_lock));
416
417 return error;
418 }
419
420#endif /* of #ifdef TCP_CFG_EXTENTIONS */
421
422#endif /* of #ifdef __tcp_cre_cep */
423
424/*
425 * tcp_del_cep -- TCP 通信端点の削除【拡張機能】
426 */
427
428#ifdef __tcp_del_cep
429
430#ifdef TCP_CFG_EXTENTIONS
431
432ER
433tcp_del_cep (ID cepid)
434{
435 T_TCP_CEP *cep;
436 ER error;
437
438 /* TCP 通信端点 ID をチェックする。*/
439 if (!VAID_TCP_CEPID(cepid))
440 return E_ID;
441
442 /* TCP 通信端点を得る。*/
443 cep = GET_TCP_CEP(cepid);
444
445 /* TCP 通信端点が、動的生成用でなければエラー */
446 if (!DYNAMIC_TCP_CEP(cep))
447 return E_ID;
448
449 /* 通信端点をロックする。*/
450 syscall(wai_sem(cep->semid_lock));
451
452 /*
453 * TCP 通信端点をチェックする。以下の場合はエラー
454 * ・未生成。
455 * ・使用中。
456 */
457 if (!VALID_TCP_CEP(cep))
458 error = E_NOEXS;
459 else if (cep->fsm_state != TCP_FSM_CLOSED)
460 error = E_OBJ;
461 else {
462
463 /* TCP 通信端点を未生成にする。*/
464 cep->flags &= ~TCP_CEP_FLG_VALID;
465 error = E_OK;
466 }
467
468 /* 通信端点のロックを解除する。*/
469 syscall(sig_sem(cep->semid_lock));
470
471 return error;
472 }
473
474#endif /* of #ifdef TCP_CFG_EXTENTIONS */
475
476#endif /* of #ifdef __tcp_del_cep */
477
478#ifdef TCP_CFG_PASSIVE_OPEN
479
480/*
481 * tcp_acp_cep -- 接続要求待
482ち (受動オープン)【標準機能】
483 */
484
485#ifdef __tcp_acp_cep
486
487ER
488TCP_ACP_CEP (ID cepid, ID repid, T_IPEP *p_dstaddr, TMO tmout)
489{
490 T_TCP_REP *rep;
491 T_TCP_CEP *cep;
492 ER error;
493 FLGPTN flag;
494
495 /* TCP 受付口をチェックする。*/
496 if (!VAID_TCP_REPID(repid))
497 return E_ID;
498
499#ifdef TCP_CFG_NON_BLOCKING
500
501 /* p_dstaddr が NULL ならエラー */
502 if (p_dstaddr == NULL)
503 return E_PAR;
504
505#else /* of #ifdef TCP_CFG_NON_BLOCKING */
506
507 /* p_dstaddr が NULL か、tmout が TMO_NBLK ならエラー */
508 if (p_dstaddr == NULL || tmout == TMO_NBLK)
509 return E_PAR;
510
511#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
512
513 /*
514 * CEP をロックし、API 機能コードとタスク識別子を記録する。
515 * すでに記録されていれば、ペンディング中なのでエラー
516 */
517 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_ACP_CEP)) != E_OK)
518 return error;
519
520 /* CEP の FSM がクローズ状æ…
521‹ã§ãªã‘ればエラー。*/
522 if (cep->fsm_state != TCP_FSM_CLOSED) {
523 error = E_OBJ;
524 goto err_ret;
525 }
526 syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_CLOSED)));
527
528 /* TCP 通信端点を初期化する。*/
529 tcp_init_cep(cep);
530
531 /* TCP 受付口を得る。*/
532 rep = GET_TCP_REP(repid);
533
534#ifdef TCP_CFG_EXTENTIONS
535
536 /* TCP 受付口をロックする。*/
537 syscall(wai_sem(rep->semid_lock));
538
539 /* TCP 受付口をチェックする。*/
540 if (!VALID_TCP_REP(rep)) {
541 syscall(sig_sem(rep->semid_lock));
542 error = E_NOEXS;
543 goto err_ret;
544 }
545
546#endif /* of #ifdef TCP_CFG_EXTENTIONS */
547
548 /* TCP 通信端点にTCP受付口を記録する。*/
549 cep->rep = rep;
550
551#ifdef TCP_CFG_EXTENTIONS
552
553 /* TCP 受付口のロックを解除する。*/
554 syscall(sig_sem(rep->semid_lock));
555
556#endif /* of #ifdef TCP_CFG_EXTENTIONS */
557
558 /* TCP 受付口のアドレスをコピーする。*/
559 cep->myaddr = rep->myaddr;
560
561 /* 通信端点を設定する。*/
562 cep->fsm_state = TCP_FSM_LISTEN;
563
564#ifdef TCP_CFG_NON_BLOCKING
565
566 /* タイムアウトをチェックする。*/
567 if (tmout == TMO_NBLK) {
568 /* ノンブロッキングコール */
569 cep->p_dstaddr = p_dstaddr;
570 cep->rcv_nblk_tfn = TFN_TCP_ACP_CEP;
571 return E_WBLK;
572 }
573 else {
574
575#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
576
577 /*
578 * FSM が ESTABLISHED になるまで待
579つ。
580 * FSM が CLOSED になった場合は、エラーが発生したことを意味している。
581 */
582 error = twai_flg(cep->est_flgid, (TCP_CEP_EVT_CLOSED |
583 TCP_CEP_EVT_ESTABLISHED), TWF_ORW, &flag, tmout);
584 if (error == E_OK) {
585 if (cep->error != E_OK)
586 error = cep->error;
587 else if (cep->fsm_state == TCP_FSM_CLOSED)
588 error = E_TMOUT;
589 }
590
591 syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_ESTABLISHED)));
592
593 if (error == E_OK) {
594 /* 相手のアドレスをコピーする。*/
595 *p_dstaddr = cep->dstaddr;
596 }
597 else {
598 /*
599 * 通信端点から受付口を解放し、
600 * イベントフラグをクローズに設定する。
601 */
602 cep->rep = NULL;
603 cep->fsm_state = TCP_FSM_CLOSED;
604 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
605 }
606
607#ifdef TCP_CFG_NON_BLOCKING
608
609 }
610
611#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
612
613err_ret:
614 cep->rcv_tskid = TA_NULL;
615 cep->rcv_tfn = TFN_TCP_UNDEF;
616 return error;
617 }
618
619#endif /* of #ifdef __tcp_acp_cep */
620
621#endif /* of #ifdef TCP_CFG_PASSIVE_OPEN */
622
623/*
624 * tcp_con_cep -- 接続要求 (能動オープン)【標準機能】
625 */
626
627#ifdef __tcp_con_cep
628
629ER
630TCP_CON_CEP (ID cepid, T_IPEP *p_myaddr, T_IPEP *p_dstaddr, TMO tmout)
631{
632 T_TCP_CEP *cep;
633 ER error;
634 FLGPTN flag;
635
636#ifdef TCP_CFG_NON_BLOCKING
637
638 /*
639 * p_dstaddr または p_myaddr が NULL か、
640 * あてå…
641ˆãŒãƒžãƒ«ãƒã‚­ãƒ£ã‚¹ãƒˆã‚¢ãƒ‰ãƒ¬ã‚¹ãªã‚‰ã‚¨ãƒ©ãƒ¼
642 */
643 if (p_myaddr == NULL || p_dstaddr == NULL || IN_IS_ADDR_MULTICAST(&p_dstaddr->ipaddr))
644 return E_PAR;
645
646#else /* of #ifdef TCP_CFG_NON_BLOCKING */
647
648 /*
649 * p_dstaddr または p_myaddr が NULL 、
650 * あてå…
651ˆãŒãƒžãƒ«ãƒã‚­ãƒ£ã‚¹ãƒˆã‚¢ãƒ‰ãƒ¬ã‚¹ã‹ã€
652 * tmout が TMO_NBLK ならエラー
653 */
654 if (p_myaddr == NULL || p_dstaddr == NULL ||
655 IN_IS_ADDR_MULTICAST(&p_dstaddr->ipaddr) || tmout == TMO_NBLK)
656 return E_PAR;
657
658#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
659
660 /*
661 * CEP をロックし、API 機能コードとタスク識別子を記録する。
662 * すでに記録されていれば、ペンディング中なのでエラー
663 */
664 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_CON_CEP)) != E_OK)
665 return error;
666
667 /* CEP の FSM がクローズ状æ…
668‹ã§ãªã‘ればエラー。*/
669 if (cep->fsm_state != TCP_FSM_CLOSED) {
670 error = E_OBJ;
671 goto err_ret;
672 }
673 syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_CLOSED)));
674
675 /* シーケンス番号を初期化する。*/
676 if (tcp_iss == 0)
677 tcp_init_iss();
678
679 /* 通信端点を初期化する。*/
680 tcp_init_cep(cep);
681
682 /*
683 * p_myaddr が NADR (-1) ではなく、自 IP アドレスが ANY でなければ、
684 * 指定された IP アドレスを割り当てる。
685 */
686 if (p_myaddr != NADR && !IN_IS_ADDR_ANY(&p_myaddr->ipaddr))
687 cep->myaddr.ipaddr = p_myaddr->ipaddr;
688 else {
689 T_IN_IFADDR *ia;
690
691 if ((ia = IN_IFAWITHIFP(IF_GET_IFNET(), &p_dstaddr->ipaddr)) == NULL) {
692 error = E_PAR;
693 goto err_ret;
694 }
695 cep->myaddr.ipaddr = ia->addr;
696 }
697
698 /* 通信端点を設定する。*/
699 cep->fsm_state = TCP_FSM_SYN_SENT;
700 cep->dstaddr = *p_dstaddr;
701 cep->iss = tcp_iss;
702 cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_INIT;
703 tcp_iss += TCP_ISS_INCR() / 2;
704 init_send_seq(cep);
705
706#ifdef TCP_CFG_NON_BLOCKING
707
708 /* タイムアウトをチェックする。*/
709 if (tmout == TMO_NBLK) {
710 /* ノンブロッキングコール */
711 cep->p_dstaddr = p_dstaddr;
712 cep->p_myaddr = p_myaddr;
713 cep->snd_nblk_tfn = TFN_TCP_CON_CEP;
714
715 /* コネクションの開設をポストする。*/
716 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
717 sig_sem(SEM_TCP_POST_OUTPUT);
718 return E_WBLK;
719 }
720 else {
721
722#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
723
724 /*
725 * p_myaddr が NADR (-1) か、
726 * 自ポート番号が TCP_PORTANY なら、自動で割り当てる。
727 */
728 if (p_myaddr == NADR || p_myaddr->portno == TCP_PORTANY)
729 tcp_alloc_auto_port(cep);
730 else if ((error = tcp_alloc_port(cep, p_myaddr->portno)) != E_OK)
731 goto err_ret;
732
733 /* コネクションの開設をポストする。*/
734 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
735 sig_sem(SEM_TCP_POST_OUTPUT);
736
737 /*
738 * イベントが ESTABLISHED になるまで待
739つ。
740 * イベントが CLOSED になった場合は、何らかのエラーが発生したか、
741 * 接続要求が拒否されたことを意味している。
742 */
743 error = twai_flg(cep->est_flgid, (TCP_CEP_EVT_CLOSED |
744 TCP_CEP_EVT_ESTABLISHED), TWF_ORW, &flag, tmout);
745 if (error == E_OK) {
746 if (cep->error != E_OK)
747 error = cep->error;
748 else if (cep->fsm_state == TCP_FSM_CLOSED)
749 error = E_CLS;
750 }
751
752 syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_ESTABLISHED)));
753
754 if (error != E_OK) {
755 /*
756 * 通信端点から受付口を解放し、
757 * イベントフラグをクローズに設定する。
758 */
759 cep->rep = NULL;
760 cep->fsm_state = TCP_FSM_CLOSED;
761 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
762 }
763
764#ifdef TCP_CFG_NON_BLOCKING
765
766 }
767
768#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
769
770err_ret:
771 cep->snd_tskid = TA_NULL;
772 cep->snd_tfn = TFN_TCP_UNDEF;
773 return error;
774 }
775
776#endif /* of #ifdef __tcp_con_cep */
777
778#ifdef __tcp_cls_cep
779
780/*
781 * tcp_user_closed -- ユーザからのコネクションの開放
782 */
783
784T_TCP_CEP *
785tcp_user_closed (T_TCP_CEP *cep)
786{
787 switch (cep->fsm_state) {
788
789 case TCP_FSM_CLOSED: /* クローズ */
790 case TCP_FSM_LISTEN: /* 受動オープン */
791 cep->fsm_state = TCP_FSM_CLOSED;
792 cep = tcp_close(cep);
793 break;
794
795 case TCP_FSM_SYN_SENT: /* 能動オープン、SYN 送信済み */
796 case TCP_FSM_SYN_RECVD: /* SYN を受信し、SYN 送信済み */
797 cep->flags |= TCP_CEP_FLG_NEED_FIN;
798 break;
799
800 case TCP_FSM_ESTABLISHED: /* コネクション開設完了 */
801 cep->fsm_state = TCP_FSM_FIN_WAIT_1;
802 break;
803
804 case TCP_FSM_CLOSE_WAIT: /* 相手から FIN 受信、APP の終了待
805ち */
806 cep->fsm_state = TCP_FSM_LAST_ACK;
807 break;
808 }
809
810 if (cep != NULL && cep->fsm_state == TCP_FSM_FIN_WAIT_2)
811 cep->timer[TCP_TIM_2MSL] = TCP_TVAL_KEEP_COUNT * TCP_TVAL_KEEP_INTERVAL;
812 return cep;
813 }
814
815/*
816 * tcp_cls_cep -- 通信端点のクローズ【標準機能】
817 */
818
819ER
820tcp_cls_cep (ID cepid, TMO tmout)
821{
822 T_TCP_CEP *cep;
823 ER error = E_OK;
824 FLGPTN flag;
825
826#ifndef TCP_CFG_NON_BLOCKING
827
828 /* tmout が TMO_NBLK ならエラー */
829 if (tmout == TMO_NBLK)
830 return E_PAR;
831
832#endif /* of #ifndef TCP_CFG_NON_BLOCKING */
833
834 /*
835 * CEP をロックし、API 機能コードとタスク識別子を記録する。
836 * すでに記録されていれば、ペンディング中なのでエラー
837 */
838 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_CLS_CEP)) != E_OK)
839 return error;
840
841#ifdef TCP_CFG_NON_BLOCKING
842
843 /* タイムアウトをチェックする。*/
844 if (tmout == TMO_NBLK) { /* ノンブロッキングコール */
845
846 if (!IS_PTR_DEFINED(cep->callback))
847 error = E_OBJ;
848 else if (cep->fsm_state == TCP_FSM_CLOSED) { /* すでにクローズされているとき */
849
850#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
851
852 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_CLS_CEP, E_OK);
853 error = E_WBLK;
854
855#else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
856
857 ER error = E_OK;
858
859 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_CLS_CEP, (void*)&error);
860 error = E_WBLK;
861
862#endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
863
864 }
865 else {
866 /* NBLK のAPI 機能コードを設定する。*/
867 cep->rcv_nblk_tfn = TFN_TCP_CLS_CEP;
868
869 if ((cep = tcp_user_closed(cep)) != NULL) { /* コネクションを切断する。*/
870 /* 切断セグメント出力をポストする。*/
871 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
872 sig_sem(SEM_TCP_POST_OUTPUT);
873 }
874
875 /* cep が NULL で戻ってきた場合は、
876 * 既にコネクションが切断されていることを意味している。
877 * また、この場合コールバック関数が呼び出されている。
878 */
879 return E_WBLK;
880 }
881 }
882 else { /* 非ノンブロッキングコール */
883
884#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
885
886 if ((cep = tcp_user_closed(cep)) == NULL) { /* コネクションを切断する。*/
887
888 /* cep が NULL で戻ってきた場合は、
889 * 既にコネクションが切断されていることを意味している。
890 */
891 return error;
892 }
893 else {
894 /* 切断セグメント出力をポストする。*/
895 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
896 sig_sem(SEM_TCP_POST_OUTPUT);
897
898 /* イベントフラグが CLOSED になるまで待
899つ。*/
900 error = twai_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED, TWF_ORW, &flag, tmout);
901 if (error == E_OK && cep->error != E_OK)
902 error = cep->error;
903
904 if (error != E_OK) {
905 if (error == E_RLWAI) {
906 /* tcp_cls_cep がキャンセルされたときは、RST を送信する。*/
907 tcp_respond(NULL, cep, cep->rcv_nxt, cep->snd_una - 1,
908 cep->rbufsz - cep->rwbuf_count, TCP_FLG_RST);
909 }
910
911 /* タイマーを停止する。*/
912 tcp_cancel_timers(cep);
913
914 /*
915 * 通信端点をロックし、
916 * 受信再構成キューのネットワークバッファを解放する。
917 */
918 syscall(wai_sem(cep->semid_lock));
919 tcp_free_reassq(cep);
920 syscall(sig_sem(cep->semid_lock));
921
922 /* 状æ…
923‹ã‚’未使用にする。*/
924 cep->fsm_state = TCP_FSM_CLOSED;
925
926 /*
927 * 以下に関係しないフラグをクリアーする。
928 * ・送受信ウィンドバッファの省コピー機能
929 * ・動的な通信端点の生成・削除機能
930 */
931 cep->flags &= (TCP_CEP_FLG_WBCS_NBUF_REQ | TCP_CEP_FLG_WBCS_MASK |
932 TCP_CEP_FLG_DYNAMIC | TCP_CEP_FLG_VALID);
933
934 /*
935 * 通信端点をロックし、
936 * 送受信ウィンドバッファキューのネットワークバッファを解放する。
937 */
938 cep->rwbuf_count = 0;
939 syscall(wai_sem(cep->semid_lock));
940 TCP_FREE_RWBUFQ(cep);
941 TCP_FREE_SWBUFQ(cep);
942 syscall(sig_sem(cep->semid_lock));
943
944 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
945 }
946 }
947
948#ifdef TCP_CFG_NON_BLOCKING
949
950 }
951
952#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
953
954 cep->rcv_tskid = TA_NULL;
955 cep->rcv_tfn = TFN_TCP_UNDEF;
956 return error;
957 }
958
959#endif /* of #ifdef __tcp_cls_cep */
960
961#ifdef __tcp_sht_cep
962
963/*
964 * tcp_sht_cep -- データ送信の終了【標準機能】
965 */
966
967ER
968tcp_sht_cep (ID cepid)
969{
970 T_TCP_CEP *cep;
971 ER error = E_OK;
972
973 /*
974 * CEP をロックし、API 機能コードとタスク識別子を記録する。
975 * すでに記録されていれば、ペンディング中なのでエラー
976 */
977 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_SHT_CEP)) != E_OK)
978 return error;
979
980 /* TCP 通信端点のコネクションが確立状æ…
981‹ã§ãªã‘ればエラー */
982 if (!TCP_FSM_HAVE_ESTABLISHED(cep->fsm_state)) {
983 if ((error = cep->error) == E_OK)
984 error = E_OBJ;
985 }
986
987 else if ((cep = tcp_user_closed(cep)) != NULL) { /* コネクションを切断する。*/
988
989 /* 切断セグメント出力をポストする。*/
990 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
991 sig_sem(SEM_TCP_POST_OUTPUT);
992 }
993
994 cep->snd_tskid = TA_NULL;
995 cep->snd_tfn = TFN_TCP_UNDEF;
996 return error;
997 }
998
999#endif /* of #ifdef __tcp_sht_cep */
1000
1001#ifdef __tcp_snd_dat
1002
1003/*
1004 * tcp_snd_dat -- パケットの送信【標準機能】
1005 */
1006
1007ER_UINT
1008tcp_snd_dat (ID cepid, void *data, int_t len, TMO tmout)
1009{
1010 T_TCP_CEP *cep;
1011 ER_UINT error;
1012
1013#ifdef TCP_CFG_NON_BLOCKING
1014
1015 /* data が NULL か、len < 0 ならエラー */
1016 if (data == NULL || len < 0)
1017 return E_PAR;
1018
1019#else /* of #ifdef TCP_CFG_NON_BLOCKING */
1020
1021 /* data が NULL、len < 0 か、tmout が TMO_NBLK ならエラー */
1022 if (data == NULL || len < 0 || tmout == TMO_NBLK)
1023 return E_PAR;
1024
1025#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1026
1027 /*
1028 * CEP をロックし、API 機能コードとタスク識別子を記録する。
1029 * すでに記録されていれば、ペンディング中なのでエラー
1030 */
1031 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_SND_DAT)) != E_OK)
1032 return error;
1033
1034 /* 送信できるか、通信端点の状æ…
1035‹ã‚’見る。*/
1036 if ((error = tcp_can_send_more(cep, TFN_TCP_SND_DAT, tmout)) != E_OK)
1037 goto err_ret;
1038
1039#ifdef TCP_CFG_NON_BLOCKING
1040
1041 /* タイムアウトをチェックする。*/
1042 if (tmout == TMO_NBLK) { /* ノンブロッキングコール */
1043
1044 /* 送信ウィンドバッファに空きがあればコールバック関数を呼び出す。*/
1045 if (!TCP_IS_SWBUF_FULL(cep)) {
1046
1047 /* 送信ウィンドバッファにデータを書き込む。*/
1048 error = TCP_WRITE_SWBUF(cep, data, (uint_t)len);
1049
1050 /* 出力をポストする。*/
1051 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
1052 sig_sem(SEM_TCP_POST_OUTPUT);
1053
1054#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
1055
1056 /* コールバック関数を呼び出す。*/
1057 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_DAT, (void*)error);
1058
1059#else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1060
1061 /* コールバック関数を呼び出す。*/
1062 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_DAT, (void*)&error);
1063
1064#endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1065
1066 error = E_WBLK;
1067 goto err_ret;
1068 }
1069 else {
1070 cep->snd_data = data;
1071 cep->snd_len = len;
1072 cep->snd_nblk_tfn = TFN_TCP_SND_DAT;
1073 TCP_ALLOC_SWBUF(cep);
1074
1075 return E_WBLK;
1076 }
1077 }
1078 else { /* 非ノンブロッキングコール */
1079
1080#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1081
1082 /* 送信ウィンドバッファが空くのを待
1083つ。*/
1084 if ((error = TCP_WAIT_SWBUF(cep, tmout)) != E_OK)
1085 goto err_ret;
1086
1087 /* 送信ウィンドバッファにデータを書き込む。*/
1088 if ((error = TCP_WRITE_SWBUF(cep, data, (uint_t)len)) > 0) {
1089
1090 /* データを送信する。送信ウィンドバッファがフルのときは強制的に送信する。*/
1091 if (TCP_IS_SWBUF_FULL(cep))
1092 cep->flags |= TCP_CEP_FLG_FORCE | TCP_CEP_FLG_FORCE_CLEAR;
1093
1094 /* 出力をポストする。*/
1095 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
1096 sig_sem(SEM_TCP_POST_OUTPUT);
1097 }
1098
1099#ifdef TCP_CFG_NON_BLOCKING
1100
1101 }
1102
1103#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1104
1105err_ret:
1106 cep->snd_tskid = TA_NULL;
1107 cep->snd_tfn = TFN_TCP_UNDEF;
1108 return error;
1109 }
1110
1111#endif /* of #ifdef __tcp_snd_dat */
1112
1113#ifdef __tcp_snd_oob
1114
1115#ifdef TCP_CFG_EXTENTIONS
1116
1117/*
1118 * tcp_snd_oob -- 緊急データの送信【拡張機能】
1119 */
1120
1121ER_UINT
1122tcp_snd_oob (ID cepid, void *data, int_t len, TMO tmout)
1123{
1124 T_TCP_CEP *cep;
1125 ER_UINT error;
1126
1127#ifdef TCP_CFG_NON_BLOCKING
1128
1129 /* data が NULL か、len < 0 ならエラー */
1130 if (data == NULL || len < 0)
1131 return E_PAR;
1132
1133#else /* of #ifdef TCP_CFG_NON_BLOCKING */
1134
1135 /* data が NULL、len < 0 か、tmout が TMO_NBLK ならエラー */
1136 if (data == NULL || len < 0 || tmout == TMO_NBLK)
1137 return E_PAR;
1138
1139#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1140
1141 /*
1142 * CEP をロックし、API 機能コードとタスク識別子を記録する。
1143 * すでに記録されていれば、ペンディング中なのでエラー
1144 */
1145 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_SND_OOB)) != E_OK)
1146 return error;
1147
1148 /* 送信できるか、通信端点の状æ…
1149‹ã‚’見る。*/
1150 if ((error = tcp_can_send_more(cep, TFN_TCP_SND_OOB, tmout)) != E_OK)
1151 goto err_ret;
1152
1153#ifdef TCP_CFG_NON_BLOCKING
1154
1155 /* タイムアウトをチェックする。*/
1156 if (tmout == TMO_NBLK) { /* ノンブロッキングコール */
1157
1158 /* 送信ウィンドバッファに空きがあればコールバック関数を呼び出す。*/
1159 if (!TCP_IS_SWBUF_FULL(cep)) {
1160
1161 /* 送信ウィンドバッファにデータを書き込む。*/
1162 error = TCP_WRITE_SWBUF(cep, data, (uint_t)len);
1163
1164 /* 送信緊急ポインタを設定する。*/
1165 cep->snd_up = cep->snd_una + cep->swbuf_count;
1166
1167 /* 出力をポストする。*/
1168 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
1169 sig_sem(SEM_TCP_POST_OUTPUT);
1170
1171#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
1172
1173 /* コールバック関数を呼び出す。*/
1174 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_OOB, (void*)error);
1175
1176#else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1177
1178 /* コールバック関数を呼び出す。*/
1179 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_OOB, (void*)&error);
1180
1181#endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1182
1183 error = E_WBLK;
1184 goto err_ret;
1185 }
1186 else {
1187 cep->snd_data = data;
1188 cep->snd_len = len;
1189 cep->snd_nblk_tfn = TFN_TCP_SND_OOB;
1190 TCP_ALLOC_SWBUF(cep);
1191
1192 return E_WBLK;
1193 }
1194 }
1195 else { /* 非ノンブロッキングコール */
1196
1197#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1198
1199 /* 送信ウィンドバッファが空くのを待
1200つ。*/
1201 if ((error = TCP_WAIT_SWBUF(cep, tmout)) != E_OK)
1202 goto err_ret;
1203
1204 /* 送信ウィンドバッファにデータを書き込む。*/
1205 if ((error = TCP_WRITE_SWBUF(cep, data, (uint_t)len)) > 0) {
1206
1207 /* 送信緊急ポインタを設定する。*/
1208 cep->snd_up = cep->snd_una + cep->swbuf_count;
1209
1210 /* データを送信する。送信ウィンドバッファがフルのときは強制的に送信する。*/
1211 if (TCP_IS_SWBUF_FULL(cep))
1212 cep->flags |= TCP_CEP_FLG_FORCE | TCP_CEP_FLG_FORCE_CLEAR;
1213
1214 /* 出力をポストする。*/
1215 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
1216 sig_sem(SEM_TCP_POST_OUTPUT);
1217 }
1218
1219#ifdef TCP_CFG_NON_BLOCKING
1220
1221 }
1222
1223#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1224
1225err_ret:
1226 cep->snd_tskid = TA_NULL;
1227 cep->snd_tfn = TFN_TCP_UNDEF;
1228 return error;
1229 }
1230
1231#endif /* of #ifdef TCP_CFG_EXTENTIONS */
1232
1233#endif /* of #ifdef __tcp_snd_oob */
1234
1235#ifdef __tcp_get_buf
1236
1237/*
1238 * tcp_get_buf -- 送信用バッファの獲得【標準機能】
1239 */
1240
1241ER_UINT
1242tcp_get_buf (ID cepid, void **p_buf, TMO tmout)
1243{
1244 T_TCP_CEP *cep;
1245 ER_UINT error;
1246
1247#ifdef TCP_CFG_NON_BLOCKING
1248
1249 /* p_buf が NULL ならエラー */
1250 if (p_buf == NULL)
1251 return E_PAR;
1252
1253#else /* of #ifdef TCP_CFG_NON_BLOCKING */
1254
1255 /* p_buf が NULL か、tmout が TMO_NBLK ならエラー */
1256 if (p_buf == NULL || tmout == TMO_NBLK)
1257 return E_PAR;
1258
1259#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1260
1261 /*
1262 * CEP をロックし、API 機能コードとタスク識別子を記録する。
1263 * すでに記録されていれば、ペンディング中なのでエラー
1264 */
1265 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_GET_BUF)) != E_OK)
1266 return error;
1267
1268 /* 送信できるか、通信端点の状æ…
1269‹ã‚’見る。*/
1270 if ((error = tcp_can_send_more(cep, TFN_TCP_GET_BUF, tmout)) != E_OK)
1271 goto err_ret;
1272
1273#ifdef TCP_CFG_NON_BLOCKING
1274
1275 /* タイムアウトをチェックする。*/
1276 if (tmout == TMO_NBLK) { /* ノンブロッキングコール */
1277
1278 if (!TCP_IS_SWBUF_FULL(cep)) {
1279
1280 /* 送信ウィンドバッファに空きがあればコールバック関数を呼び出す。*/
1281 error = TCP_GET_SWBUF_ADDR(cep, p_buf);
1282
1283#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
1284
1285 /* コールバック関数を呼び出す。*/
1286 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_GET_BUF, (void*)error);
1287
1288#else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1289
1290 /* コールバック関数を呼び出す。*/
1291 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_GET_BUF, (void*)&error);
1292
1293#endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1294
1295 error = E_WBLK;
1296 goto err_ret;
1297 }
1298 else {
1299 cep->snd_p_buf = p_buf;
1300 cep->snd_nblk_tfn = TFN_TCP_GET_BUF;
1301 TCP_ALLOC_SWBUF(cep);
1302 return E_WBLK;
1303 }
1304 }
1305
1306 else { /* 非ノンブロッキングコール */
1307
1308#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1309
1310 /* 送信ウィンドバッファが空くのを待
1311つ。*/
1312 if ((error = TCP_WAIT_SWBUF(cep, tmout)) != E_OK)
1313 goto err_ret;
1314
1315 /* 送信ウィンドバッファの空アドレスを獲得する。*/
1316 error = TCP_GET_SWBUF_ADDR(cep, p_buf);
1317
1318#ifdef TCP_CFG_NON_BLOCKING
1319
1320 }
1321
1322#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1323
1324err_ret:
1325 cep->snd_tskid = TA_NULL;
1326 cep->snd_tfn = TFN_TCP_UNDEF;
1327 return error;
1328 }
1329
1330#endif /* of #ifdef __tcp_get_buf */
1331
1332#ifdef __tcp_snd_buf
1333
1334/*
1335 * tcp_snd_buf -- バッファ内
1336のデータの送信【標準機能】
1337 */
1338
1339ER
1340tcp_snd_buf (ID cepid, int_t len)
1341{
1342 T_TCP_CEP *cep;
1343 ER error;
1344
1345 /* 送信する長さ len をチェックする。*/
1346 if (len < 0)
1347 return E_PAR;
1348
1349 /* 送信する長さlen が 0 であれば、何もしないで戻る。*/
1350 if (len == 0)
1351 return E_OK;
1352
1353 /*
1354 * CEP をロックし、API 機能コードとタスク識別子を記録する。
1355 * すでに記録されていれば、ペンディング中なのでエラー
1356 */
1357 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_SND_BUF)) != E_OK)
1358 return error;
1359
1360 /* 送信する長さ len をチェックする。*/
1361 if (len > cep->get_buf_len) {
1362 error = E_OBJ;
1363 goto err_ret;
1364 }
1365
1366 /* 送信できるか、CEP の FSM 状æ…
1367‹ã‚’見る。*/
1368 if (!TCP_FSM_CAN_SEND_MORE(cep->fsm_state)) {
1369 if ((error = cep->error) == E_OK)
1370 error = E_OBJ;
1371 goto err_ret;
1372 }
1373
1374 /* 送信ウィンドバッファのデータを送信可能にする。*/
1375 TCP_SEND_SWBUF(cep, (uint_t)len);
1376
1377 /* 出力をポストする。*/
1378 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
1379 sig_sem(SEM_TCP_POST_OUTPUT);
1380
1381err_ret:
1382 cep->snd_tskid = TA_NULL;
1383 cep->snd_tfn = TFN_TCP_UNDEF;
1384 return error;
1385 }
1386
1387#endif /* of #ifdef __tcp_snd_buf */
1388
1389#ifdef __tcp_rcv_dat
1390
1391/*
1392 * tcp_rcv_dat -- パケットの受信【標準機能】
1393 */
1394
1395ER_UINT
1396tcp_rcv_dat (ID cepid, void *data, int_t len, TMO tmout)
1397{
1398 T_TCP_CEP *cep;
1399 ER_UINT error;
1400
1401#ifdef TCP_CFG_NON_BLOCKING
1402
1403 /* data が NULL か、len < 0 ならエラー */
1404 if (data == NULL || len < 0)
1405 return E_PAR;
1406
1407#else /* of #ifdef TCP_CFG_NON_BLOCKING */
1408
1409 /* data が NULL、len < 0 か、tmout が TMO_NBLK ならエラー */
1410 if (data == NULL || len < 0 || tmout == TMO_NBLK)
1411 return E_PAR;
1412
1413#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1414
1415 /*
1416 * CEP をロックし、API 機能コードとタスク識別子を記録する。
1417 * すでに記録されていれば、ペンディング中なのでエラー
1418 */
1419 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_RCV_DAT)) != E_OK)
1420 return error;
1421
1422 /* 受信できるか、通信端点の状æ…
1423‹ã‚’見る。*/
1424 if (tcp_can_recv_more(&error, cep, TFN_TCP_RCV_DAT, tmout) != E_OK)
1425 goto err_ret;
1426
1427#ifdef TCP_CFG_NON_BLOCKING
1428
1429 /* タイムアウトをチェックする。*/
1430 if (tmout == TMO_NBLK) { /* ノンブロッキングコール */
1431
1432 /* 受信ウィンドバッファにデータがあればコールバック関数を呼び出す。*/
1433 if (cep->rwbuf_count > 0) {
1434
1435 /* 受信ウィンドバッファからデータを取り出す。*/
1436 len = TCP_READ_RWBUF(cep, data, (uint_t)len);
1437
1438#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
1439
1440 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_DAT, (void*)(uint32_t)len);
1441
1442#else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1443
1444 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_DAT, (void*)&len);
1445
1446#endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1447
1448 error = E_WBLK;
1449 goto err_ret;
1450 }
1451 else {
1452 cep->rcv_data = data;
1453 cep->rcv_len = len;
1454 cep->rcv_nblk_tfn = TFN_TCP_RCV_DAT;
1455 return E_WBLK;
1456 }
1457 }
1458 else { /* 非ノンブロッキングコール */
1459
1460#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1461
1462 /* 受信ウィンドバッファにデータがなければ、å…
1463¥åŠ›ãŒã‚るまで待
1464つ。*/
1465 if ((error = tcp_wait_rwbuf(cep, tmout)) != E_OK)
1466 goto err_ret;
1467
1468 /* 受信ウィンドバッファからデータを取り出す。*/
1469 error = TCP_READ_RWBUF(cep, data, (uint_t)len);
1470
1471 /* 相手にウィンドウサイズが変わったことを知らせるため出力をポストする。*/
1472 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
1473 sig_sem(SEM_TCP_POST_OUTPUT);
1474
1475#ifdef TCP_CFG_NON_BLOCKING
1476
1477 }
1478
1479#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1480
1481err_ret:
1482 cep->rcv_tskid = TA_NULL;
1483 cep->rcv_tfn = TFN_TCP_UNDEF;
1484 return error;
1485 }
1486
1487#endif /* of #ifdef __tcp_rcv_dat */
1488
1489#ifdef __tcp_rcv_oob
1490
1491#ifdef TCP_CFG_EXTENTIONS
1492
1493/*
1494 * tcp_rcv_oob -- 緊急データの受信【拡張機能】
1495 *
1496 * 注意: 送信側が複数オクテットのデータを送信しても、
1497 * 緊急ポインタが指す 1 オクテットのデータのみ受信する。
1498 */
1499
1500ER_UINT
1501tcp_rcv_oob (ID cepid, void *data, int_t len)
1502{
1503 T_TCP_CEP *cep;
1504 uint8_t *urg;
1505
1506 /* TCP 通信端点 ID をチェックする。*/
1507 if (!VAID_TCP_CEPID(cepid))
1508 return E_ID;
1509
1510 /* data が NULL か、len < 0 ならエラー */
1511 if (data == NULL || len < 0)
1512 return E_PAR;
1513
1514 /* TCP 通信端点を得る。*/
1515 cep = GET_TCP_CEP(cepid);
1516
1517 /* 受信できるか、通信端点の状æ…
1518‹ã‚’見る。*/
1519 /* 受信できるか、fsm_state を見る。*/
1520 if (!TCP_FSM_CAN_RECV_MORE(cep->fsm_state))
1521 return E_OBJ;
1522
1523 /*
1524 * 緊急データå…
1525¥ã‚Šã®ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã® TCP ヘッダが
1526 * 設定されていなければ、緊急データを受信していない。
1527 */
1528 if (cep->urg_tcph == NULL)
1529 return E_OBJ;
1530
1531 /* len == 0 ならバッファオーバーフロー */
1532 if (len == 0)
1533 return E_BOVR;
1534
1535 /* 緊急ポインタが指す 1 オクテットのデータを読み取る。*/
1536 urg = (uint8_t*)cep->urg_tcph + TCP_DATA_OFF(cep->urg_tcph->doff) + cep->urg_tcph->urp + TCP_CFG_URG_OFFSET;
1537 *(uint8_t*)data = *urg;
1538
1539 /* 読み取ったデータから後ろの SDU を前に詰める。*/
1540 memcpy(urg, urg + 1, cep->urg_tcph->sum - (cep->urg_tcph->urp + TCP_CFG_URG_OFFSET) - 1);
1541
1542 /* tcp_rcv_oob() が呼出されたこと知らせるために、NULL を設定する。*/
1543 cep->urg_tcph = NULL;
1544
1545 return 1;
1546 }
1547
1548#endif /* of #ifdef TCP_CFG_EXTENTIONS */
1549
1550#endif /* of #ifdef __tcp_rcv_oob */
1551
1552#ifdef __tcp_rcv_buf
1553
1554/*
1555 * tcp_rcv_buf -- 受信したデータのå…
1556¥ã£ãŸãƒãƒƒãƒ•ã‚¡ã®ç²å¾—【標準機能】
1557 */
1558
1559ER_UINT
1560tcp_rcv_buf (ID cepid, void **p_buf, TMO tmout)
1561{
1562 T_TCP_CEP *cep;
1563 ER_UINT error;
1564
1565#ifdef TCP_CFG_NON_BLOCKING
1566
1567 /* p_buf が NULL ならエラー */
1568 if (p_buf == NULL)
1569 return E_PAR;
1570
1571#else /* of #ifdef TCP_CFG_NON_BLOCKING */
1572
1573 /* p_buf が NULL か、tmout が TMO_NBLK ならエラー */
1574 if (p_buf == NULL || tmout == TMO_NBLK)
1575 return E_PAR;
1576
1577#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1578
1579 /*
1580 * CEP をロックし、API 機能コードとタスク識別子を記録する。
1581 * すでに記録されていれば、ペンディング中なのでエラー
1582 */
1583 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_RCV_BUF)) != E_OK)
1584 return error;
1585
1586 /* 受信できるか、通信端点の状æ…
1587‹ã‚’見る。*/
1588 if (tcp_can_recv_more(&error, cep, TFN_TCP_RCV_DAT, tmout) != E_OK)
1589 goto err_ret;
1590
1591#ifdef TCP_CFG_NON_BLOCKING
1592
1593 /* タイムアウトをチェックする。*/
1594 if (tmout == TMO_NBLK) { /* ノンブロッキングコール */
1595
1596 /* 受信ウィンドバッファにデータがあればコールバック関数を呼び出す。*/
1597 if (cep->rwbuf_count > 0) {
1598
1599 /* 受信ウィンドバッファの空アドレスを獲得する。*/
1600 error = TCP_GET_RWBUF_ADDR(cep, p_buf);
1601
1602#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
1603
1604 /* コールバック関数を呼び出す。*/
1605 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_BUF, (void*)error);
1606
1607#else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1608
1609 /* コールバック関数を呼び出す。*/
1610 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_BUF, (void*)&error);
1611
1612#endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1613
1614 error = E_WBLK;
1615 goto err_ret;
1616 }
1617 else {
1618 cep->rcv_p_buf = p_buf;
1619 cep->rcv_nblk_tfn = TFN_TCP_RCV_BUF;
1620 return E_WBLK;
1621 }
1622 }
1623 else { /* 非ノンブロッキングコール */
1624
1625#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1626
1627 /* 受信ウィンドバッファにデータがなければ、å…
1628¥åŠ›ãŒã‚るまで待
1629つ。*/
1630 if ((error = tcp_wait_rwbuf(cep, tmout)) != E_OK) {
1631 cep->rwbuf_count = 0;
1632 goto err_ret;
1633 }
1634
1635 /* 受信ウィンドバッファのアドレスを獲得する。*/
1636 error = TCP_GET_RWBUF_ADDR(cep, p_buf);
1637
1638#ifdef TCP_CFG_NON_BLOCKING
1639
1640 }
1641
1642#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1643
1644err_ret:
1645 cep->rcv_tskid = TA_NULL;
1646 cep->rcv_tfn = TFN_TCP_UNDEF;
1647 return error;
1648 }
1649
1650#endif /* of #ifdef __tcp_rcv_buf */
1651
1652#ifdef __tcp_rel_buf
1653
1654/*
1655 * tcp_rel_buf -- 受信用バッファの解放【標準機能】
1656 */
1657
1658ER
1659tcp_rel_buf (ID cepid, int_t len)
1660{
1661 T_TCP_CEP *cep;
1662 ER error;
1663
1664 /* 解放する長さ len をチェックする。*/
1665 if (len < 0)
1666 return E_PAR;
1667
1668 /*
1669 * CEP をロックし、API 機能コードとタスク識別子を記録する。
1670 * すでに記録されていれば、ペンディング中なのでエラー
1671 */
1672 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_REL_BUF)) != E_OK)
1673 return error;
1674
1675 /* 解放する長さ len をチェックする。*/
1676 if (len > cep->rcv_buf_len) {
1677 error = E_OBJ;
1678 goto err_ret;
1679 }
1680
1681 /* 通信端点をロックする。*/
1682 syscall(wai_sem(cep->semid_lock));
1683
1684 /* 受信ウィンドバッファから受信したオクテットを削除する。*/
1685 TCP_DROP_RWBUF(cep, (uint_t)len);
1686
1687 /* tcp_rcv_buf の割当て長をリセットする。*/
1688 cep->rcv_buf_len = 0;
1689
1690 /* 通信端点のロックを解除する。*/
1691 syscall(sig_sem(cep->semid_lock));
1692
1693 /* 相手にウィンドウサイズが変わったことを知らせるため出力をポストする。*/
1694 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
1695 sig_sem(SEM_TCP_POST_OUTPUT);
1696
1697err_ret:
1698 cep->rcv_tskid = TA_NULL;
1699 cep->rcv_tfn = TFN_TCP_UNDEF;
1700 return error;
1701 }
1702
1703#endif /* of #ifdef __tcp_rel_buf */
1704
1705#ifdef __tcp_can_cep
1706
1707/*
1708 * tcp_can_snd -- ペンディングしている送信のキャンセル
1709 */
1710
1711static ER
1712tcp_can_snd (T_TCP_CEP *cep, FN fncd)
1713{
1714 ER error = E_OK;
1715
1716 /* 通信端点をロックする。*/
1717 syscall(wai_sem(cep->semid_lock));
1718
1719 /*
1720 * snd_tskid が TA_NULL なら、
1721 * ペンディングしていないのでエラー
1722 */
1723 if (cep->snd_tskid == TA_NULL)
1724 error = EV_NOPND;
1725
1726 /* ペンディング中の API 機能コードと一致しなければエラー */
1727 else if (fncd != TFN_TCP_ALL && fncd != cep->snd_tfn)
1728 error = E_OBJ;
1729
1730 /* 処理をキャンセルする。*/
1731 else {
1732
1733 /* 受信再構成キューのネットワークバッファを解放する。*/
1734 tcp_free_reassq(cep);
1735
1736 /* 受信ウィンドバッファキューのネットワークバッファを解放する。*/
1737 cep->rwbuf_count = 0;
1738 TCP_FREE_RWBUFQ(cep);
1739
1740 /* 送信ウィンドバッファキューのネットワークバッファを解放する。*/
1741 TCP_FREE_SWBUFQ(cep);
1742
1743#ifdef TCP_CFG_NON_BLOCKING
1744
1745 if (cep->snd_nblk_tfn != TFN_TCP_UNDEF) { /* ノンブロッキングコール */
1746
1747 switch (cep->snd_nblk_tfn) {
1748
1749 case TFN_TCP_CON_CEP:
1750 /* 通信端点から受付口を解放する。*/
1751 cep->rep = NULL;
1752 cep->fsm_state = TCP_FSM_CLOSED;
1753 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
1754 break;
1755
1756 case TFN_TCP_SND_DAT:
1757 case TFN_TCP_GET_BUF:
1758 case TFN_TCP_SND_OOB:
1759 break;
1760 }
1761
1762 if (IS_PTR_DEFINED(cep->callback)) {
1763
1764#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
1765
1766 (*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)E_RLWAI);
1767
1768#else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1769
1770 ER error = E_RLWAI;
1771
1772 (*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&error);
1773
1774#endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1775
1776 }
1777 else
1778 error = E_OBJ;
1779 cep->snd_nblk_tfn = TFN_TCP_UNDEF;
1780 }
1781 else
1782
1783#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1784
1785 error = rel_wai(cep->snd_tskid);
1786
1787 cep->snd_tskid = TA_NULL;
1788 cep->snd_tfn = TFN_TCP_UNDEF;
1789 }
1790
1791 /* 通信端点のロックを解除する。*/
1792 syscall(sig_sem(cep->semid_lock));
1793
1794 return error;
1795 }
1796
1797/*
1798 * tcp_can_rcv -- ペンディングしている受信のキャンセル
1799 */
1800
1801static ER
1802tcp_can_rcv (T_TCP_CEP *cep, FN fncd)
1803{
1804 ER error = E_OK;
1805
1806 /* 通信端点をロックする。*/
1807 syscall(wai_sem(cep->semid_lock));
1808
1809 /*
1810 * rcv_tskid が TA_NULL なら、
1811 * ペンディングしていないのでエラー
1812 */
1813 if (cep->rcv_tskid == TA_NULL)
1814 error = EV_NOPND;
1815
1816 /* ペンディング中の API 機能コードと一致しなければエラー */
1817 else if (fncd != TFN_TCP_ALL && fncd != cep->rcv_tfn)
1818 error = E_OBJ;
1819
1820 /* 処理をキャンセルする。*/
1821 else {
1822
1823 /* 受信再構成キューのネットワークバッファを解放する。*/
1824 tcp_free_reassq(cep);
1825
1826 /* 受信ウィンドバッファキューのネットワークバッファを解放する。*/
1827 cep->rwbuf_count = 0;
1828 TCP_FREE_RWBUFQ(cep);
1829
1830 /* 送信ウィンドバッファキューのネットワークバッファを解放する。*/
1831 TCP_FREE_SWBUFQ(cep);
1832
1833#ifdef TCP_CFG_NON_BLOCKING
1834
1835 if (cep->rcv_nblk_tfn != TFN_TCP_UNDEF) { /* ノンブロッキングコール */
1836
1837 switch (cep->rcv_nblk_tfn) {
1838
1839 case TFN_TCP_ACP_CEP:
1840 /*
1841 * 通信端点から受付口を解放し、
1842 * イベントフラグをクローズに設定する。
1843 */
1844 cep->rep = NULL;
1845 cep->fsm_state = TCP_FSM_CLOSED;
1846 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
1847 break;
1848
1849 case TFN_TCP_RCV_DAT:
1850 case TFN_TCP_RCV_BUF:
1851 break;
1852
1853 case TFN_TCP_CLS_CEP:
1854 cep->fsm_state = TCP_FSM_CLOSED;
1855 tcp_respond(NULL, cep, cep->rcv_nxt, cep->snd_una - 1,
1856 cep->rbufsz - cep->rwbuf_count, TCP_FLG_RST);
1857 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
1858 break;
1859 }
1860
1861 if (IS_PTR_DEFINED(cep->callback)) {
1862
1863#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
1864
1865 (*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)E_RLWAI);
1866
1867#else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1868
1869 ER error = E_RLWAI;
1870
1871 (*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&error);
1872
1873#endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1874
1875 }
1876 else
1877 error = E_OBJ;
1878 cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
1879 }
1880 else
1881
1882#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1883
1884 error = rel_wai(cep->rcv_tskid);
1885
1886 cep->rcv_tskid = TA_NULL;
1887 cep->rcv_tfn = TFN_TCP_UNDEF;
1888 }
1889
1890 /* 通信端点のロックを解除する。*/
1891 syscall(sig_sem(cep->semid_lock));
1892
1893 return error;
1894 }
1895
1896/*
1897 * tcp_can_cep -- ペンディングしている処理のキャンセル【標準機能】
1898 */
1899
1900ER
1901tcp_can_cep (ID cepid, FN fncd)
1902{
1903 T_TCP_CEP *cep;
1904 ER error = E_OK, snd_err, rcv_err;
1905
1906 /* API 機能コードをチェックする。*/
1907 if (!VALID_TFN_TCP_CAN(fncd))
1908 return E_PAR;
1909
1910 /* TCP 通信端点 ID をチェックする。*/
1911 if (!VAID_TCP_CEPID(cepid))
1912 return E_ID;
1913
1914 /* TCP 通信端点を得る。*/
1915 cep = GET_TCP_CEP(cepid);
1916
1917 /* TCP 通信端点をチェックする。*/
1918 if (!VALID_TCP_CEP(cep))
1919 return E_NOEXS;
1920
1921 if (fncd == TFN_TCP_ALL) { /* TFN_TCP_ALL の処理 */
1922 snd_err = tcp_can_snd(cep, fncd);
1923 rcv_err = tcp_can_rcv(cep, fncd);
1924
1925 /*
1926 * snd_err と rcv_err のどちらも EV_NOPND
1927 * なら、ペンディングしていないのでエラー
1928 */
1929 if (snd_err == EV_NOPND && rcv_err == EV_NOPND)
1930 error = E_OBJ;
1931 else {
1932 if (snd_err == EV_NOPND)
1933 snd_err = E_OK;
1934 if (rcv_err == EV_NOPND)
1935 rcv_err = E_OK;
1936
1937 if (snd_err != E_OK)
1938 error = snd_err;
1939 else if (rcv_err != E_OK)
1940 error = rcv_err;
1941 }
1942 }
1943
1944 else if (IS_TFN_TCP_RCV(fncd)) { /* 受信処理のキャンセル */
1945 if ((error = tcp_can_rcv(cep, fncd)) == EV_NOPND)
1946 error = E_OBJ;
1947 }
1948
1949 else { /* 送信処理のキャンセル */
1950 if ((error = tcp_can_snd(cep, fncd)) == EV_NOPND)
1951 error = E_OBJ;
1952 }
1953
1954 return error;
1955 }
1956
1957#endif /* of #ifdef __tcp_can_cep */
1958
1959/*
1960 * tcp_set_opt -- TCP 通信端点オプションの設定【拡張機能】
1961 *
1962 * 注意: 設定可能な TCP 通信端点オプションは無いため、E_PAR が返される。
1963 */
1964
1965#ifdef __tcp_set_opt
1966
1967#ifdef TCP_CFG_EXTENTIONS
1968
1969ER
1970tcp_set_opt (ID cepid, int_t optname, void *optval, int_t optlen)
1971{
1972 T_TCP_CEP *cep;
1973
1974 /* TCP 通信端点 ID をチェックする。*/
1975 if (!VAID_TCP_CEPID(cepid))
1976 return E_ID;
1977
1978 /* TCP 通信端点を得る。*/
1979 cep = GET_TCP_CEP(cepid);
1980
1981 /* TCP 通信端点をチェックする。*/
1982 if (!VALID_TCP_CEP(cep))
1983 return E_NOEXS;
1984
1985 return E_PAR;
1986 }
1987
1988#endif /* of #ifdef TCP_CFG_EXTENTIONS */
1989
1990#endif /* of #ifdef __tcp_set_opt */
1991
1992/*
1993 * tcp_get_opt -- TCP 通信端点オプションの設定【拡張機能】
1994 *
1995 * 注意: 設定可能な TCP 通信端点オプションは無いため、E_PAR が返される。
1996 */
1997
1998#ifdef __tcp_get_opt
1999
2000#ifdef TCP_CFG_EXTENTIONS
2001
2002ER
2003tcp_get_opt (ID cepid, int_t optname, void *optval, int_t optlen)
2004{
2005 T_TCP_CEP *cep;
2006
2007 /* TCP 通信端点 ID をチェックする。*/
2008 if (!VAID_TCP_CEPID(cepid))
2009 return E_ID;
2010
2011 /* TCP 通信端点を得る。*/
2012 cep = GET_TCP_CEP(cepid);
2013
2014 /* TCP 通信端点をチェックする。*/
2015 if (!VALID_TCP_CEP(cep))
2016 return E_NOEXS;
2017
2018 return E_PAR;
2019 }
2020
2021#endif /* of #ifdef TCP_CFG_EXTENTIONS */
2022
2023#endif /* of #ifdef __tcp_get_opt */
2024
2025#endif /* of #ifdef SUPPORT_TCP */
Note: See TracBrowser for help on using the repository browser.