source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/tinet/netinet/tcpn_usrreq.c@ 387

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

ファイルディスクリプタ処理を更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 21.6 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2017 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 * Copyright (c) 1982, 1986, 1988, 1993
36 * The Regents of the University of California. All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by the University of
49 * California, Berkeley and its contributors.
50 * 4. Neither the name of the University nor the names of its contributors
51 * may be used to endorse or promote products derived from this software
52 * without specific prior written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * SUCH DAMAGE.
65 *
66 * From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94
67 * $FreeBSD: src/sys/netinet/tcp_usrreq.c,v 1.40.2.3 1999/08/29 16:29:57 peter Exp $
68 */
69
70#ifdef TCP_CFG_EXTENTIONS
71
72#if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0)
73
74/*
75 * tcp_cre_rep -- TCP 受付口の生成【拡張機能】
76 */
77
78#ifdef __tcp_cre_rep
79
80ER
81TCP_CRE_REP (ID repid, T_TCPN_CREP *pk_crep)
82{
83 T_TCP_REP *rep;
84 ER error;
85
86 /* TCP 受付口 ID をチェックする。*/
87 if (!VALID_TCP_REPID(repid))
88 return E_ID;
89
90 /* pk_crep が NULL ならエラー */
91 if (pk_crep == NULL)
92 return E_PAR;
93
94#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
95
96 /*
97 * API が IPv6 で IPv4 射影アドレスが認められていないのにもかかわらず、
98 * IPv4 射影アドレスが指定されたらエラー
99 */
100 if (in6_is_addr_ipv4mapped(&pk_crep->myaddr.ipaddr))
101 return E_PAR;
102
103#endif /* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
104
105 /* TCP 受付口を得る。*/
106 rep = GET_TCP_REP(repid);
107
108 /* TCP 受付口が、動的生成用でなければエラー */
109 if (!DYNAMIC_TCP_REP(rep))
110 return E_ID;
111
112 /* 受付口をロックする。*/
113 syscall(wai_sem(rep->semid_lock));
114
115 /*
116 * TCP 受付口をチェックする。生成済みであればエラー
117 */
118 if (VALID_TCP_REP(rep))
119 error = E_OBJ;
120 else {
121
122 /* TCP 受付口生成情報をコピーする。*/
123 rep->repatr = pk_crep->repatr; /* 受付口属性 */
124 rep->myaddr.ipaddr = pk_crep->myaddr.ipaddr; /* 自分のアドレス */
125 rep->myaddr.portno = pk_crep->myaddr.portno; /* 自分のアドレス */
126
127 /* TCP 受付口を生成済みにする。*/
128 rep->flags |= TCP_REP_FLG_VALID;
129 error = E_OK;
130 }
131
132 /* 受付口のロックを解除する。*/
133 syscall(sig_sem(rep->semid_lock));
134
135 return error;
136 }
137
138#endif /* of #ifdef __tcp_cre_rep */
139
140#ifdef __tcp_del_rep
141
142/*
143 * tcp_find_cep_rep -- TCP 受付口をリンクしている TCP 通信端点を得る。
144 */
145
146static T_TCP_CEP*
147TCP_FIND_CEP_REP (T_TCP_REP* rep)
148{
149 T_TCP_CEP* cep;
150
151 for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; ) {
152
153#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
154 if (cep->rep4 == rep)
155#else
156 if (cep->rep == rep)
157#endif
158 return cep;
159 }
160
161 return NULL;
162 }
163
164/*
165 * tcp_del_rep_body -- TCP 受付口の削除【拡張機能】の本体
166 */
167
168static ER
169TCP_DEL_REP_BODY (ID repid)
170{
171 T_TCP_CEP *cep;
172 T_TCP_REP *rep;
173 ER error = E_OK;
174
175 /* TCP 受付口 ID のチェックは終了している。*/
176
177 /* TCP 受付口を得る。*/
178 rep = GET_TCP_REP(repid);
179
180 /* TCP 受付口が、動的生成用でなければエラー */
181 if (!DYNAMIC_TCP_REP(rep))
182 return E_ID;
183
184 /* 受付口をロックする。*/
185 syscall(wai_sem(rep->semid_lock));
186
187 /* TCP 受付口をチェックする。未生成の場合はエラー */
188 if (!VALID_TCP_REP(rep))
189 error = E_NOEXS;
190 else {
191 if ((cep = TCP_FIND_CEP_REP(rep)) != NULL) {
192 /*
193 * すでに受動オープンしているとき
194 *(tcp_acp_cep が呼ばれているとき)は、
195 * tcp_acp_cep を終了させる。
196 */
197
198 /* 通信端点をロックする。*/
199 syscall(wai_sem(cep->semid_lock));
200
201 /*
202 * 通信端点から受付口を解放し、
203 * イベントフラグをクローズに設定する。
204 */
205 cep->rep = NULL;
206
207#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
208 cep->rep4 = NULL;
209#endif
210
211 cep->fsm_state = TCP_FSM_CLOSED;
212 cep->error = E_DLT;
213 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
214
215#ifdef TCP_CFG_NON_BLOCKING
216
217 if (cep->rcv_nblk_tfn != TFN_TCP_UNDEF) {
218 if (IS_PTR_DEFINED(cep->callback)) {
219
220#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
221
222 (*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)E_DLT);
223
224#else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
225
226 ER error = E_DLT;
227
228 (*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&error);
229
230#endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
231
232 }
233 else
234 error = E_OBJ;
235 cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
236 }
237
238#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
239
240 cep->rcv_tskid = TA_NULL;
241 cep->rcv_tfn = TFN_TCP_UNDEF;
242
243 /* 通信端点のロックを解除する。*/
244 syscall(sig_sem(cep->semid_lock));
245
246 }
247 else
248 error = E_OK;
249
250 /* TCP 受付口を未生成にする。*/
251 rep->flags &= ~TCP_REP_FLG_VALID;
252 }
253
254 /* 受付口のロックを解除する。*/
255 syscall(sig_sem(rep->semid_lock));
256
257 return error;
258 }
259
260#endif /* of #ifdef __tcp_del_rep */
261
262#endif /* of #if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0) */
263
264#endif /* of #ifdef TCP_CFG_EXTENTIONS */
265
266#if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0)
267
268/*
269 * tcp_acp_cep -- 接続要求待ち (受動オープン)【標準機能】
270 */
271
272#ifdef __tcp_acp_cep
273
274ER
275TCP_ACP_CEP (ID cepid, ID repid, T_IPEP *p_dstaddr, TMO tmout)
276{
277 T_TCP_REP *rep;
278 T_TCP_CEP *cep;
279 ER error;
280 FLGPTN flag;
281
282#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
283
284 /*
285 * API (tcp6_acp_cep と tcp_acp_cep) と、
286 * TCP通信端点のプロトコルが矛盾していればエラー
287 */
288
289#if API_PROTO == API_PROTO_IPV6
290
291 if (GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4)
292 return E_ID;
293
294#endif /* of #if API_PROTO == API_PROTO_IPV6 */
295
296#if API_PROTO == API_PROTO_IPV4
297
298 if ((GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4) == 0)
299 return E_ID;
300
301#endif /* of #if API_PROTO == API_PROTO_IPV4 */
302
303#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
304
305 /* TCP 受付口をチェックする。*/
306 if (!VALID_TCP_REPID(repid))
307 return E_ID;
308
309#ifdef TCP_CFG_NON_BLOCKING
310
311 /* p_dstaddr が NULL ならエラー */
312 if (p_dstaddr == NULL)
313 return E_PAR;
314
315#else /* of #ifdef TCP_CFG_NON_BLOCKING */
316
317 /* p_dstaddr が NULL か、tmout が TMO_NBLK ならエラー */
318 if (p_dstaddr == NULL || tmout == TMO_NBLK)
319 return E_PAR;
320
321#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
322
323#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
324
325 /*
326 * API が IPv6 で IPv4 射影アドレスが認められていないのにもかかわらず、
327 * IPv4 射影アドレスが指定されたらエラー
328 */
329 if (in6_is_addr_ipv4mapped(&p_dstaddr->ipaddr))
330 return E_PAR;
331
332#endif /* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
333
334 /*
335 * CEP をロックし、API 機能コードとタスク識別子を記録する。
336 * すでに記録されていれば、ペンディング中なのでエラー
337 */
338 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_ACP_CEP)) != E_OK)
339 return error;
340
341 /* CEP の FSM がクローズ状態でなければエラー。*/
342 if (cep->fsm_state != TCP_FSM_CLOSED) {
343 error = E_OBJ;
344 goto err_ret;
345 }
346 syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_CLOSED)));
347
348 /* TCP 通信端点を初期化する。*/
349 tcp_init_cep(cep);
350
351 /* TCP 受付口を得る。*/
352
353 rep = GET_TCP_REP(repid);
354
355#ifdef TCP_CFG_EXTENTIONS
356
357 /* TCP 受付口をロックする。*/
358 syscall(wai_sem(rep->semid_lock));
359
360 /* TCP 受付口をチェックする。*/
361 if (!VALID_TCP_REP(rep)) {
362 syscall(sig_sem(rep->semid_lock));
363 error = E_NOEXS;
364 goto err_ret;
365 }
366
367#endif /* of #ifdef TCP_CFG_EXTENTIONS */
368
369 /* TCP 通信端点にTCP受付口を記録する。*/
370
371#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
372
373#if API_PROTO == API_PROTO_IPV6
374
375 cep->rep = rep;
376
377#else /* of #if API_PROTO == API_PROTO_IPV6 */
378
379 cep->rep4 = rep;
380
381#endif /*of #if API_PROTO == API_PROTO_IPV6 */
382
383#else /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
384
385 cep->rep = rep;
386
387#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
388
389#ifdef TCP_CFG_EXTENTIONS
390
391 /* TCP 受付口のロックを解除する。*/
392 syscall(sig_sem(rep->semid_lock));
393
394#endif /* of #ifdef TCP_CFG_EXTENTIONS */
395
396 /* TCP 受付口のアドレスをコピーする。*/
397
398#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
399
400 if (rep->myaddr.ipaddr == IPV4_ADDRANY)
401 memcpy(&cep->myaddr.ipaddr, &in6_addr_unspecified,
402 sizeof(in6_addr_unspecified));
403 else
404 in6_make_ipv4mapped(&cep->myaddr.ipaddr, rep->myaddr.ipaddr);
405 cep->myaddr.portno = rep->myaddr.portno;
406
407#else /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
408
409 cep->myaddr = rep->myaddr;
410
411#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
412
413#if API_PROTO == API_PROTO_IPV4
414
415 /* TCP 通信端点のネットワーク層プロトコルを設定する。*/
416 cep->flags |= TCP_CEP_FLG_IPV4;
417
418#endif /* of #if API_PROTO == API_PROTO_IPV4 */
419
420 /* 通信端点を設定する。*/
421 cep->fsm_state = TCP_FSM_LISTEN;
422
423#ifdef TCP_CFG_NON_BLOCKING
424
425 /* タイムアウトをチェックする。*/
426 if (tmout == TMO_NBLK) {
427 /* ノンブロッキングコール */
428
429#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
430
431#if API_PROTO == API_PROTO_IPV4
432
433 cep->p_dstaddr4 = p_dstaddr;
434 cep->p_dstaddr = NULL;
435
436#else /* of #if API_PROTO == API_PROTO_IPV4 */
437
438 cep->p_dstaddr4 = NULL;
439 cep->p_dstaddr = p_dstaddr;
440
441#endif /* of #if API_PROTO == API_PROTO_IPV4 */
442
443#else /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
444
445 cep->p_dstaddr = p_dstaddr;
446
447#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
448
449 cep->rcv_nblk_tfn = TFN_TCP_ACP_CEP;
450 return E_WBLK;
451 }
452 else {
453
454#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
455
456 /*
457 * FSM が ESTABLISHED になるまで待つ。
458 * FSM が CLOSED になった場合は、エラーが発生したことを意味している。
459 */
460 error = twai_flg(cep->est_flgid, (TCP_CEP_EVT_CLOSED |
461 TCP_CEP_EVT_ESTABLISHED), TWF_ORW, &flag, tmout);
462 if (error == E_OK) {
463 if (cep->error != E_OK)
464 error = cep->error;
465 else if (cep->fsm_state == TCP_FSM_CLOSED)
466 error = E_TMOUT;
467 }
468
469 syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_ESTABLISHED)));
470
471 if (error == E_OK) {
472 /* 相手のアドレスをコピーする。*/
473#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
474 p_dstaddr->ipaddr = ntohl(cep->dstaddr.ipaddr.s6_addr32[3]);
475 p_dstaddr->portno = cep->dstaddr.portno;
476#else
477 *p_dstaddr = cep->dstaddr;
478#endif
479 }
480 else {
481 /*
482 * 通信端点から受付口を解放し、
483 * イベントフラグをクローズに設定する。
484 */
485 cep->rep = NULL;
486
487#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
488 cep->rep4 = NULL;
489#endif
490
491 cep->fsm_state = TCP_FSM_CLOSED;
492 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
493 }
494
495#ifdef TCP_CFG_NON_BLOCKING
496
497 }
498
499#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
500
501err_ret:
502 cep->rcv_tskid = TA_NULL;
503 cep->rcv_tfn = TFN_TCP_UNDEF;
504 return error;
505 }
506
507#endif /* of #ifdef __tcp_acp_cep */
508
509#endif /* of #if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0) */
510
511/*
512 * tcp_con_cep -- 接続要求 (能動オープン)【標準機能】
513 */
514
515#ifdef __tcp_con_cep
516
517ER
518TCP_CON_CEP (ID cepid, T_IPEP *p_myaddr, T_IPEP *p_dstaddr, TMO tmout)
519{
520 T_TCP_CEP *cep;
521 ER error;
522 FLGPTN flag;
523
524#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
525
526 /*
527 * API (tcp6_acp_cep と tcp_acp_cep) と、
528 * TCP通信端点のプロトコルが矛盾していればエラー
529 */
530
531#if API_PROTO == API_PROTO_IPV6
532
533 if (GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4)
534 return E_ID;
535
536#endif /* of #if API_PROTO == API_PROTO_IPV6 */
537
538#if API_PROTO == API_PROTO_IPV4
539
540 if ((GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4) == 0)
541 return E_ID;
542
543#endif /* of #if API_PROTO == API_PROTO_IPV4 */
544
545#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
546
547 /*
548 * あて先がマルチキャストアドレスならエラー
549 */
550
551#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
552
553 if (IN4_IS_ADDR_MULTICAST(p_dstaddr->ipaddr))
554 return E_PAR;
555
556#else /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
557
558 if (IN_IS_ADDR_MULTICAST(&p_dstaddr->ipaddr))
559 return E_PAR;
560
561#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
562
563#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
564
565 /*
566 * API が IPv6 で IPv4 射影アドレスが認められていないのにもかかわらず、
567 * IPv4 射影アドレスが指定されたらエラー
568 */
569 if (in6_is_addr_ipv4mapped(&p_dstaddr->ipaddr))
570 return E_PAR;
571
572#endif /* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
573
574#ifdef TCP_CFG_NON_BLOCKING
575
576 /*
577 * p_dstaddr または p_myaddr が NULL ならエラー
578 */
579 if (p_myaddr == NULL || p_dstaddr == NULL)
580 return E_PAR;
581
582#else /* of #ifdef TCP_CFG_NON_BLOCKING */
583
584 /*
585 * p_dstaddr または p_myaddr が NULL 、
586 * tmout が TMO_NBLK ならエラー
587 */
588 if (p_myaddr == NULL || p_dstaddr == NULL || tmout == TMO_NBLK)
589 return E_PAR;
590
591#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
592
593 /*
594 * CEP をロックし、API 機能コードとタスク識別子を記録する。
595 * すでに記録されていれば、ペンディング中なのでエラー
596 */
597 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_CON_CEP)) != E_OK)
598 return error;
599
600 /* CEP の FSM がクローズ状態でなければエラー。*/
601 if (cep->fsm_state != TCP_FSM_CLOSED) {
602 error = E_OBJ;
603 goto err_ret;
604 }
605 syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_CLOSED)));
606
607 /* シーケンス番号を初期化する。*/
608 if (tcp_iss == 0)
609 tcp_init_iss();
610
611 /* 通信端点を初期化する。*/
612 tcp_init_cep(cep);
613
614 /*
615 * IP アドレスを設定する。
616 * p_myaddr が NADR (-1) ではなく、自 IP アドレスが ANY でなければ、
617 * 指定された IP アドレスを割り当てる。
618 */
619
620#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
621
622 if (p_myaddr != NADR && !IN4_IS_ADDR_ANY(&p_myaddr->ipaddr))
623 in6_make_ipv4mapped(&cep->myaddr.ipaddr, p_myaddr->ipaddr);
624 else
625 in6_make_ipv4mapped(&cep->myaddr.ipaddr, IF_GET_IFNET()->in4_ifaddr.addr);
626
627 in6_make_ipv4mapped(&cep->dstaddr.ipaddr, p_dstaddr->ipaddr);
628 cep->dstaddr.portno = p_dstaddr->portno;
629
630#else /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
631
632 if (p_myaddr != NADR && !IN_IS_ADDR_ANY(&p_myaddr->ipaddr))
633 cep->myaddr.ipaddr = p_myaddr->ipaddr;
634 else {
635 if (IN_ADDRWITHIFP(IF_GET_IFNET(), &cep->myaddr.ipaddr, &p_dstaddr->ipaddr) == NULL) {
636 error = E_PAR;
637 goto err_ret;
638 }
639 }
640
641 cep->dstaddr = *p_dstaddr;
642
643#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
644
645#if API_PROTO == API_PROTO_IPV4
646
647 /* TCP 通信端点のネットワーク層プロトコルを設定する。*/
648 cep->flags |= TCP_CEP_FLG_IPV4;
649
650#endif /* of #if API_PROTO == API_PROTO_IPV4 */
651
652 /* 通信端点を設定する。*/
653 //NET_DEBUG_TCP5("tcp_con_cep3[c=%d,d=%lI.%d,s=%lI.%d]\n",
654 cep->fsm_state = TCP_FSM_SYN_SENT;
655 cep->iss = tcp_iss;
656 cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_INIT;
657 tcp_iss += TCP_ISS_INCR() / 2;
658 init_send_seq(cep);
659
660#ifdef TCP_CFG_NON_BLOCKING
661
662 /* タイムアウトをチェックする。*/
663 if (tmout == TMO_NBLK) {
664 /* ノンブロッキングコール */
665
666#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
667
668#if API_PROTO == API_PROTO_IPV4
669
670 cep->p_dstaddr4 = p_dstaddr;
671 cep->p_myaddr4 = p_myaddr;
672 cep->p_dstaddr = NULL;
673 cep->p_myaddr = NADR;
674
675#else /* of #if API_PROTO == API_PROTO_IPV4 */
676
677 cep->p_dstaddr4 = NULL;
678 cep->p_myaddr4 = NADR;
679 cep->p_dstaddr = p_dstaddr;
680 cep->p_myaddr = p_myaddr;
681
682#endif /* of #if API_PROTO == API_PROTO_IPV4 */
683
684#else /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
685
686 cep->p_dstaddr = p_dstaddr;
687 cep->p_myaddr = p_myaddr;
688
689#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
690
691 cep->snd_nblk_tfn = TFN_TCP_CON_CEP;
692
693 /* コネクションの開設をポストする。*/
694 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
695 sig_sem(SEM_TCP_POST_OUTPUT);
696 return E_WBLK;
697 }
698 else {
699
700#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
701
702 /*
703 * p_myaddr が NADR (-1) か、
704 * 自ポート番号が TCP_PORTANY なら、自動で割り当てる。
705 */
706 if (p_myaddr == NADR || p_myaddr->portno == TCP_PORTANY)
707 tcp_alloc_auto_port(cep);
708 else if ((error = tcp_alloc_port(cep, p_myaddr->portno)) != E_OK)
709 goto err_ret;
710
711 /* コネクションの開設をポストする。*/
712 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
713 sig_sem(SEM_TCP_POST_OUTPUT);
714
715 /*
716 * イベントが ESTABLISHED になるまで待つ。
717 * イベントが CLOSED になった場合は、何らかのエラーが発生したか、
718 * 接続要求が拒否されたことを意味している。
719 */
720 error = twai_flg(cep->est_flgid, (TCP_CEP_EVT_CLOSED |
721 TCP_CEP_EVT_ESTABLISHED), TWF_ORW, &flag, tmout);
722 if (error == E_OK) {
723 if (cep->error != E_OK)
724 error = cep->error;
725 else if (cep->fsm_state == TCP_FSM_CLOSED)
726 error = E_CLS;
727 }
728
729 syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_ESTABLISHED)));
730
731 if (error != E_OK) {
732 /*
733 * 通信端点から受付口を解放し、
734 * イベントフラグをクローズに設定する。
735 */
736 cep->rep = NULL;
737
738#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
739 cep->rep4 = NULL;
740#endif
741
742 cep->fsm_state = TCP_FSM_CLOSED;
743 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
744 }
745
746#ifdef TCP_CFG_NON_BLOCKING
747
748 }
749
750#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
751
752err_ret:
753 cep->snd_tskid = TA_NULL;
754 cep->snd_tfn = TFN_TCP_UNDEF;
755 return error;
756 }
757
758#endif /* of #ifdef __tcp_con_cep */
Note: See TracBrowser for help on using the repository browser.