1 /*--------------------------------------------------------------------------
2 Project: HorizonSDK
3 File: rdt_ReceiverImpl.cpp
4 Copyright 2009 Nintendo. All rights reserved.
5 These coded instructions, statements, and computer programs contain
6 proprietary information of Nintendo of America Inc. and/or Nintendo
7 Company Ltd., and are protected by Federal copyright law. They may
8 not be disclosed to third parties or copied or duplicated in any form,
9 in whole or in part, without the prior written consent of Nintendo.
10 $Date:: 2010-09-14#$
11 $Rev: 25753 $
12 $Author: hiratsu_daisuke $
13 *-------------------------------------------------------------------------
14
15
16 */
17
18 #include "stdafx.h"
19
20 #include "rdt_ReceiverImpl.h"
21
22 #include <nn/rdt/CTR/rdt_define.h>
23 #include <nn/rdt/CTR/rdt_Result.h>
24
25
26 namespace
27 {
28
29 } // End of anonymous namespace
30
31 namespace nn { namespace rdt { namespace CTR {
32
33
34 // Base class for "State"
35 class ReceiverStateBase{
36 public:
~ReceiverStateBase(void)37 virtual ~ReceiverStateBase(void){}
38
39 virtual void initialize(ReceiverImpl *pReceiver); // Called when this state is started
40 virtual void finalize (ReceiverImpl *pReceiver); // Called when this state is finished
41 virtual void update (ReceiverImpl *pReceiver);
42 virtual enum ReceiverState getStatus(void) const = 0;
43
44 protected:
ReceiverStateBase(void)45 ReceiverStateBase(void){}
46 };
47
48
initialize(ReceiverImpl * pReceiver)49 void ReceiverStateBase::initialize(ReceiverImpl *pReceiver)
50 {
51 (void)pReceiver;
52 }
53
54
finalize(ReceiverImpl * pReceiver)55 void ReceiverStateBase::finalize(ReceiverImpl *pReceiver)
56 {
57 (void)pReceiver;
58 }
59
60
update(ReceiverImpl * pReceiver)61 void ReceiverStateBase::update(ReceiverImpl *pReceiver)
62 {
63 (void)pReceiver;
64 }
65
66
67 class ReceiverStateWaiting : public ReceiverStateBase{
68 public:
69 static ReceiverStateBase* getInstance(void);
70 virtual void update(ReceiverImpl *pReceiver);
71 virtual enum ReceiverState getStatus(void) const;
72
73 protected:
ReceiverStateWaiting(void)74 ReceiverStateWaiting(void){}
75 };
76
77
78 class ReceiverStateOpened : public ReceiverStateBase{
79 public:
80 static ReceiverStateBase* getInstance(void);
81 virtual void update(ReceiverImpl *pReceiver);
82 virtual enum ReceiverState getStatus(void) const;
83
84 protected:
ReceiverStateOpened(void)85 ReceiverStateOpened(void){}
86 };
87
88
89 class ReceiverStateWaitingFinished : public ReceiverStateBase{
90 public:
91 static ReceiverStateBase* getInstance(void);
92 virtual void update(ReceiverImpl *pReceiver);
93 virtual enum ReceiverState getStatus(void) const;
94
95 protected:
ReceiverStateWaitingFinished(void)96 ReceiverStateWaitingFinished(void){}
97 };
98
99
100 class ReceiverStateFinished : public ReceiverStateBase{
101 public:
102 static ReceiverStateBase* getInstance(void);
103 virtual void update(ReceiverImpl *pReceiver);
104 virtual enum ReceiverState getStatus(void) const;
105
106 protected:
ReceiverStateFinished(void)107 ReceiverStateFinished(void){}
108 };
109
110
111 class ReceiverStateClosed : public ReceiverStateBase{
112 public:
113 static ReceiverStateBase* getInstance(void);
114 virtual void initialize(ReceiverImpl *pReceiver);
115 virtual void update (ReceiverImpl *pReceiver);
116 virtual enum ReceiverState getStatus(void) const;
117
118 protected:
ReceiverStateClosed(void)119 ReceiverStateClosed(void){}
120 };
121
122
123 // The following is an implementation of an inherited class.
124
getInstance(void)125 ReceiverStateBase* ReceiverStateWaiting::getInstance(void)
126 {
127 static ReceiverStateWaiting s_instance;
128 return &s_instance;
129 }
130
131
getStatus(void) const132 enum ReceiverState ReceiverStateWaiting::getStatus(void) const
133 {
134 return RECEIVER_STATE_WAITING;
135 }
136
137
update(ReceiverImpl * pReceiver)138 void ReceiverStateWaiting::update(ReceiverImpl *pReceiver)
139 {
140 ASSERT(pReceiver!=NULL);
141
142 //Process here if segment is received.
143 Segment seg;
144 if(pReceiver->pullSegment(&seg).IsSuccess())
145 {
146 if(seg.IsRst())
147 {
148 // Per the TCP RFC, it is described that RST received during a LISTEN state should be ignored.
149 //Therefore, nothing is done here.
150 }
151 else if(seg.IsSyn())
152 {
153 // If this is a proper connection request from a remote source, ACK is returned.
154
155 // Set receive buffer
156 pReceiver->m_recvBuf.SetInitialSequenceNumber(seg.GetSeqNumber());
157
158 // Response to SYN.
159 pReceiver->putSynAckSegment(seg.GetSeqNumber() + 1);
160 pReceiver->setNextState(ReceiverStateOpened::getInstance());
161 }
162 }
163 }
164
165
getInstance(void)166 ReceiverStateBase* ReceiverStateOpened::getInstance(void)
167 {
168 static ReceiverStateOpened s_instance;
169 return &s_instance;
170 }
171
172
getStatus(void) const173 enum ReceiverState ReceiverStateOpened::getStatus(void) const
174 {
175 return RECEIVER_STATE_OPENED;
176 }
177
178
update(ReceiverImpl * pReceiver)179 void ReceiverStateOpened::update(ReceiverImpl *pReceiver)
180 {
181 ASSERT(pReceiver!=NULL);
182
183 //Process here if segment is received.
184 Segment seg;
185 if(pReceiver->pullSegment(&seg).IsSuccess())
186 {
187 // First, RST bit check
188 if(seg.IsRst())
189 {
190 pReceiver->setNextState(ReceiverStateClosed::getInstance());
191 pReceiver->errorHandling(ResultResetReceived());
192 return;
193 }
194
195 // Has the segment with the expected sequence number arrived?
196 ReceiveBuffer &rBuf = pReceiver->m_recvBuf;
197 if(seg.GetSeqNumber()==rBuf.GetLatestSequenceNumber()+1)
198 {
199 if(seg.IsData())
200 {
201 bool result = rBuf.Push(seg.payload, seg.GetDataLength());
202 if(result)
203 {
204 // Data has been stored in the receive buffer without problems.
205 // In the existing implementation, the ACK is returned, and as a result it is nothing but a ACK packet of the reception side.
206 // So, returning the ACK here was eliminated.
207 }
208 else
209 {
210 LOG("Received data segment, but could not return ACK because receive buffer did not have enough space.\n");
211 }
212 }
213 else if(seg.IsFin())
214 {
215 // ACK transmission for the FIN segment
216 pReceiver->putFinAckSegment(seg.GetSeqNumber() + 1);
217 pReceiver->setNextState(ReceiverStateWaitingFinished::getInstance());
218 }
219 else
220 {
221 seg.PrintDebugInfo();
222 PANIC("It seems that SEQ number is valid, but unexpected segment. It is not DATA, nor FIN.");
223 }
224 }
225 else if(seg.GetSeqNumber()==rBuf.GetLatestSequenceNumber())
226 {
227 // If no response for Syn arrives, it may be considered that the Sender resends a Syn request.
228 // Handling for this case.
229 if(seg.IsSyn())
230 {
231 // Response to SYN.
232 pReceiver->putSynAckSegment(seg.GetSeqNumber() + 1);
233 }
234 }
235
236 else
237 {
238 VERBOSE("Unexpected SEQ number. (%d)\n", seg.GetSeqNumber());
239 VERBOSE("SEQ number %d is expected.\n", rBuf.GetLatestSequenceNumber()+1);
240 VERBOSE("Received segment will be ignored.\n");
241
242 #if 0
243 // Because it was not an expected segment, the possibility of a packet loss is suspected.
244 // For now, return ACK quickly for the portion received to this point.
245 pReceiver->putAckSegment();
246
247 // If the above code is entered, it actually made it slower. Probably because there are a lot of ACK packets issued ...
248 #endif
249 }
250 }
251 }
252
253
getInstance(void)254 ReceiverStateBase* ReceiverStateWaitingFinished::getInstance(void)
255 {
256 static ReceiverStateWaitingFinished s_instance;
257 return &s_instance;
258 }
259
260
getStatus(void) const261 enum ReceiverState ReceiverStateWaitingFinished::getStatus(void) const
262 {
263 return RECEIVER_STATE_WAITING_FINISHED;
264 }
265
266
update(ReceiverImpl * pReceiver)267 void ReceiverStateWaitingFinished::update(ReceiverImpl *pReceiver)
268 {
269 // These return ACK for FIN, but it is not assured that the ACK has arrived to the other party even if the Finished state is entered.
270 //
271 // To determine if the ACK arrived at the other party, you must confirm that no resend packet has arrived from the other party after some time has passed.
272 //
273
274 ASSERT(pReceiver!=NULL);
275
276 //Process here if segment is received.
277 Segment seg;
278 if(pReceiver->pullSegment(&seg).IsSuccess())
279 {
280 // RST bit check
281 if(seg.IsRst())
282 {
283 pReceiver->setNextState(ReceiverStateClosed::getInstance());
284 pReceiver->errorHandling(ResultResetReceived());
285 return;
286 }
287
288 // Has FIN segment arrived?
289 ReceiveBuffer &rBuf = pReceiver->m_recvBuf;
290 if(seg.GetSeqNumber()==rBuf.GetLatestSequenceNumber()+1)
291 {
292 if(seg.IsFin())
293 {
294 pReceiver->putFinAckSegment(seg.GetSeqNumber() + 1);
295 }
296 else
297 {
298 seg.PrintDebugInfo();
299 PANIC("Sequence number is valid, but FIN is not included.\n");
300 }
301 }
302 else
303 {
304 // seg.PrintDebugInfo();
305 LOG("Segment with unexpected sequence number. Ignored.\n");
306 }
307 }
308
309 // State transition after timeout determination.
310 if(pReceiver->isSenderClosed())
311 {
312 pReceiver->setNextState(ReceiverStateFinished::getInstance());
313 }
314 }
315
316
getInstance(void)317 ReceiverStateBase* ReceiverStateFinished::getInstance(void)
318 {
319 static ReceiverStateFinished s_instance;
320 return &s_instance;
321 }
322
323
getStatus(void) const324 enum ReceiverState ReceiverStateFinished::getStatus(void) const
325 {
326 return RECEIVER_STATE_FINISHED;
327 }
328
329
update(ReceiverImpl * pReceiver)330 void ReceiverStateFinished::update(ReceiverImpl *pReceiver)
331 {
332 ASSERT(pReceiver!=NULL);
333
334 //Process here if segment is received.
335 Segment seg;
336 if(pReceiver->pullSegment(&seg).IsSuccess())
337 {
338 // TODO: Should send RST for segments that do not include RST.
339 PANIC("State is FINISHED, but received segment from remote!\n");
340 }
341 }
342
343
344
getInstance(void)345 ReceiverStateBase* ReceiverStateClosed::getInstance(void)
346 {
347 static ReceiverStateClosed s_instance;
348 return &s_instance;
349 }
350
351
getStatus(void) const352 enum ReceiverState ReceiverStateClosed::getStatus(void) const
353 {
354 return RECEIVER_STATE_CLOSED;
355 }
356
357
initialize(ReceiverImpl * pReceiver)358 void ReceiverStateClosed::initialize(ReceiverImpl *pReceiver)
359 {
360 ASSERT(pReceiver!=NULL);
361
362 pReceiver->clear();
363 }
364
365
update(ReceiverImpl * pReceiver)366 void ReceiverStateClosed::update(ReceiverImpl *pReceiver)
367 {
368 ASSERT(pReceiver!=NULL);
369
370 // For segments (not including RST) received while in CLOSED state, respond with RST
371 Segment seg;
372 if(pReceiver->pullSegment(&seg).IsSuccess() && !seg.IsRst())
373 {
374 LOG("Receiver is in CLOSED state, but received segment. RST will be sent.\n");
375 if(seg.IsAck())
376 {
377 pReceiver->sendRstSegment(seg.GetAckNumber());
378 }
379 else
380 {
381 const u32 SEQ = 0;
382 const u32 ACK = seg.GetSeqNumber() + seg.GetSegmentLength();
383 pReceiver->sendRstAckSegment(SEQ, ACK);
384 }
385 }
386 }
387
388
389
390 //
ReceiverImpl(void)391 ReceiverImpl::ReceiverImpl(void) throw()
392 :m_initialized(false)
393 {
394 }
395
396
397 //
~ReceiverImpl(void)398 ReceiverImpl::~ReceiverImpl(void)
399 {
400 Finalize();
401 }
402
403
404 #ifdef _WIN32
Initialize(SOCKET sock,void * pRecvBuf,u16 recvBufSize)405 nn::Result ReceiverImpl::Initialize(SOCKET sock, void *pRecvBuf, u16 recvBufSize)
406 #else
407 nn::Result ReceiverImpl::Initialize(u16 nodeId, u8 port, void *pRecvBuf, u16 recvBufSize)
408 #endif
409 {
410 if(m_initialized)
411 {
412 return ResultAlreadyInitialized();
413 }
414 else
415 {
416 if(pRecvBuf==NULL)
417 {
418 return ResultNullPointer();
419 }
420
421 if(recvBufSize==0)
422 {
423 return ResultInvalidSize();
424 }
425
426 #ifdef _WIN32
427 nn::Result result = HostBase::Initialize(sock);
428 #elif defined(NN_PLATFORM_CTR)
429 nn::Result result = HostBase::Initialize(nodeId, port);
430 #endif
431 if(result.IsFailure())
432 {
433 return result;
434 }
435 else
436 {
437 m_pState = ReceiverStateClosed::getInstance();
438 m_pNextState = NULL;
439 m_recvBuf.Initialize(pRecvBuf, recvBufSize);
440
441 clear();
442
443 m_initialized = true;
444 return ResultSuccess();
445 }
446 }
447 }
448
449
Finalize(void)450 void ReceiverImpl::Finalize(void)
451 {
452 if(m_initialized)
453 {
454 m_initialized = false;
455 m_recvBuf.Finalize();
456 HostBase::Finalize();
457 }
458 else
459 {
460 // Do nothing.
461 }
462 }
463
464
Wait(void)465 nn::Result ReceiverImpl::Wait(void)
466 {
467 ASSERT(m_initialized);
468
469 if(GetStatus()==RECEIVER_STATE_CLOSED)
470 {
471 setNextState(ReceiverStateWaiting::getInstance());
472 changeState();
473 return ResultSuccess();
474 }
475 else
476 {
477 return ResultUntimelyFunctionCall();
478 }
479 }
480
481
Close(void)482 nn::Result ReceiverImpl::Close(void)
483 {
484 ASSERT(m_initialized);
485
486 if(GetStatus()==RECEIVER_STATE_FINISHED)
487 {
488 setNextState(ReceiverStateClosed::getInstance());
489 changeState();
490 return ResultSuccess();
491 }
492 else
493 {
494 return ResultUntimelyFunctionCall();
495 }
496 }
497
498
Receive(void * pBuf,size_t * recvSize,size_t bufSize)499 nn::Result ReceiverImpl::Receive(void *pBuf, size_t *recvSize, size_t bufSize)
500 {
501 ASSERT(m_initialized);
502
503 if((pBuf==NULL) || (recvSize==NULL))
504 {
505 return ResultNullPointer();
506 }
507
508 if(bufSize==0)
509 {
510 return ResultDoNothing();
511 }
512
513 enum ReceiverState stat = GetStatus();
514 if((stat!=RECEIVER_STATE_OPENED) && (stat!=RECEIVER_STATE_WAITING_FINISHED) && (stat!=RECEIVER_STATE_FINISHED))
515 {
516 return ResultUntimelyFunctionCall();
517 }
518
519 *recvSize = m_recvBuf.Read(pBuf, bufSize);
520 if(*recvSize > 0)
521 {
522 m_recvBuf.Pop(*recvSize);
523 }
524
525 // Using Receive as the trigger, notify window remotely.
526 // Since space in the receive window was made, send segment for the purpose of remote notification.
527 // If attempting to send a segment while not in the OPENED state, a state check is performed with the if-statement because there is a possibility that the connection has been interrupted.
528 //
529 if(GetStatus()==RECEIVER_STATE_OPENED)
530 {
531 putAckSegment();
532 }
533
534 return ResultSuccess();
535 }
536
537
Process(void)538 nn::Result ReceiverImpl::Process(void)
539 {
540 ASSERT(m_initialized);
541
542 // update function for each state.
543 if(m_pState)
544 {
545 m_pState->update(this);
546 }
547
548 // State Transitions
549 changeState();
550
551 // Error returned here.
552 // If returned, reset error.
553 nn::Result ret = GetErrorCode();
554 errorHandling(ResultSuccess());
555 return ret;
556 }
557
558
GetStatus(void) const559 enum ReceiverState ReceiverImpl::GetStatus(void) const
560 {
561 ASSERT(m_initialized);
562 ASSERTMSG(m_pState!=NULL, "It seems that state is not initialized.\n");
563
564 return m_pState->getStatus();
565 }
566
567
Cancel(void)568 void ReceiverImpl::Cancel(void)
569 {
570 ASSERT(m_initialized);
571
572 // The cancel process executes immediately without waiting for the Process function.
573
574 // RST transmission
575 const u32 seq = 0;
576 sendRstSegment(seq);
577
578 // To Closed state immediately.
579 setNextState(ReceiverStateClosed::getInstance());
580 changeState();
581 }
582
583
584 // State Transitions. Do nothing specific if the next state is not set.
changeState(void)585 void ReceiverImpl::changeState(void)
586 {
587 if(m_pNextState)
588 {
589 if(m_pState)
590 {
591 m_pState->finalize(this);
592 }
593 m_pState = m_pNextState;
594 m_pNextState = NULL;
595 m_pState->initialize(this);
596 }
597 }
598
599
setNextState(ReceiverStateBase * p)600 void ReceiverImpl::setNextState(ReceiverStateBase *p)
601 {
602 ASSERT(p!=NULL);
603 ASSERT(m_pNextState==NULL);
604
605 m_pNextState = p;
606 }
607
608
putSynAckSegment(u32 ack)609 void ReceiverImpl::putSynAckSegment(u32 ack)
610 {
611 Segment a;
612 a.ClearHeader();
613 a.SetAckNumber(ack);
614 a.SetWindowSize(m_recvBuf.GetRestSize());
615 putSegment(a);
616 }
617
618
putAckSegment(void)619 void ReceiverImpl::putAckSegment(void)
620 {
621 Segment a;
622 a.ClearHeader();
623 a.SetAckNumber(m_recvBuf.GetLatestSequenceNumber()+1);
624 a.SetWindowSize(m_recvBuf.GetRestSize());
625 putSegment(a);
626 }
627
628
putFinAckSegment(u32 ack)629 void ReceiverImpl::putFinAckSegment(u32 ack)
630 {
631 Segment a;
632 a.ClearHeader();
633 a.SetAckNumber(ack);
634 a.SetWindowSize(m_recvBuf.GetRestSize());
635 putSegment(a);
636
637 m_finAckSentTime = GetCurrentTimeAsMillisecond();
638 }
639
640
isSenderClosed(void) const641 bool ReceiverImpl::isSenderClosed(void) const
642 {
643 ASSERT(m_finAckSentTime!=0);
644
645 // LOG("m_finAckSentTime = %lld\n", m_finAckSentTime);
646 // LOG("Current: %lld\n", GetCurrentTimeAsMillisecond());
647 return GetCurrentTimeAsMillisecond() - m_finAckSentTime > FIN_TIMEOUT;
648 }
649
650
clear(void)651 void ReceiverImpl::clear(void)
652 {
653 m_recvBuf.Clear();
654 m_finAckSentTime = 0;
655 }
656
657
PrintDebugInfo(void) const658 void ReceiverImpl::PrintDebugInfo(void) const
659 {
660 LOG("-- Receiver debug information --\n");
661 LOG("Current state: %d\n", GetStatus());
662 m_recvBuf.PrintDebugInfo();
663 LOG("\n");
664 }
665
666 }}} // namespace nn::rdt::CTR
667