1 /*--------------------------------------------------------------------------
2 Project: HorizonSDK
3 File: rdt_SenderImpl.cpp
4
5 Copyright 2009 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2010-09-14#$
14 $Rev: 25753 $
15 $Author: hiratsu_daisuke $
16 *-------------------------------------------------------------------------*/
17
18 #include "stdafx.h"
19
20 #include "rdt_SenderImpl.h"
21
22 #include <nn/rdt/CTR/rdt_define.h>
23 #include <nn/rdt/CTR/rdt_Result.h>
24
25 #include "rdt_Stopwatch.h"
26
27 #include "Test.h"
28
29
30 namespace
31 {
32
33 } // end of anonymous namespace
34
35
36 namespace nn { namespace rdt { namespace CTR {
37
38
39 // 「状態」の基底クラス。
40 class SenderStateBase{
41 public:
~SenderStateBase(void)42 virtual ~SenderStateBase(void){}
43
44 virtual void initialize(SenderImpl *pSender); // この状態が開始されるときに呼ばれる
45 virtual void finalize (SenderImpl *pSender); // この状態が終了されるときに呼ばれる
46 void update (SenderImpl *pSender);
47 virtual void updatePrologue (SenderImpl *pSender);
48 virtual void updateCore (SenderImpl *pSender);
49 virtual void updateEpilogue (SenderImpl *pSender);
50 virtual enum SenderState getStatus(void) const = 0;
51
52 protected:
SenderStateBase(void)53 SenderStateBase(void){}
54 };
55
56
initialize(SenderImpl * pSender)57 void SenderStateBase::initialize(SenderImpl *pSender)
58 {
59 (void)pSender;
60 }
61
62
finalize(SenderImpl * pSender)63 void SenderStateBase::finalize(SenderImpl *pSender)
64 {
65 (void)pSender;
66 }
67
68
updatePrologue(SenderImpl * pSender)69 void SenderStateBase::updatePrologue(SenderImpl *pSender)
70 {
71 (void)pSender;
72 }
73
74
updateCore(SenderImpl * pSender)75 void SenderStateBase::updateCore(SenderImpl *pSender)
76 {
77 (void)pSender;
78 }
79
80
updateEpilogue(SenderImpl * pSender)81 void SenderStateBase::updateEpilogue(SenderImpl *pSender)
82 {
83 (void)pSender;
84 }
85
86
update(SenderImpl * pSender)87 void SenderStateBase::update(SenderImpl *pSender)
88 {
89 updatePrologue(pSender);
90 updateCore(pSender);
91 updateEpilogue(pSender);
92 }
93
94
95 class SenderStateOpenRequested : public SenderStateBase{
96 public:
97 static SenderStateBase* getInstance(void);
98
99 virtual void updateCore(SenderImpl *pSender);
100 virtual enum SenderState getStatus(void) const;
101
102 protected:
SenderStateOpenRequested(void)103 SenderStateOpenRequested(void){}
104 };
105
106
107 class SenderStateOpening : public SenderStateBase{
108 public:
109 static SenderStateBase* getInstance(void);
110
111 virtual void updateCore(SenderImpl *pSender);
112 virtual enum SenderState getStatus(void) const;
113
114 protected:
SenderStateOpening(void)115 SenderStateOpening(void){}
116 };
117
118
119 class SenderStateOpened : public SenderStateBase{
120 public:
121 static SenderStateBase* getInstance(void);
122
123 virtual void updateCore(SenderImpl *pSender);
124 virtual enum SenderState getStatus(void) const;
125
126 protected:
SenderStateOpened(void)127 SenderStateOpened(void){}
128 };
129
130
131 class SenderStateCloseRequested : public SenderStateBase{
132 public:
133 static SenderStateBase* getInstance(void);
134
135 virtual void updateCore(SenderImpl *pSender);
136 virtual enum SenderState getStatus(void) const;
137
138 protected:
SenderStateCloseRequested(void)139 SenderStateCloseRequested(void){}
140 };
141
142
143 class SenderStateClosing : public SenderStateBase{
144 public:
145 static SenderStateBase* getInstance(void);
146
147 virtual void updateCore(SenderImpl *pSender);
148 virtual enum SenderState getStatus(void) const;
149
150 protected:
SenderStateClosing(void)151 SenderStateClosing(void){}
152 };
153
154
155 class SenderStateClosed : public SenderStateBase{
156 public:
157 static SenderStateBase* getInstance(void);
158
159 virtual void initialize(SenderImpl *pSender);
160 virtual void updateCore(SenderImpl *pSender);
161 virtual enum SenderState getStatus(void) const;
162
163 protected:
SenderStateClosed(void)164 SenderStateClosed(void){}
165 };
166
167
168 // 以下、State派生クラスの実装。
getInstance(void)169 SenderStateBase* SenderStateClosed::getInstance(void)
170 {
171 static SenderStateClosed s_instance;
172 return &s_instance;
173 }
174
175
getStatus(void) const176 enum SenderState SenderStateClosed::getStatus(void) const
177 {
178 return SENDER_STATE_CLOSED;
179 }
180
181
initialize(SenderImpl * pSender)182 void SenderStateClosed::initialize(SenderImpl *pSender)
183 {
184 ASSERT(pSender!=NULL);
185
186 pSender->clear();
187 }
188
189
updateCore(SenderImpl * pSender)190 void SenderStateClosed::updateCore(SenderImpl *pSender)
191 {
192 ASSERT(pSender!=NULL);
193
194 // CLOSED状態の時に受信した(RSTを含まない)セグメントに対しては、RSTで返答
195 Segment seg;
196 if(pSender->pullSegment(&seg).IsSuccess() && !seg.IsRst())
197 {
198 #if 0
199 LOG("SenderはCLOSED状態ですが、セグメントが届いてしまったので、RSTで返答します。\n");
200 LOG("受信セグメントの内容は、\n");
201 seg.PrintDebugInfo();
202 LOG("です。\n");
203 const u32 SEQ = 0;
204 pSender->sendRstSegment(SEQ);
205 #else
206 LOG("Sender is in CLOSED state, but received segment. Ignored.\n");
207 #endif
208 }
209 }
210
211
getInstance(void)212 SenderStateBase* SenderStateOpenRequested::getInstance(void)
213 {
214 static SenderStateOpenRequested s_instance;
215 return &s_instance;
216 }
217
218
getStatus(void) const219 enum SenderState SenderStateOpenRequested::getStatus(void) const
220 {
221 return SENDER_STATE_OPEN_REQUESTED;
222 }
223
224
updateCore(SenderImpl * pSender)225 void SenderStateOpenRequested::updateCore(SenderImpl *pSender)
226 {
227 // 接続要求セグメントを送る
228 pSender->sendSynSegment();
229
230 // 次の状態へ。
231 pSender->setNextState(SenderStateOpening::getInstance());
232 }
233
234
getInstance(void)235 SenderStateBase* SenderStateOpening::getInstance(void)
236 {
237 static SenderStateOpening s_instance;
238 return &s_instance;
239 }
240
241
getStatus(void) const242 enum SenderState SenderStateOpening::getStatus(void) const
243 {
244 return SENDER_STATE_OPENING;
245 }
246
247
updateCore(SenderImpl * pSender)248 void SenderStateOpening::updateCore(SenderImpl *pSender)
249 {
250 ASSERT(pSender!=NULL);
251
252 // 受信したセグメントの内容を調べる。
253 Segment seg;
254 if(pSender->pullSegment(&seg).IsSuccess())
255 {
256 pSender->processReceivedSegment(seg);
257
258 if(seg.IsRst())
259 {
260 // こちらのSYNに対するRSTかどうかをチェック。SYNに対するものでなければ、セグメントは破棄。
261 if(seg.IsAck() && seg.GetAckNumber()==pSender->getInitialSequenceNumber()+1)
262 {
263 // SYNは拒否されたと見なす。CLOSEDへ。
264 LOG("SYN rejected. CLOSED... ack of segment = %u\n", seg.GetAckNumber());
265 pSender->setNextState(SenderStateClosed::getInstance());
266 pSender->errorHandling(ResultResetReceived());
267 return;
268 }
269 else
270 {
271 LOG("Ignored RST segment.\n");
272 }
273 }
274 else if(seg.IsAck())
275 {
276 if(seg.GetAckNumber()==pSender->getInitialSequenceNumber()+1)
277 {
278 // SYNに対するACKが返ってきたので、次の状態に移行。
279 pSender->setNextState(SenderStateOpened::getInstance());
280 }
281 else
282 {
283 LOG("ack : %u\n", seg.GetAckNumber());
284 LOG("una : %u\n", pSender->getUnacknowledgeNumber());
285 LOG("nxt : %u\n", pSender->getNextSequenceNumber());
286 LOG("It seems that it isn't ACK for SYN. Ignored\n");
287 }
288 }
289 }
290
291 // 再送処理。
292 pSender->processResending();
293 }
294
295
getInstance(void)296 SenderStateBase* SenderStateOpened::getInstance(void)
297 {
298 static SenderStateOpened s_instance;
299 return &s_instance;
300 }
301
302
getStatus(void) const303 enum SenderState SenderStateOpened::getStatus(void) const
304 {
305 return SENDER_STATE_OPENED;
306 }
307
308
updateCore(SenderImpl * pSender)309 void SenderStateOpened::updateCore(SenderImpl *pSender)
310 {
311 ASSERT(pSender!=NULL);
312
313 // 受信したセグメントの内容を調べる。
314 Segment seg;
315 if(pSender->pullSegment(&seg).IsSuccess())
316 {
317 pSender->processReceivedSegment(seg);
318
319 if(seg.IsRst())
320 {
321 // RSTだったので、CLOSEDへ。
322 pSender->setNextState(SenderStateClosed::getInstance());
323 pSender->errorHandling(ResultResetReceived());
324 return;
325 }
326 }
327
328 bool bSent = false; // 送信処理を実行したなら、trueにセットすること。
329
330 // 再送処理。
331 bSent = pSender->processResending();
332
333 // 送信処理が1回も無ければ、データ送信のチャンス。
334 if(!bSent)
335 {
336 if(!pSender->isSendBufferEmpty())
337 {
338 pSender->sendData();
339 bSent = true;
340 }
341 }
342 }
343
344
getInstance(void)345 SenderStateBase* SenderStateCloseRequested::getInstance(void)
346 {
347 static SenderStateCloseRequested s_instance;
348 return &s_instance;
349 }
350
351
getStatus(void) const352 enum SenderState SenderStateCloseRequested::getStatus(void) const
353 {
354 return SENDER_STATE_CLOSE_REQUESTED;
355 }
356
357
updateCore(SenderImpl * pSender)358 void SenderStateCloseRequested::updateCore(SenderImpl *pSender)
359 {
360 ASSERT(pSender!=NULL);
361
362 // 受信したセグメントの内容を調べる。このあたりはOpened状態と同様。
363 Segment seg;
364 if(pSender->pullSegment(&seg).IsSuccess())
365 {
366 pSender->processReceivedSegment(seg);
367
368 if(seg.IsRst())
369 {
370 // RSTだったので、CLOSEDへ。
371 pSender->setNextState(SenderStateClosed::getInstance());
372 pSender->errorHandling(ResultResetReceived());
373 return;
374 }
375 }
376
377 bool bSent = false; // 送信処理を実行したなら、trueにセットすること。
378
379 // 再送処理。
380 bSent = pSender->processResending();
381
382 if(pSender->isSendBufferEmpty())
383 {
384 // FINセグメントの送信
385 if(!bSent)
386 {
387 pSender->sendFinSegment();
388 bSent = true;
389
390 // CLOSING状態へ。
391 pSender->setNextState(SenderStateClosing::getInstance());
392 }
393 }
394 else
395 {
396 // 送信バッファのデータを掃き出し
397 if(!bSent)
398 {
399 pSender->sendData();
400 bSent = true;
401 }
402 }
403
404 // 送信処理が1回も無ければ、データ送信のチャンス。
405 if(!bSent)
406 {
407 if(!pSender->isSendBufferEmpty())
408 {
409 pSender->sendData();
410 bSent = true;
411 }
412 }
413 }
414
415
getInstance(void)416 SenderStateBase* SenderStateClosing::getInstance(void)
417 {
418 static SenderStateClosing s_instance;
419 return &s_instance;
420 }
421
422
getStatus(void) const423 enum SenderState SenderStateClosing::getStatus(void) const
424 {
425 return SENDER_STATE_CLOSING;
426 }
427
428
updateCore(SenderImpl * pSender)429 void SenderStateClosing::updateCore(SenderImpl *pSender)
430 {
431 ASSERT(pSender!=NULL);
432
433 // 再送処理。
434 pSender->processResending();
435
436 // 受信したセグメントの内容を調べる。
437 Segment seg;
438 if(pSender->pullSegment(&seg).IsSuccess())
439 {
440 pSender->processReceivedSegment(seg);
441
442 if(seg.IsRst())
443 {
444 // RSTだったので、CLOSEDへ。
445 pSender->setNextState(SenderStateClosed::getInstance());
446 pSender->errorHandling(ResultResetReceived());
447 return;
448 }
449 else if(seg.IsAck() && seg.GetAckNumber()==pSender->m_sendBuffer.GetCurrentSequenceNumber()+1)
450 {
451 // 受信したセグメントの内容を調べる。(FINチェック)
452 // FINに対するACKが返ってきたので、CLOSEDへ。
453 pSender->setNextState(SenderStateClosed::getInstance());
454 }
455 else
456 {
457 VERBOSE("セグメントは受信しましたが、FINへのACKセグメントではないようです。破棄します。\n");
458 }
459 }
460 }
461
462
463
464 ///< コンストラクタ
SenderImpl(void)465 SenderImpl::SenderImpl(void) throw()
466 :m_initialized(false)
467 {
468 }
469
470
471 ///< デストラクタ
~SenderImpl(void)472 SenderImpl::~SenderImpl(void)
473 {
474 Finalize();
475 }
476
477
478 #ifdef _WIN32
Initialize(SOCKET sock,void * pSendBuf,u16 sendBufSize)479 nn::Result SenderImpl::Initialize(SOCKET sock, void *pSendBuf, u16 sendBufSize)
480 #else
481 nn::Result SenderImpl::Initialize(u16 nodeId, u8 port, void *pSendBuf, u16 sendBufSize)
482 #endif
483 {
484 if(m_initialized)
485 {
486 return ResultAlreadyInitialized();
487 }
488 else
489 {
490 if(pSendBuf==NULL)
491 {
492 return ResultNullPointer();
493 }
494
495 if(sendBufSize==0)
496 {
497 return ResultInvalidSize();
498 }
499
500 #ifdef _WIN32
501 nn::Result result = HostBase::Initialize(sock);
502 #elif defined(NN_PLATFORM_CTR)
503 nn::Result result = HostBase::Initialize(nodeId, port);
504 #endif
505 if(result.IsFailure())
506 {
507 return result;
508 }
509 else
510 {
511 m_sendBuffer.Initialize(pSendBuf, sendBufSize);
512 m_pState = SenderStateClosed::getInstance();
513 m_pNextState = NULL;
514
515 clear();
516
517 m_initialized = true;
518 return ResultSuccess();
519 }
520 }
521 }
522
523
Finalize(void)524 void SenderImpl::Finalize(void)
525 {
526 if(m_initialized)
527 {
528 m_initialized = false;
529 m_sendBuffer.Finalize();
530 HostBase::Finalize();
531 }
532 else
533 {
534 // Do nothing.
535 }
536 }
537
538
Process(void)539 nn::Result SenderImpl::Process(void)
540 {
541 ASSERT(m_initialized);
542
543 // 状態に応じたupdate()
544 if(m_pState)
545 {
546 m_pState->update(this);
547 }
548
549 // 状態遷移
550 changeState();
551
552 // デバッグ用
553 // PrintDebugInfo();
554
555 // エラーはここで返る。
556 // 返したら、エラーはリセットする。
557 nn::Result ret = GetErrorCode();
558 errorHandling(ResultSuccess());
559 return ret;
560 }
561
562
Open(void)563 nn::Result SenderImpl::Open(void)
564 {
565 ASSERT(m_initialized);
566
567 if(GetStatus()==SENDER_STATE_CLOSED)
568 {
569 setNextState(SenderStateOpenRequested::getInstance());
570 changeState();
571 return ResultSuccess();
572 }
573 else
574 {
575 return ResultUntimelyFunctionCall();
576 }
577 }
578
579
Close(void)580 nn::Result SenderImpl::Close(void)
581 {
582 ASSERT(m_initialized);
583
584 if(GetStatus()==SENDER_STATE_OPENED)
585 {
586 setNextState(SenderStateCloseRequested::getInstance());
587 changeState();
588 return ResultSuccess();
589 }
590 else
591 {
592 // CLOSED状態の時にClose()が呼ばれたら、エラーにする。
593 // この挙動はTCPのRFCに準じているが、この挙動もここに含まれる。
594 return ResultUntimelyFunctionCall();
595 }
596 }
597
598
Send(const void * pBuf,size_t bufSize)599 nn::Result SenderImpl::Send(const void *pBuf, size_t bufSize)
600 {
601 ASSERT(m_initialized);
602
603 if(pBuf==NULL)
604 {
605 return ResultNullPointer();
606 }
607
608 if(bufSize==0)
609 {
610 return ResultDoNothing();
611 }
612
613 if(GetStatus()!=SENDER_STATE_OPENED)
614 {
615 return ResultUntimelyFunctionCall();
616 }
617
618 if(m_sendBuffer.Push(pBuf, bufSize))
619 {
620 return ResultSuccess();
621 }
622 else
623 {
624 return ResultSendBufferIsNotAvailable();
625 }
626 }
627
628
Cancel(void)629 void SenderImpl::Cancel(void)
630 {
631 ASSERT(m_initialized);
632
633 // キャンセル処理はProcess()を待たずに即座に実行することにする。
634 // エラーハンドリングを実装したサンプルプログラムを記述している最中、
635 // そのほうがアプリ側にとって使いやすいように思えたので。
636
637 // RST送信
638 sendRstSegment(m_sendBuffer.GetCurrentSequenceNumber());
639
640 // 即座にClosed状態へ。
641 setNextState(SenderStateClosed::getInstance());
642 changeState();
643
644 // Cancel()処理は必ず成功させねばならない。
645 ASSERT(GetErrorCode().IsSuccess());
646 }
647
648
GetStatus(void) const649 enum SenderState SenderImpl::GetStatus(void) const
650 {
651 ASSERT(m_initialized);
652 ASSERT(m_pState!=NULL);
653
654 return m_pState->getStatus();
655 }
656
657
processResending(void)658 bool SenderImpl::processResending(void)
659 {
660 Segment seg;
661 // タイムアウトを迎えたセグメントがキューに見つかったか、
662 // あるいはいったんそういうセグメントが見つかり、残りの
663 // セグメントを送り終えるのを待っている状態か
664 if(m_resendQueue.IsResendMode())
665 {
666 bool ret = m_resendQueue.Front(&seg);
667 ASSERT(ret);
668 VERBOSE("新・再送処理を実行します。\n");
669 VERBOSE("送信セグメントのシーケンス番号は:%dです。\n", seg.GetSeqNumber());
670 putSegment(seg);
671
672 static detail::Stopwatch s_sp("ResendQueue::TryAgain()");
673 s_sp.Start();
674 m_resendQueue.TryAgain(); // キューの先頭要素を最後尾に回す
675 s_sp.Stop();
676 return true;
677 }
678 else
679 {
680 return false;
681 }
682 }
683
684
sendData(void)685 void SenderImpl::sendData(void)
686 {
687 if(m_sendBuffer.IsEmpty())
688 {
689 VERBOSE("送信バッファはカラッポでしたので、送信処理は行いません。\n");
690 return;
691 }
692
693 u32 unackDataSize = m_resendQueue.GetTotalDataSize();
694 if(unackDataSize >= m_remoteWindowSize)
695 {
696 VERBOSE("到達未確認のデータが受信ウィンドウサイズ以上なので、データ送信は見送ります。\n");
697 return;
698 }
699
700 if(m_resendQueue.IsFull())
701 {
702 VERBOSE("再送キューが満杯なので、送信処理は行いません。\n");
703 return;
704 }
705
706 size_t vacant = m_remoteWindowSize - unackDataSize;
707 size_t pullSize = min(Segment::PAYLOAD_SIZE, vacant); // 送信バッファから引き出す量
708 ASSERT(pullSize > 0);
709
710 // 以下、データ送信処理
711 Segment seg;
712 seg.ClearHeader();
713 u32 seq = 0;
714
715 // データをセグメントに詰める処理を実行。
716 size_t sz = m_sendBuffer.Pull(seg.payload, &seq, pullSize);
717 ASSERT(sz > 0);
718
719 // ここにくるまでに、再送処理が確実に行われること(再送キューに余裕があること)などを
720 // しっかり保証しておかないといけない。
721 seg.header.dataLength = sz;
722 seg.SetSeqNumber(seq);
723 putSegmentWithResend(seg);
724 }
725
726
sendSynSegment(void)727 void SenderImpl::sendSynSegment(void)
728 {
729 Segment seg;
730 seg.ClearHeader();
731 seg.SetSeqNumber(getInitialSequenceNumber());
732 seg.SetSyn();
733 putSegmentWithResend(seg);
734 }
735
736
sendFinSegment(void)737 void SenderImpl::sendFinSegment(void)
738 {
739 ASSERTMSG(m_sendBuffer.IsEmpty(), "You cannot request FIN if send buffer is not empty.");
740
741 VERBOSE("sendFinSegment() called.\n");
742
743 Segment seg;
744 seg.ClearHeader();
745 seg.SetFin();
746 seg.SetSeqNumber(m_sendBuffer.GetCurrentSequenceNumber());
747 putSegmentWithResend(seg);
748 }
749
750
clear(void)751 void SenderImpl::clear(void)
752 {
753 m_resendQueue.Clear();
754 m_remoteWindowSize = 0;
755 #if 1
756 m_iss = static_cast<u32>(0xffffffff & GetCurrentTimeAsMillisecond());
757 #else
758 m_iss = 0xffffffff - 100;
759 #endif
760 m_sendBuffer.Clear(m_iss);
761 m_una = m_iss;
762 m_nxt = m_iss;
763
764 m_arrivals = 0;
765 }
766
767
isValidAckNumber(u32 ack) const768 bool SenderImpl::isValidAckNumber(u32 ack) const
769 {
770 s32 s32_ack = static_cast<s32>(ack);
771 s32 s32_una = static_cast<s32>(getUnacknowledgeNumber());
772 s32 s32_nxt = static_cast<s32>(getNextSequenceNumber());
773
774 // 許容ACKの不等式、snd.una < seg.ack <= snd.nxtを表現する。
775 if((0 <= s32_una - s32_ack) || (0 < s32_ack - s32_nxt))
776 {
777 return false;
778 }
779 else
780 {
781 return true;
782 }
783 }
784
785
786
787 // 状態遷移。次の状態がセットされていないなら、特に何もしない。
changeState(void)788 void SenderImpl::changeState(void)
789 {
790 if(m_pNextState)
791 {
792 if(m_pState)
793 {
794 m_pState->finalize(this);
795 }
796 m_pState = m_pNextState;
797 m_pNextState = NULL;
798 m_pState->initialize(this);
799 }
800 }
801
802
setNextState(SenderStateBase * p)803 void SenderImpl::setNextState(SenderStateBase *p)
804 {
805 ASSERT(p!=NULL);
806 ASSERT(m_pNextState==NULL);
807
808 m_pNextState = p;
809 }
810
811
putSegmentWithResend(const Segment & seg)812 void SenderImpl::putSegmentWithResend(const Segment &seg)
813 {
814 // 再送キューが満杯では、信頼性のある通信が実現できない。
815 ASSERT(!m_resendQueue.IsFull());
816
817 putSegment(seg);
818
819 // 全てのセグメントは、再送対象であることに依存している。
820 // もし、SYNセグメントを再送対象から外してしまうと、
821 // うまくいかない。
822 m_nxt = seg.GetLastSeqNumber() + 1;
823
824 // 再送キューにセグメントを入れる。
825 // 基本的に送信側は、「届いた」ことが確認できなければ、再送しなければならない。
826 // 受信側は、自分の応答が相手に届くかどうか、あまり気にしないことにする。
827 // 届いていなかったら、相手の方から何か言ってくることを期待する。
828 bool ret = m_resendQueue.Push(seg);
829 if(!ret)
830 {
831 errorHandling(ResultResendQueueIsFull());
832 PANIC("It seems that resend queue in RDT library is full.");
833 }
834 }
835
836
processReceivedSegment(const Segment & seg)837 void SenderImpl::processReceivedSegment(const Segment &seg)
838 {
839 // セグメントが到着したときに、必ず実行される処理を
840 // ここにまとめる。
841
842 ++m_arrivals;
843
844 // ACKフィールドチェック
845 if(seg.IsAck())
846 {
847 const u32 ack = seg.GetAckNumber();
848 if(isValidAckNumber(ack))
849 {
850 m_una = ack;
851
852 // 配達の確認ができたパケットは、再送キューから除去できる。
853 VERBOSE("ACK番号 %d を受け取りました。\n", ack);
854 m_resendQueue.Remove(ack);
855
856 // ウィンドウサイズ更新
857 m_remoteWindowSize = seg.GetWindowSize();
858 }
859 else
860 {
861 VERBOSE("una : %d\n", getUnacknowledgeNumber());
862 VERBOSE("nxt : %d\n", getNextSequenceNumber());
863 VERBOSE("不正、あるいは受信済みのACK番号です。(%u)\n", ack);
864 }
865 }
866 }
867
868
PrintDebugInfo(void) const869 void SenderImpl::PrintDebugInfo(void) const
870 {
871 ASSERT(m_initialized);
872
873 m_resendQueue.PrintDebugInfo();
874 m_sendBuffer.PrintDebugInfo();
875 LOG("m_remoteWindowSize: %d\n", m_remoteWindowSize);
876 LOG("m_arrivals: %u\n", m_arrivals);
877 }
878
879
PrintProperty(void)880 void SenderImpl::PrintProperty(void)
881 {
882 LOG("m_sendBuffer: %d (%d)\n", offsetof(SenderImpl, m_sendBuffer), sizeof(SendBuffer));
883 LOG("m_remoteWindowSize: %d (%d)\n", offsetof(SenderImpl, m_remoteWindowSize), sizeof(u16));
884 LOG("m_resendQueue: %d (%d)\n", offsetof(SenderImpl, m_resendQueue), sizeof(ResendQueue));
885 LOG("m_pState: %d (%d)\n", offsetof(SenderImpl, m_pState), sizeof(SenderStateBase*));
886 LOG("m_pNextState: %d (%d)\n", offsetof(SenderImpl, m_pNextState), sizeof(SenderStateBase*));
887 LOG("m_arrivals: %d (%d)\n", offsetof(SenderImpl, m_arrivals), sizeof(u32));
888
889 LOG("sizeof(SenderImpl)=%ld\n", (long) sizeof(SenderImpl));
890 }
891
892
893 // この単体テストは、Receiver抜きで実行できるテスト…を目指していたのですが、
894 // ペンディング。
Test(void)895 void SenderImpl::Test(void)
896 {
897 /*
898 const int BUFSIZE = 1024;
899 char buf[BUFSIZE];
900 SenderImpl s;
901 const int SUCCESS = 0;
902
903 CU_ASSERT(s.GetStatus()==SENDER_STATE_CLOSED);
904
905 CU_ASSERT(s.Open()==SUCCESS);
906
907 for(int i=0; i<10; ++i)
908 {
909 CU_ASSERT(s.Process()==SUCCESS);
910 CU_ASSERT(s.GetStatus()==SENDER_STATE_OPENING);
911 SleepCurrentThread(50);
912 }
913
914 CU_ASSERT(s.Cancel()==SUCCESS);
915 while(1)
916 {
917 CU_ASSERT(s.Process()==SUCCESS);
918 CU_ASSERT(s.GetStatus()==SENDER_STATE_CLOSED);
919 SleepCurrentThread(50);
920 }
921 */
922 }
923
924
925 }}} // namespace nn::rdt::CTR
926