source: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcpn_usrreq.c@ 331

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

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
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 * 上記著作権者
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$
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#ifdef TCP_CFG_EXTENTIONS
83
84#if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0)
85
86/*
87 * tcp_cre_rep -- TCP 受付口の生成【拡張機能】
88 */
89
90#ifdef __tcp_cre_rep
91
92ER
93TCP_CRE_REP (ID repid, T_TCPN_CREP *pk_crep)
94{
95 T_TCP_REP *rep;
96 ER error;
97
98 /* TCP 受付口 ID をチェックする。*/
99 if (!VALID_TCP_REPID(repid))
100 return E_ID;
101
102 /* pk_crep が NULL ならエラー */
103 if (pk_crep == NULL)
104 return E_PAR;
105
106#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
107
108 /*
109 * API が IPv6 で IPv4 射影アドレスが認められていないのにもかかわらず、
110 * IPv4 射影アドレスが指定されたらエラー
111 */
112 if (in6_is_addr_ipv4mapped(&pk_crep->myaddr.ipaddr))
113 return E_PAR;
114
115#endif /* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
116
117 /* TCP 受付口を得る。*/
118 rep = GET_TCP_REP(repid);
119
120 /* TCP 受付口が、動的生成用でなければエラー */
121 if (!DYNAMIC_TCP_REP(rep))
122 return E_ID;
123
124 /* 受付口をロックする。*/
125 syscall(wai_sem(rep->semid_lock));
126
127 /*
128 * TCP 受付口をチェックする。生成済みであればエラー
129 */
130 if (VALID_TCP_REP(rep))
131 error = E_OBJ;
132 else {
133
134 /* TCP 受付口生成情
135報をコピーする。*/
136 rep->repatr = pk_crep->repatr; /* 受付口属性 */
137 rep->myaddr.ipaddr = pk_crep->myaddr.ipaddr; /* 自分のアドレス */
138 rep->myaddr.portno = pk_crep->myaddr.portno; /* 自分のアドレス */
139
140 /* TCP 受付口を生成済みにする。*/
141 rep->flags |= TCP_REP_FLG_VALID;
142 error = E_OK;
143 }
144
145 /* 受付口のロックを解除する。*/
146 syscall(sig_sem(rep->semid_lock));
147
148 return error;
149 }
150
151#endif /* of #ifdef __tcp_cre_rep */
152
153#ifdef __tcp_del_rep
154
155/*
156 * tcp_find_cep_rep -- TCP 受付口をリンクしている TCP 通信端点を得る。
157 */
158
159static T_TCP_CEP*
160TCP_FIND_CEP_REP (T_TCP_REP* rep)
161{
162 T_TCP_CEP* cep;
163
164 for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; ) {
165
166#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
167 if (cep->rep4 == rep)
168#else
169 if (cep->rep == rep)
170#endif
171 return cep;
172 }
173
174 return NULL;
175 }
176
177/*
178 * tcp_del_rep_body -- TCP 受付口の削除【拡張機能】の本体
179 */
180
181static ER
182TCP_DEL_REP_BODY (ID repid)
183{
184 T_TCP_CEP *cep;
185 T_TCP_REP *rep;
186 ER error = E_OK;
187
188 /* TCP 受付口 ID のチェックは終了している。*/
189
190 /* TCP 受付口を得る。*/
191 rep = GET_TCP_REP(repid);
192
193 /* TCP 受付口が、動的生成用でなければエラー */
194 if (!DYNAMIC_TCP_REP(rep))
195 return E_ID;
196
197 /* 受付口をロックする。*/
198 syscall(wai_sem(rep->semid_lock));
199
200 /* TCP 受付口をチェックする。未生成の場合はエラー */
201 if (!VALID_TCP_REP(rep))
202 error = E_NOEXS;
203 else {
204 if ((cep = TCP_FIND_CEP_REP(rep)) != NULL) {
205 /*
206 * すでに受動オープンしているとき
207 *(tcp_acp_cep が呼ばれているとき)は、
208 * tcp_acp_cep を終了させる。
209 */
210
211 /* 通信端点をロックする。*/
212 syscall(wai_sem(cep->semid_lock));
213
214 /*
215 * 通信端点から受付口を解放し、
216 * イベントフラグをクローズに設定する。
217 */
218 cep->rep = NULL;
219
220#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
221 cep->rep4 = NULL;
222#endif
223
224 cep->fsm_state = TCP_FSM_CLOSED;
225 cep->error = E_DLT;
226 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
227
228#ifdef TCP_CFG_NON_BLOCKING
229
230 if (cep->rcv_nblk_tfn != TFN_TCP_UNDEF) {
231 if (IS_PTR_DEFINED(cep->callback)) {
232
233#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
234
235 (*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)E_DLT);
236
237#else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
238
239 ER error = E_DLT;
240
241 (*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&error);
242
243#endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
244
245 }
246 else
247 error = E_OBJ;
248 cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
249 }
250
251#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
252
253 cep->rcv_tskid = TA_NULL;
254 cep->rcv_tfn = TFN_TCP_UNDEF;
255
256 /* 通信端点のロックを解除する。*/
257 syscall(sig_sem(cep->semid_lock));
258
259 }
260 else
261 error = E_OK;
262
263 /* TCP 受付口を未生成にする。*/
264 rep->flags &= ~TCP_REP_FLG_VALID;
265 }
266
267 /* 受付口のロックを解除する。*/
268 syscall(sig_sem(rep->semid_lock));
269
270 return error;
271 }
272
273#endif /* of #ifdef __tcp_del_rep */
274
275#endif /* of #if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0) */
276
277#endif /* of #ifdef TCP_CFG_EXTENTIONS */
278
279#if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0)
280
281/*
282 * tcp_acp_cep -- 接続要求待
283ち (受動オープン)【標準機能】
284 */
285
286#ifdef __tcp_acp_cep
287
288ER
289TCP_ACP_CEP (ID cepid, ID repid, T_IPEP *p_dstaddr, TMO tmout)
290{
291 T_TCP_REP *rep;
292 T_TCP_CEP *cep;
293 ER error;
294 FLGPTN flag;
295
296#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
297
298 /*
299 * API (tcp6_acp_cep と tcp_acp_cep) と、
300 * TCP通信端点のプロトコルが矛盾していればエラー
301 */
302
303#if API_PROTO == API_PROTO_IPV6
304
305 if (GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4)
306 return E_ID;
307
308#endif /* of #if API_PROTO == API_PROTO_IPV6 */
309
310#if API_PROTO == API_PROTO_IPV4
311
312 if ((GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4) == 0)
313 return E_ID;
314
315#endif /* of #if API_PROTO == API_PROTO_IPV4 */
316
317#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
318
319 /* TCP 受付口をチェックする。*/
320 if (!VALID_TCP_REPID(repid))
321 return E_ID;
322
323#ifdef TCP_CFG_NON_BLOCKING
324
325 /* p_dstaddr が NULL ならエラー */
326 if (p_dstaddr == NULL)
327 return E_PAR;
328
329#else /* of #ifdef TCP_CFG_NON_BLOCKING */
330
331 /* p_dstaddr が NULL か、tmout が TMO_NBLK ならエラー */
332 if (p_dstaddr == NULL || tmout == TMO_NBLK)
333 return E_PAR;
334
335#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
336
337#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
338
339 /*
340 * API が IPv6 で IPv4 射影アドレスが認められていないのにもかかわらず、
341 * IPv4 射影アドレスが指定されたらエラー
342 */
343 if (in6_is_addr_ipv4mapped(&p_dstaddr->ipaddr))
344 return E_PAR;
345
346#endif /* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
347
348 /*
349 * CEP をロックし、API 機能コードとタスク識別子を記録する。
350 * すでに記録されていれば、ペンディング中なのでエラー
351 */
352 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_ACP_CEP)) != E_OK)
353 return error;
354
355 /* CEP の FSM がクローズ状æ…
356‹ã§ãªã‘ればエラー。*/
357 if (cep->fsm_state != TCP_FSM_CLOSED) {
358 error = E_OBJ;
359 goto err_ret;
360 }
361 syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_CLOSED)));
362
363 /* TCP 通信端点を初期化する。*/
364 tcp_init_cep(cep);
365
366 /* TCP 受付口を得る。*/
367
368 rep = GET_TCP_REP(repid);
369
370#ifdef TCP_CFG_EXTENTIONS
371
372 /* TCP 受付口をロックする。*/
373 syscall(wai_sem(rep->semid_lock));
374
375 /* TCP 受付口をチェックする。*/
376 if (!VALID_TCP_REP(rep)) {
377 syscall(sig_sem(rep->semid_lock));
378 error = E_NOEXS;
379 goto err_ret;
380 }
381
382#endif /* of #ifdef TCP_CFG_EXTENTIONS */
383
384 /* TCP 通信端点にTCP受付口を記録する。*/
385
386#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
387
388#if API_PROTO == API_PROTO_IPV6
389
390 cep->rep = rep;
391
392#else /* of #if API_PROTO == API_PROTO_IPV6 */
393
394 cep->rep4 = rep;
395
396#endif /*of #if API_PROTO == API_PROTO_IPV6 */
397
398#else /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
399
400 cep->rep = rep;
401
402#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
403
404#ifdef TCP_CFG_EXTENTIONS
405
406 /* TCP 受付口のロックを解除する。*/
407 syscall(sig_sem(rep->semid_lock));
408
409#endif /* of #ifdef TCP_CFG_EXTENTIONS */
410
411 /* TCP 受付口のアドレスをコピーする。*/
412
413#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
414
415 if (rep->myaddr.ipaddr == IPV4_ADDRANY)
416 memcpy(&cep->myaddr.ipaddr, &in6_addr_unspecified,
417 sizeof(in6_addr_unspecified));
418 else
419 in6_make_ipv4mapped(&cep->myaddr.ipaddr, rep->myaddr.ipaddr);
420 cep->myaddr.portno = rep->myaddr.portno;
421
422#else /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
423
424 cep->myaddr = rep->myaddr;
425
426#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
427
428#if API_PROTO == API_PROTO_IPV4
429
430 /* TCP 通信端点のネットワーク層プロトコルを設定する。*/
431 cep->flags |= TCP_CEP_FLG_IPV4;
432
433#endif /* of #if API_PROTO == API_PROTO_IPV4 */
434
435 /* 通信端点を設定する。*/
436 cep->fsm_state = TCP_FSM_LISTEN;
437
438#ifdef TCP_CFG_NON_BLOCKING
439
440 /* タイムアウトをチェックする。*/
441 if (tmout == TMO_NBLK) {
442 /* ノンブロッキングコール */
443
444#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
445
446#if API_PROTO == API_PROTO_IPV4
447
448 cep->p_dstaddr4 = p_dstaddr;
449 cep->p_dstaddr = NULL;
450
451#else /* of #if API_PROTO == API_PROTO_IPV4 */
452
453 cep->p_dstaddr4 = NULL;
454 cep->p_dstaddr = p_dstaddr;
455
456#endif /* of #if API_PROTO == API_PROTO_IPV4 */
457
458#else /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
459
460 cep->p_dstaddr = p_dstaddr;
461
462#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
463
464 cep->rcv_nblk_tfn = TFN_TCP_ACP_CEP;
465 return E_WBLK;
466 }
467 else {
468
469#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
470
471 /*
472 * FSM が ESTABLISHED になるまで待
473つ。
474 * FSM が CLOSED になった場合は、エラーが発生したことを意味している。
475 */
476 error = twai_flg(cep->est_flgid, (TCP_CEP_EVT_CLOSED |
477 TCP_CEP_EVT_ESTABLISHED), TWF_ORW, &flag, tmout);
478 if (error == E_OK) {
479 if (cep->error != E_OK)
480 error = cep->error;
481 else if (cep->fsm_state == TCP_FSM_CLOSED)
482 error = E_TMOUT;
483 }
484
485 syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_ESTABLISHED)));
486
487 if (error == E_OK) {
488 /* 相手のアドレスをコピーする。*/
489#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
490 p_dstaddr->ipaddr = ntohl(cep->dstaddr.ipaddr.s6_addr32[3]);
491 p_dstaddr->portno = cep->dstaddr.portno;
492#else
493 *p_dstaddr = cep->dstaddr;
494#endif
495 }
496 else {
497 /*
498 * 通信端点から受付口を解放し、
499 * イベントフラグをクローズに設定する。
500 */
501 cep->rep = NULL;
502
503#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
504 cep->rep4 = NULL;
505#endif
506
507 cep->fsm_state = TCP_FSM_CLOSED;
508 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
509 }
510
511#ifdef TCP_CFG_NON_BLOCKING
512
513 }
514
515#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
516
517err_ret:
518 cep->rcv_tskid = TA_NULL;
519 cep->rcv_tfn = TFN_TCP_UNDEF;
520 return error;
521 }
522
523#endif /* of #ifdef __tcp_acp_cep */
524
525#endif /* of #if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0) */
526
527/*
528 * tcp_con_cep -- 接続要求 (能動オープン)【標準機能】
529 */
530
531#ifdef __tcp_con_cep
532
533ER
534TCP_CON_CEP (ID cepid, T_IPEP *p_myaddr, T_IPEP *p_dstaddr, TMO tmout)
535{
536 T_TCP_CEP *cep;
537 ER error;
538 FLGPTN flag;
539
540#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
541
542 /*
543 * API (tcp6_acp_cep と tcp_acp_cep) と、
544 * TCP通信端点のプロトコルが矛盾していればエラー
545 */
546
547#if API_PROTO == API_PROTO_IPV6
548
549 if (GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4)
550 return E_ID;
551
552#endif /* of #if API_PROTO == API_PROTO_IPV6 */
553
554#if API_PROTO == API_PROTO_IPV4
555
556 if ((GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4) == 0)
557 return E_ID;
558
559#endif /* of #if API_PROTO == API_PROTO_IPV4 */
560
561#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
562
563 /*
564 * あてå…
565ˆãŒãƒžãƒ«ãƒã‚­ãƒ£ã‚¹ãƒˆã‚¢ãƒ‰ãƒ¬ã‚¹ãªã‚‰ã‚¨ãƒ©ãƒ¼
566 */
567
568#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
569
570 if (IN4_IS_ADDR_MULTICAST(p_dstaddr->ipaddr))
571 return E_PAR;
572
573#else /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
574
575 if (IN_IS_ADDR_MULTICAST(&p_dstaddr->ipaddr))
576 return E_PAR;
577
578#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
579
580#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
581
582 /*
583 * API が IPv6 で IPv4 射影アドレスが認められていないのにもかかわらず、
584 * IPv4 射影アドレスが指定されたらエラー
585 */
586 if (in6_is_addr_ipv4mapped(&p_dstaddr->ipaddr))
587 return E_PAR;
588
589#endif /* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
590
591#ifdef TCP_CFG_NON_BLOCKING
592
593 /*
594 * p_dstaddr または p_myaddr が NULL ならエラー
595 */
596 if (p_myaddr == NULL || p_dstaddr == NULL)
597 return E_PAR;
598
599#else /* of #ifdef TCP_CFG_NON_BLOCKING */
600
601 /*
602 * p_dstaddr または p_myaddr が NULL 、
603 * tmout が TMO_NBLK ならエラー
604 */
605 if (p_myaddr == NULL || p_dstaddr == NULL || tmout == TMO_NBLK)
606 return E_PAR;
607
608#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
609
610 /*
611 * CEP をロックし、API 機能コードとタスク識別子を記録する。
612 * すでに記録されていれば、ペンディング中なのでエラー
613 */
614 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_CON_CEP)) != E_OK)
615 return error;
616
617 /* CEP の FSM がクローズ状æ…
618‹ã§ãªã‘ればエラー。*/
619 if (cep->fsm_state != TCP_FSM_CLOSED) {
620 error = E_OBJ;
621 goto err_ret;
622 }
623 syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_CLOSED)));
624
625 /* シーケンス番号を初期化する。*/
626 if (tcp_iss == 0)
627 tcp_init_iss();
628
629 /* 通信端点を初期化する。*/
630 tcp_init_cep(cep);
631
632 /*
633 * IP アドレスを設定する。
634 * p_myaddr が NADR (-1) ではなく、自 IP アドレスが ANY でなければ、
635 * 指定された IP アドレスを割り当てる。
636 */
637
638#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
639
640 if (p_myaddr != NADR && !IN4_IS_ADDR_ANY(&p_myaddr->ipaddr))
641 in6_make_ipv4mapped(&cep->myaddr.ipaddr, p_myaddr->ipaddr);
642 else
643 in6_make_ipv4mapped(&cep->myaddr.ipaddr, IF_GET_IFNET()->in4_ifaddr.addr);
644
645 in6_make_ipv4mapped(&cep->dstaddr.ipaddr, p_dstaddr->ipaddr);
646 cep->dstaddr.portno = p_dstaddr->portno;
647
648#else /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
649
650 if (p_myaddr != NADR && !IN_IS_ADDR_ANY(&p_myaddr->ipaddr))
651 cep->myaddr.ipaddr = p_myaddr->ipaddr;
652 else {
653 if (IN_ADDRWITHIFP(IF_GET_IFNET(), &cep->myaddr.ipaddr, &p_dstaddr->ipaddr) == NULL) {
654 error = E_PAR;
655 goto err_ret;
656 }
657 }
658
659 cep->dstaddr = *p_dstaddr;
660
661#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
662
663#if API_PROTO == API_PROTO_IPV4
664
665 /* TCP 通信端点のネットワーク層プロトコルを設定する。*/
666 cep->flags |= TCP_CEP_FLG_IPV4;
667
668#endif /* of #if API_PROTO == API_PROTO_IPV4 */
669
670 /* 通信端点を設定する。*/
671 //NET_DEBUG_TCP5("tcp_con_cep3[c=%d,d=%lI.%d,s=%lI.%d]\n",
672 cep->fsm_state = TCP_FSM_SYN_SENT;
673 cep->iss = tcp_iss;
674 cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_INIT;
675 tcp_iss += TCP_ISS_INCR() / 2;
676 init_send_seq(cep);
677
678#ifdef TCP_CFG_NON_BLOCKING
679
680 /* タイムアウトをチェックする。*/
681 if (tmout == TMO_NBLK) {
682 /* ノンブロッキングコール */
683
684#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
685
686#if API_PROTO == API_PROTO_IPV4
687
688 cep->p_dstaddr4 = p_dstaddr;
689 cep->p_myaddr4 = p_myaddr;
690 cep->p_dstaddr = NULL;
691 cep->p_myaddr = NULL;
692
693#else /* of #if API_PROTO == API_PROTO_IPV4 */
694
695 cep->p_dstaddr4 = NULL;
696 cep->p_myaddr4 = NULL;
697 cep->p_dstaddr = p_dstaddr;
698 cep->p_myaddr = p_myaddr;
699
700#endif /* of #if API_PROTO == API_PROTO_IPV4 */
701
702#else /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
703
704 cep->p_dstaddr = p_dstaddr;
705 cep->p_myaddr = p_myaddr;
706
707#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
708
709 cep->snd_nblk_tfn = TFN_TCP_CON_CEP;
710
711 /* コネクションの開設をポストする。*/
712 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
713 sig_sem(SEM_TCP_POST_OUTPUT);
714 return E_WBLK;
715 }
716 else {
717
718#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
719
720 /*
721 * p_myaddr が NADR (-1) か、
722 * 自ポート番号が TCP_PORTANY なら、自動で割り当てる。
723 */
724 if (p_myaddr == NADR || p_myaddr->portno == TCP_PORTANY)
725 tcp_alloc_auto_port(cep);
726 else if ((error = tcp_alloc_port(cep, p_myaddr->portno)) != E_OK)
727 goto err_ret;
728
729 /* コネクションの開設をポストする。*/
730 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
731 sig_sem(SEM_TCP_POST_OUTPUT);
732
733 /*
734 * イベントが ESTABLISHED になるまで待
735つ。
736 * イベントが CLOSED になった場合は、何らかのエラーが発生したか、
737 * 接続要求が拒否されたことを意味している。
738 */
739 error = twai_flg(cep->est_flgid, (TCP_CEP_EVT_CLOSED |
740 TCP_CEP_EVT_ESTABLISHED), TWF_ORW, &flag, tmout);
741 if (error == E_OK) {
742 if (cep->error != E_OK)
743 error = cep->error;
744 else if (cep->fsm_state == TCP_FSM_CLOSED)
745 error = E_CLS;
746 }
747
748 syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_ESTABLISHED)));
749
750 if (error != E_OK) {
751 /*
752 * 通信端点から受付口を解放し、
753 * イベントフラグをクローズに設定する。
754 */
755 cep->rep = NULL;
756
757#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
758 cep->rep4 = NULL;
759#endif
760
761 cep->fsm_state = TCP_FSM_CLOSED;
762 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
763 }
764
765#ifdef TCP_CFG_NON_BLOCKING
766
767 }
768
769#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
770
771err_ret:
772 cep->snd_tskid = TA_NULL;
773 cep->snd_tfn = TFN_TCP_UNDEF;
774 return error;
775 }
776
777#endif /* of #ifdef __tcp_con_cep */
Note: See TracBrowser for help on using the repository browser.