1 /*********************************************************************************
\r
3 * --------------------------------------------------------------------------------
\r
5 * This file is part of MiMic
\r
6 * Copyright (C)2011 Ryo Iizuka
\r
8 * MiMic is free software: you can redistribute it and/or modify
\r
9 * it under the terms of the GNU Lesser General Public License as published
\r
10 * by the Free Software Foundation, either version 3 of the License, or
\r
11 * (at your option) any later version.
\r
13 * This program is distributed in the hope that it will be useful,
\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
16 * GNU General Public License for more details.
\r
18 * You should have received a copy of the GNU Lesser General Public License
\r
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
\r
21 * For further information please contact.
\r
23 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
\r
25 *********************************************************************************/
\r
26 #include "NyLPC_cTcpListener_protected.h"
\r
27 #include "NyLPC_cTcpSocket_protected.h"
\r
28 #include "NyLPC_cUipService_protected.h"
\r
29 #include "NyLPC_cIPv4.h"
\r
30 #include "NyLPC_stdlib.h"
\r
33 * NyLPC_TTcpListenerListenQ
\r
36 void NyLPC_TTcpListenerListenQ_init(struct NyLPC_TTcpListenerListenQ* i_struct)
\r
40 for(i=NyLPC_TcTcpListener_NUMBER_OF_Q-1;i>=0;i--){
\r
41 i_struct->item[i].rport=0;
\r
46 * ListenQへSYNパケットの情報を追加する。
\r
48 void NyLPC_TTcpListenerListenQ_add(struct NyLPC_TTcpListenerListenQ* i_struct,const NyLPC_TcIPv4Payload_t* i_payload)
\r
50 struct NyLPC_TTcpSocketSynParam* item=&i_struct->item[i_struct->wp];
\r
57 item->rport = i_payload->payload.tcp->srcport;
\r
58 item->srcaddr=i_payload->header->srcipaddr;
\r
59 item->rcv_nxt32=NyLPC_ntohl(i_payload->payload.tcp->seqno32)+1;
\r
61 if(!NyLPC_TTcpHeader_getTcpMmsOpt(i_payload->payload.tcp,&item->mss)){
\r
65 i_struct->wp=(i_struct->wp+1)%NyLPC_TcTcpListener_NUMBER_OF_Q;
\r
69 * 最も古いSYNパケット情報のインデクスをキューから返す。
\r
73 int NyLPC_TTcpListenerListenQ_getLastIndex(struct NyLPC_TTcpListenerListenQ* i_struct)
\r
77 for(i=1;i<=NyLPC_TcTcpListener_NUMBER_OF_Q;i++){
\r
78 t=(i_struct->wp+i)%NyLPC_TcTcpListener_NUMBER_OF_Q;
\r
80 if(i_struct->item[t].rport!=0){
\r
90 void NyLPC_TTcpListenerListenQ_remove(struct NyLPC_TTcpListenerListenQ* i_struct,int i_idx)
\r
92 i_struct->item[i_idx].rport=0;
\r
101 //#define lockResource(i_inst) NyLPC_cMutex_lock(((i_inst)->_mutex))
\r
102 //#define unlockResource(i_inst) NyLPC_cMutex_unlock(((i_inst)->_mutex))
\r
103 #define lockResource(i_inst) NyLPC_cMutex_lock(NyLPC_cIPv4_getListenerMutex(((i_inst)->_super._parent_ipv4)))
\r
104 #define unlockResource(i_inst) NyLPC_cMutex_unlock(NyLPC_cIPv4_getListenerMutex(((i_inst)->_super._parent_ipv4)))
\r
108 * uipサービスが稼働中にのみ機能します。
110 NyLPC_TBool NyLPC_cTcpListener_initialize(NyLPC_TcTcpListener_t* i_inst,NyLPC_TUInt16 i_port)
\r
112 NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst;
\r
113 NyLPC_cBaseSocket_initialize(&(i_inst->_super),NyLPC_TcBaseSocket_TYPEID_TCP_LISTENER);
\r
114 NyLPC_TTcpListenerListenQ_init(&i_inst->_listen_q);
\r
115 //uipサービスは初期化済であること。
\r
116 NyLPC_Assert(NyLPC_TcUipService_isInitService());
\r
118 // // NyLPC_cMutex_initialize(&(i_inst->_mutex));
\r
119 // i_inst->_mutex=NyLPC_cIPv4_getListenerMutex(&srv->_tcpv4);// NyLPC_cMutex_initialize(&(i_inst->_mutex));
\r
120 i_inst->_port=NyLPC_htons(i_port);
\r
122 return NyLPC_cIPv4_addSocket(&(srv->_tcpv4),&(i_inst->_super));
\r
125 void NyLPC_cTcpListener_finaize(NyLPC_TcTcpListener_t* i_inst)
\r
127 NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst;
\r
128 NyLPC_Assert(NyLPC_TcUipService_isInitService());
\r
129 //uipサービスは初期化済であること。
\r
130 if(!NyLPC_cIPv4_removeSocket(&(srv->_tcpv4),&(i_inst->_super))){
\r
134 NyLPC_cBaseSocket_finalize(&(i_inst->_super));
\r
141 NyLPC_TBool NyLPC_cTcpListener_listen(NyLPC_TcTcpListener_t* i_inst,NyLPC_TcTcpSocket_t* i_sock,NyLPC_TUInt32 i_wait_msec)
\r
144 NyLPC_TcStopwatch_t sw;
\r
145 NyLPC_TBool ret=NyLPC_TBool_FALSE;
\r
147 NyLPC_Assert(NyLPC_cUipService_isRun());
\r
149 //入力ソケットはCLOSEDであること。
\r
150 if(i_sock->tcpstateflags!=UIP_CLOSED){
\r
151 return NyLPC_TBool_FALSE;
\r
155 NyLPC_cStopwatch_initialize(&sw);
\r
156 NyLPC_cStopwatch_setNow(&sw);
\r
160 lockResource(i_inst);
\r
162 while(NyLPC_cStopwatch_elapseInMsec(&sw)<i_wait_msec){
\r
163 qi=NyLPC_TTcpListenerListenQ_getLastIndex(&i_inst->_listen_q);
\r
166 if(!NyLPC_cTcpSocket_listenSyn(i_sock,&i_inst->_listen_q.item[qi],i_inst->_port)){
\r
167 ret=NyLPC_TBool_FALSE;
\r
170 ret=NyLPC_TBool_TRUE;
\r
173 NyLPC_TTcpListenerListenQ_remove(&i_inst->_listen_q,qi);
\r
176 //SYN処理要求は無い(しばらくまつ)
\r
177 unlockResource(i_inst);
\r
178 NyLPC_cThread_yield();
\r
179 lockResource(i_inst);
\r
183 unlockResource(i_inst);
\r
184 NyLPC_cStopwatch_finalize(&sw);
\r
189 * この関数は、Uip受信タスクから実行します。
191 NyLPC_TBool NyLPC_cTcpListener_synPacket(NyLPC_TcTcpListener_t* i_inst,const NyLPC_TcIPv4Payload_t* i_payload)
\r
193 //パケットチェック。SYN設定されてる?
\r
194 if(!(i_payload->payload.tcp->flags & TCP_SYN)){
\r
196 return NyLPC_TBool_FALSE;
\r
198 //peer port==0は受け取らない。
\r
199 if(i_payload->payload.tcp->srcport==0){
\r
200 return NyLPC_TBool_FALSE;
\r
203 lockResource(i_inst);
\r
205 NyLPC_TTcpListenerListenQ_add(&(i_inst->_listen_q),i_payload);
\r
206 //Listenerのリソースアンロック
\r
207 unlockResource(i_inst);
\r
208 return NyLPC_TBool_TRUE;
\r