- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_usrreq_nblk.c
r321 r331 2 2 * TINET (UDP/IP Protocol Stack) 3 3 * 4 * Copyright (C) 2001-20 09by Dep. of Computer Science and Engineering4 * Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering 5 5 * Tomakomai National College of Technology, JAPAN 6 6 * … … 75 75 #include <sil.h> 76 76 #include "kernel_cfg.h" 77 #include "tinet_cfg.h" 77 78 78 79 #endif /* of #ifdef TARGET_KERNEL_ASP */ … … 83 84 #include <t_services.h> 84 85 #include "kernel_id.h" 86 #include "tinet_id.h" 85 87 86 88 #endif /* of #ifdef TARGET_KERNEL_JSP */ … … 94 96 #include <net/ethernet.h> 95 97 #include <net/net.h> 98 #include <net/net_endian.h> 96 99 #include <net/net_buf.h> 97 100 #include <net/net_count.h> … … 99 102 100 103 #include <netinet/in.h> 101 #include <netinet6/in6.h>102 104 #include <netinet/in_var.h> 103 105 #include <netinet/in_itron.h> … … 105 107 #include <netinet/ip_var.h> 106 108 #include <netinet/ip_icmp.h> 107 #include <netinet6/in6_var.h>108 #include <netinet/ip6.h>109 #include <netinet6/ip6_var.h>110 #include <netinet6/nd6.h>111 #include <netinet/icmp6.h>112 109 #include <netinet/udp.h> 113 110 #include <netinet/udp_var.h> 114 111 115 112 #ifdef SUPPORT_UDP 116 117 /*118 * IPv4 と IPv6 の切り替えマクロ119 */120 121 #if defined(SUPPORT_INET4)122 123 #define UDP_SND_DAT udp_snd_dat124 #define UDP_RCV_DAT udp_rcv_dat125 126 #endif /* of #if defined(SUPPORT_INET4) */127 128 #if defined(SUPPORT_INET6)129 130 #define UDP_SND_DAT udp6_snd_dat131 #define UDP_RCV_DAT udp6_rcv_dat132 133 #endif /* of #if defined(SUPPORT_INET6) */134 113 135 114 /* … … 140 119 #ifndef UDP_CFG_LIBRARY 141 120 142 #define __udp_can_snd 143 #define __udp_can_rcv 144 #define __udp_snd_dat 145 #define __udp_rcv_dat 121 #define __udp_can_snd_nblk 122 #define __udp_can_rcv_nblk 123 #define __udp_snd_dat_nblk 124 #define __udp_rcv_dat_nblk 146 125 147 126 #endif /* of #ifndef UDP_CFG_LIBRARY */ … … 149 128 #ifdef UDP_CFG_NON_BLOCKING 150 129 151 #ifdef __udp_can_snd152 153 130 /* 154 * udp_can_snd -- ペンディングしている送信のキャンセル131 * IPv6 と IPv4 で引数が異なる関数のコンパイル 155 132 */ 156 133 157 ER 158 udp_can_snd (T_UDP_CEP *cep, ER error) 159 { 160 if (cep->snd_p_dstaddr != NULL) { /* ノンブロッキングコールでペンディング中 */ 161 if (IS_PTR_DEFINED(cep->callback)) 134 #undef IN_COPY_TO_HOST 162 135 163 #if def TCP_CFG_NON_BLOCKING_COMPAT14136 #if defined(SUPPORT_INET6) && TNUM_UDP6_CEPID > 0 164 137 165 (*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)error); 138 #define UDP_SND_DAT udp6_snd_dat 139 #define UDP_RCV_DAT udp6_rcv_dat 140 #define UDP_CAN_SND udp6_can_snd 141 #define UDP_CAN_RCV udp6_can_rcv 142 #define UDP_ALLOC_AUTO_PORT udp6_alloc_auto_port 143 #define UDP_SEND_DATA udp6_send_data 144 #define VALID_UDP_CEPID VALID_UDP6_CEPID 145 #define GET_UDP_CEP GET_UDP6_CEP 146 #define GET_UDP_CEPID GET_UDP6_CEPID 147 #define T_UDP_CEP T_UDP6_CEP 148 #define T_IPEP T_IPV6EP 149 #define API_PROTO API_PROTO_IPV6 166 150 167 #else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */ 151 #if defined(SUPPORT_INET4) 152 #define IN_COPY_TO_HOST inn_copy_to_host 153 #else 154 #define IN_COPY_TO_HOST IN6_COPY_TO_HOST 155 #endif 168 156 169 (*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)&error); 157 #include <netinet/udpn_usrreq_nblk.c> 170 158 171 #endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */ 159 #undef UDP_SND_DAT 160 #undef UDP_RCV_DAT 161 #undef UDP_CAN_SND 162 #undef UDP_CAN_RCV 163 #undef UDP_ALLOC_AUTO_PORT 164 #undef UDP_SEND_DATA 165 #undef VALID_UDP_CEPID 166 #undef GET_UDP_CEP 167 #undef GET_UDP_CEPID 168 #undef T_UDP_CEP 169 #undef T_IPEP 170 #undef API_PROTO 171 #undef IN_COPY_TO_HOST 172 172 173 else 174 error = E_OBJ; 175 cep->snd_p_dstaddr = NULL; 176 } 177 else if (cep->snd_tskid != TA_NULL) { /* 非ノンブロッキングコールでペンディング中 */ 173 #endif /* of #if defined(SUPPORT_INET6) && TNUM_UDP6_CEPID > 0 */ 178 174 179 #if def UDP_CFG_EXTENTIONS175 #if defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0 180 176 181 /* 待ち中に発生したエラー情報を設定する。*/ 182 cep->error = error; 177 #define UDP_SND_DAT udp_snd_dat 178 #define UDP_RCV_DAT udp_rcv_dat 179 #define UDP_CAN_SND udp4_can_snd 180 #define UDP_CAN_RCV udp4_can_rcv 181 #define UDP_ALLOC_AUTO_PORT udp4_alloc_auto_port 182 #define UDP_SEND_DATA udp4_send_data 183 #define VALID_UDP_CEPID VALID_UDP4_CEPID 184 #define GET_UDP_CEP GET_UDP4_CEP 185 #define GET_UDP_CEPID GET_UDP4_CEPID 186 #define T_UDP_CEP T_UDP4_CEP 187 #define T_IPEP T_IPV4EP 188 #define API_PROTO API_PROTO_IPV4 183 189 184 # endif /* of #ifdef UDP_CFG_EXTENTIONS */190 #define IN_COPY_TO_HOST IN4_COPY_TO_HOST 185 191 186 error = rel_wai(cep->snd_tskid); 187 cep->snd_tskid = TA_NULL; 188 } 189 else /* どちらでもないならペンディングしていない */ 190 error = EV_NOPND; 192 #include <netinet/udpn_usrreq_nblk.c> 191 193 192 return error; 193 } 194 195 #endif /* of #ifdef __udp_can_snd */ 196 197 #ifdef __udp_can_rcv 198 199 /* 200 * udp_can_rcv -- ペンディングしている受信のキャンセル 201 */ 202 203 ER 204 udp_can_rcv (T_UDP_CEP *cep, ER error) 205 { 206 if (cep->rcv_p_dstaddr != NULL) { /* ノンブロッキングコールでペンディング中 */ 207 if (IS_PTR_DEFINED(cep->callback)) 208 209 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 210 211 (*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_RCV_DAT, (void*)error); 212 213 #else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */ 214 215 (*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_RCV_DAT, (void*)&error); 216 217 #endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */ 218 219 else 220 error = E_OBJ; 221 cep->rcv_p_dstaddr = NULL; 222 } 223 else if (cep->rcv_tskid != TA_NULL) { /* 非ノンブロッキングコールでペンディング中 */ 224 225 #ifdef UDP_CFG_EXTENTIONS 226 227 /* 待ち中に発生したエラー情報を設定する。*/ 228 cep->error = error; 229 230 #endif /* of #ifdef UDP_CFG_EXTENTIONS */ 231 232 error = rel_wai(cep->rcv_tskid); 233 cep->rcv_tskid = TA_NULL; 234 } 235 else /* どちらでもないならペンディングしていない */ 236 error = EV_NOPND; 237 238 return error; 239 } 240 241 #endif /* of #ifdef __udp_can_rcv */ 242 243 #ifdef __udp_snd_dat 244 245 /* 246 * udp_snd_dat -- パケットの送信【標準機能】 247 */ 248 249 ER_UINT 250 UDP_SND_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout) 251 { 252 T_UDP_CEP *cep; 253 ER error; 254 255 /* p_dstaddr または data が NULL ならエラー */ 256 if (p_dstaddr == NULL || data == NULL) 257 return E_PAR; 258 259 /* データ長をチェックする。*/ 260 if (len < 0 || len + IP_HDR_SIZE + UDP_HDR_SIZE > IF_MTU) 261 return E_PAR; 262 263 /* UDP 通信端点 ID をチェックする。*/ 264 if (!VALID_UDP_CEPID(cepid)) 265 return E_ID; 266 267 /* UDP 通信端点を得る。*/ 268 cep = GET_UDP_CEP(cepid); 269 270 /* UDP 通信端点をチェックする。*/ 271 if (!VALID_UDP_CEP(cep)) 272 return E_NOEXS; 273 274 /* 275 * 自ポート番号が UDP_PORTANY なら、自動で割り当てる。 276 */ 277 if (cep->myaddr.portno == UDP_PORTANY) { 278 if ((error = udp_alloc_auto_port(cep)) != E_OK) 279 return error; 280 } 281 282 /* 283 * タイムアウトをチェックする。 284 */ 285 286 if (tmout == TMO_NBLK) { /* ノンブロッキングコール */ 287 288 /* 通信端点をロックする。*/ 289 syscall(wai_sem(cep->semid_lock)); 290 291 if (cep->snd_p_dstaddr != NULL) { 292 293 /* ノンブロッキングコールでペンディング中 */ 294 error = E_QOVR; 295 296 /* 通信端点をロックを解除する。*/ 297 syscall(sig_sem(cep->semid_lock)); 298 } 299 else if (cep->snd_tskid != TA_NULL) { 300 301 /* 非ノンブロッキングコールでペンディング中 */ 302 error = E_OBJ; 303 304 /* 通信端点をロックを解除する。*/ 305 syscall(sig_sem(cep->semid_lock)); 306 } 307 else { 308 309 cep->snd_p_dstaddr = p_dstaddr; 310 cep->snd_data = data; 311 cep->snd_len = len; 312 313 /* 通信端点をロックを解除する。*/ 314 syscall(sig_sem(cep->semid_lock)); 315 316 cep->flags |= UDP_CEP_FLG_POST_OUTPUT; 317 sig_sem(SEM_UDP_POST_OUTPUT); 318 error = E_WBLK; 319 } 320 } 321 else { /* 非ノンブロッキングコール */ 322 323 /* 通信端点をロックする。*/ 324 syscall(wai_sem(cep->semid_lock)); 325 326 if (cep->snd_p_dstaddr != NULL) { 327 328 /* ノンブロッキングコールでペンディング中 */ 329 error = E_OBJ; 330 331 /* 通信端点をロックを解除する。*/ 332 syscall(sig_sem(cep->semid_lock)); 333 } 334 else if (cep->snd_tskid != TA_NULL) { 335 336 /* 非ノンブロッキングコールでペンディング中 */ 337 error = E_QOVR; 338 339 /* 通信端点をロックを解除する。*/ 340 syscall(sig_sem(cep->semid_lock)); 341 } 342 else { 343 344 /* 現在のタスク識別子を記録する。*/ 345 get_tid(&(cep->snd_tskid)); 346 347 /* 通信端点をロックを解除する。*/ 348 syscall(sig_sem(cep->semid_lock)); 349 350 /* パケットを送信する。*/ 351 error = udp_send_data(cep, p_dstaddr, data, len, tmout); 352 } 353 } 354 355 return error; 356 } 357 358 #endif /* of #ifdef __udp_snd_dat */ 359 360 #ifdef __udp_rcv_dat 361 362 /* 363 * udp_rcv_dat -- パケットの受信【標準機能】 364 */ 365 366 ER_UINT 367 UDP_RCV_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout) 368 { 369 T_NET_BUF *input; 370 T_UDP_CEP *cep; 371 T_UDP_HDR *udph; 372 ER_UINT error; 373 uint_t ulen, uhoff; 374 375 /* p_dstaddr または data が NULL か、len < 0 ならエラー */ 376 if (p_dstaddr == NULL || data == NULL || len < 0) 377 return E_PAR; 378 379 /* UDP 通信端点 ID をチェックする。*/ 380 if (!VALID_UDP_CEPID(cepid)) 381 return E_ID; 382 383 /* UDP 通信端点を得る。*/ 384 cep = GET_UDP_CEP(cepid); 385 386 /* UDP 通信端点をチェックする。*/ 387 if (!VALID_UDP_CEP(cep)) 388 return E_NOEXS; 389 390 /* 391 * タイムアウトをチェックする。 392 */ 393 394 if (tmout == TMO_NBLK) { /* ノンブロッキングコール */ 395 396 /* 通信端点をロックする。*/ 397 syscall(wai_sem(cep->semid_lock)); 398 399 if (cep->rcv_p_dstaddr != NULL) 400 401 /* ノンブロッキングコールでペンディング中 */ 402 error = E_QOVR; 403 404 else if (cep->rcv_tskid != TA_NULL) 405 406 /* 非ノンブロッキングコールでペンディング中 */ 407 error = E_OBJ; 408 else { 409 cep->rcv_p_dstaddr = p_dstaddr; 410 cep->rcv_data = data; 411 cep->rcv_len = len; 412 error = E_WBLK; 413 } 414 415 /* 通信端点をロックを解除する。*/ 416 syscall(sig_sem(cep->semid_lock)); 417 return error; 418 } 419 else { /* 非ノンブロッキングコール */ 420 421 /* 通信端点をロックする。*/ 422 syscall(wai_sem(cep->semid_lock)); 423 424 if (cep->rcv_p_dstaddr != NULL) { 425 426 /* ノンブロッキングコールでペンディング中 */ 427 error = E_OBJ; 428 429 /* 通信端点をロックを解除する。*/ 430 syscall(sig_sem(cep->semid_lock)); 431 } 432 else if (cep->rcv_tskid != TA_NULL) { 433 434 /* 非ノンブロッキングコールでペンディング中 */ 435 error = E_QOVR; 436 437 /* 通信端点をロックを解除する。*/ 438 syscall(sig_sem(cep->semid_lock)); 439 } 440 else { 441 442 /* 現在のタスク識別子を記録する。*/ 443 get_tid(&(cep->rcv_tskid)); 444 445 /* 通信端点をロックを解除する。*/ 446 syscall(sig_sem(cep->semid_lock)); 447 448 /* 入力があるまで待つ。*/ 449 if (cep->cb_netbuf != NULL) { 450 451 /* 452 * ここにくる場合は、コールバック関数の中から 453 * udp_rcv_dat を呼び出していることになり、 454 * すでに入力済みである。 455 */ 456 input = cep->cb_netbuf; 457 cep->cb_netbuf = NULL; 458 } 459 else if ((error = trcv_dtq(cep->rcvqid, (intptr_t*)&input, tmout)) != E_OK) { 460 cep->rcv_tskid = TA_NULL; 461 return error; 462 } 463 464 /* p_dstaddr を設定する。*/ 465 uhoff = (uint_t)GET_UDP_HDR_OFFSET(input); 466 udph = GET_UDP_HDR(input, uhoff); 467 p_dstaddr->portno = ntohs(udph->sport); 468 IN_COPY_TO_HOST(&p_dstaddr->ipaddr, &GET_IP_HDR(input)->src); 469 470 /* データをバッファに移す。*/ 471 ulen = ntohs(udph->ulen); 472 if (ulen - UDP_HDR_SIZE > len) 473 error = E_BOVR; 474 else { 475 len = (int_t)(ulen - UDP_HDR_SIZE); 476 error = (ER_UINT)(ulen - UDP_HDR_SIZE); 477 } 478 479 memcpy(data, GET_UDP_SDU(input, uhoff), (size_t)len); 480 481 syscall(rel_net_buf(input)); 482 483 cep->rcv_tskid = TA_NULL; 484 } 485 return error; 486 } 487 } 488 489 #endif /* of #ifdef __udp_rcv_dat */ 194 #endif /* of #if defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0 */ 490 195 491 196 #endif /* of #ifdef UDP_CFG_NON_BLOCKING */
Note:
See TracChangeset
for help on using the changeset viewer.