-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathWorkREADME2.txt
2068 lines (1806 loc) · 93.6 KB
/
WorkREADME2.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Done:
=====
a) In Linux as a failed connect can take 3 or more minutes to fail, we
need to use alarm() to work around it. - check Iroffer code.
issues a alarm(TCPCONNECT_FAIL_TIMEOUT), call connect(), and reset alarm
by alarm(0)
This should be handled right in the TCPConnect class.
SIGALRM to be caught before issuing a connect().
This above method is wrong. SIGALRMs are not stackable, as a result
when a couple of threads issues the connect(), the last one is the only
one valid. Hence we shouldnt be using this alarm() method for multi
threaded connect() calls. (unless we can stack them)
For Linux, set /proc/sys/net/ipv4/tcp_syn_retries to 1 from 5.
That will solve the issue. Or for a more generic solution, make the
socket non blocking, and use select to figure out if we are connected.
So now revert back FileServerWaiting timeout to 3 minutes.
May 13th
b) In DCC Send only use DCC method if DCCServer doesnt return 151 in
previous method. Change in Helper::dccSend()
May 14th
c) For a Send if server rejects transfer if receiver requests a resume
which is greater than the file length that server has, server should
NOTICE receiver appropriately.
Analysis:
Server side all originates in Helper::dccSend()
Tracing the DCCServer transaction.
Server sends -> 120 nick filesize filename
Clients DCCServer catches this, and should reject if server filesize
is <= what client has. (ie 151, send Notice, and info in UI). Change in
DCCServerThr.cpp - done.
Tracing the DCC transaction.
Server sends -> DCC SEND filename filesize etc.
Client receives it, and should reject is server filesize is <= what
client has. (ie do not respond, but send Notice, and info in UI). Change
in DCCThr.cpp - done.
May 14th
d) Auto Update feature.
If an MM client exists in im and mc, and is op in both the channels,
then he can be assumed to run the latest MM. So for such MMs, we have a
menu item called File->Upgrade Enable. Its tickable. Default starts up
unticked. On ticking it we help upgrade. so that is from the server side.
This Check item should come up only if we are OP in both channels.
The Enable will work if the directory Upgrade exists, containing
MasalaMate.OS (OS = WIN32X86 or LINUX32X86SLES9 as of now) - done.
How do clients interact ? Note that the client could be already banned
in main. Hence wont know who the other MMs are.
One way is user initiated, Tools -> Check and Upgrade. The other is
triggered on being kicked in main.
The process is same.
Two new ICs, IC_CTCPUPGRADE = ctcp, IC_CTCPUPGRADEREPLY = its reply =
NOTICE. - done.
Client sends /ctcp UpgradeNick UPGRADE SHA FileNameto all ops in chat.
OS currently can be WIN32X86 or LINUX32X86SLES9 - done.
Trigger on being kicked in main channel. - added one more message to be
handled by UI, called *UPGRADE*. On receiving it we initiate an upgrade
process. - done
The Server on getting that ctcp replies to the CTCP only if that SHA
for that OS is different and hence needs an upgrade. The reply is in the
form of a NOTICE. It will have the SHA of the file that will be sent.
- done.
All these requests are put in a seperate Q called the Upgrade Q in server.
They are picked up every 3 minutes in TimerThr, and a dccSend initiated.
Server, then, dcc sends the MasalaMate.OS file to requestor - done.
The client on receiving the MasalaMate.OS, checks if sender is OP in chat,
is same nick as noted, same SHA as noted. same IP as noted, and within
Upgrade_Time.
If so, it moves over currently running binary as .bak. Then moves the
got one in its place. - done.
May 15th
e) Add a Tools->Request UNBAN. It should attempt an unban, and then
try to join all Channels.
May 15th
f) In "Waitings" TAB, if Q number is 0, show it as UNKNOWN.
May 15th
g) When we issue a Update Queue information on an Iroffer bot entry, present
in the Waiting TAB: If its already in Q, it sends a message as below:
*** All Slots Full, Denied, You already have that item queued.
In FromServerThr, we just catch the Denied, part and remove it from
DwnldWaiting Q. Hence it disappears. Need to correct it.
May 15th
h) BUG: In DwnldInitThr. Get/Cancel/GetPartial are not initialised every loop.
This is Major. Hence erratic behavior.
May 15th
i) BUG: Requesting a download. quitting MM -> saved in config file. Restart
MM. Entries added with partial truth (Trigger type etc are wrong). Now when
we try to rerequest or cancel them, we should remove old entry, and populate
with entry form FilesDB as it will have rest of pertinent information.
Done in DwnldInitThr().
May 15th
j) In MyFilesDB and MyPartialFilesDB we convert all path seperators to
FS_DIR_SEP. That helps in having same interface in the File Server.
Also helps in FFLC, as we transfer same FS_DIR_SEP.
Now, when actually sending a file, where we actually need to open the file
and send, we need to convert the FileName and DirNames to DIR_SEP, so
it can actally open. Add in Utilities.cpp ->
convertToFSDIRSEP(char *), will convert inplace, DIR_SEP to FS_DIR_SEP.
convertToDIRSEP(char *), will convert inplace, FS_DIR_SEP to DIR_SEP.
Convert them in File Generation, and Convert back in dccSend
Correct File Size for all files in dccSend()
May 16
k) A Queued File, when pushed, is made to take the state of ManualSend = 'M'
and a dcc send also sets ManualSend = 'M'. Both have differnt ways to arrive
at full file path. Hence a conflict. So, a DCC Send should be differentiated
from a Pushed Send. Pushed Sends should take state 'M' in ManualSend.
DCC Sends should take state 'D' in ManualSend. TimerThr, should push out
Queues at index 1, which have ManualSend 'D' or 'M'.
Path corrected properly, in dccSend and DCCServerThr 0 generating full
path considering ManualSend, DownloadState.
May 16
l) Because of above, Make an UPGRADE send, ManualSend = 'D', DownloadState =
'S'.
May 17
m) Put the fully qualified file name generation, given an FD in a Helper
function, so it can be used by workaround send and DCC Send.
The FS_DIR_SEP char is converted to native DIR_SEP in Helper::dccSend().
which then resides in DCCSendWaiting, if failed to do a workaround send.
May 17
n) Quit messages if they have MasalaMate in them, put them on. Use the "To"
field to contain the Quit Message.
May 17
o) After sorting, highlight the same line that was selected before the sort.
Change in onSearchHeaderClick(). so getCurrentItem() before search, and
identify its FD pointer. And when populating list with search, on hitting
that FD, setCurrentItem() and selectItem() and makeItemVisible()
May 17
p) Unban should just print a UI message if already present in MAIN, instead
of issuing a blind !unban.
May 17
q) Obsolete FFLC version 1. Can make code cleaner.
May 17
r) FFLC Version 3. No other versions supported.
For FFLC, as partial files are very dynamic, they should be seperately
exchanged. Currently all Serving and Partial are exchanged together.
so possibly have a seperate transaction for Partial files.
In hash generation, I think we shouldnt take into consideration file
sizes for FFLC. All we care about is file list in Serving/Partial and
their approximate sizes.
So for checksum, this is what is considered:
length of FileName, length of DirName, Total # of Files
fileinfos exchanges only Serving files from MyFilesDB
fileinfop exhanges only Partial files from MyPartialFilesDB.
Change in FilesDetailList::getCheckSums, getCheckSumString - done.
Helper::helperFServNicklist - done
Helper::helperFServStartEndlist - done
Helper::helperFServFilelist - done
Add FilesDetailList::delFilesOfNickByDownloadState(nick, dstate); - done
Add FilesDetailList::getFilesOfNickByDownloadState(nick, dstate) - done
FileServer to respond to filelists and filelistp - done
May 17
s) When uploading a file we are downloading. Transfer.upload() keeps uploading
till it cant read any more from the open file. It doesnt stop when the
initial negotiated filesize is reached. Because of this the percentages
and time left information on both the server and client are messed up
as they go by initial negotiated file size. It is good that it goes on
as much as it can. Hence we only fix the UI part.
Change in TabBookWindow::updateDownloads(), updateFileServer()
May 18
t) Add function private in TabBookWindow::saveSelection() and
restoreSelection(). These will save the highlighted items, and restore them
back, while entering and exiting the updateDownloads(), updateFileServer(),
updateWaiting() calls.
May 18
u) In sorting wrt Directory. The Partial Files (who have NULL directory),
should appear before NULL Directories. Change in FilesDetailList::
compareFilesDetail() for FD_COMPARE_DIRNAME.
May 18
v) As FD->FileSize is more than resume + bytes received -> Handled in upload.
Make it behave same way in download. So we can download more of the file
than we thought its size was and not terminate when initial negotiated
size is reached.
Change in Transfer::download(). We keep reading till socket is closed on
other end (returns -1). (return 0 => DCC timeout). So if readData returns
-1, we check how much we have downloaded. If downloaded is >= filesize
its a positve note -> download complete. If not its a failed download.
May 18 - Have to test upload/download extensively.
w) We can have one more button called: List Partials. It will list only the
partials. And we add one more check box, Ignore Partials, which can be
used to ignore the partials in listing.
ID_BUTTON_LIST_PARTIALS (button), ID_BUTTON_IGNORE_PARTIALS (Check box)
onSearchListPartials(), onSearchIgnorePartialsCheckButton()
May 18
x) Transfer.run() was closing file descriptors only on a Successul upload/
download. Later it got closed only after TransferThr exited. So moving
file in TransferThr() gave errors as file was still open. Made .run()
close it on return.
May 19th
y) After a Download/Upload run gets over, print the Upload/Download BPS at
which it was done.
Add Transfer::getAvgUploadBps(), Transfer::getAvgDownloadBps()
May 19th
z) Added a LEFT Search too.
ID_FIND_TEXT_WRAP_LEFT, ID_FIND_TEXT_WRAP_RIGHT: both handled by:
TabBookWindow::onFindNextPrevious()
May 19th
a) When cancelling a download from a non Iroffer server, currently we sleep
10 seconds in the UI. Try to remove that.
In TabBookWindow::cancelDownloadSelected(), on cancelling a Download
(non Iroffer), now we put it in the UI_ToDwnldInit Q as a CANCELD
request. Changed previous CANCEL to a CANCELQ request.
Let DwnldInitThr deal with this.
May 19th
b) On clicking on text, we do get that text up in the search UI. so if we add
a right click menu item named "Search in Files", which acts on that text
and switches to "File Search" tab. Have it in the pop up menu for the
Channel TABS.
- ID_POPUP_SEARCHTEXTINFILES
May 19th
c) Added NETWORK_NAME as "IRCSuper". In Quit messages, if NETWORK_NAME is
found then do display it.
Changed CLIENT_NAME as CLIENT_NAME_FULL
Add CLIENT_NAME as "MasalaMate"
May 20th
d) Right click -> ban incorporated as /op +b.
Manual unban = /op -b channel string
Manual ban = /op +b channel string.
May 20th
e) Change Right click -> Ban as Ban/Kick. That makes more sense.
So change it to do a ban followed by a kick.
May 20th
f) Added COUTs for file open/close - to cursorily check if all opens
are closed.
May 20th
g) Do not allow a "dcc send" to ourselves. Its stupid, and gives us a wrong
information about us being not firewalled.
May 20th
h) Add a comedy option in File Search right click popup. Call it,
"FedEx File to Home". ID_FILESEARCH_FEDEX
May 20th
i) If we get a change nick, from Server, but we have a password for the nick.
Issue a ghost command, and then attempt to take the nick again.
May 20th
j) Design Problem: On getting an Ad in main, all MMs who dont have that
nicks info will jump on it. Ex, superdude, joins and does /ad. All MMs
will issue his trigger, which is about 40 or 50 of them. This is not
right. Think on it.
Say m1 m2 m3 m4 m5 ... m40 are in channel. They are all MMs.
Say s1 enters channel and puts an ad out (say s1 is sysreset)
Assume n1 n2 n3 n4 n5 are new MMs in channel and they do not know any
other MMs.
Current algo, will make m1 thru m40, and n1 thru n5 to access s1's trigger.
Each MM has a view of the channel, with their own lists of people who are
FW or NF.
When I first join channel, I have no idea of my FW state. Nor, do I have
a list of other MMs. In this state, I should only access MM ads as they
are displayed and not Ads of other servers.
Once I have a MM list of at least 10, I can assume that I am in the group.
By this time, I am known to be NF of FW.
Once in the group, the Ad access follows the propagation algorithm.
It is still being thought off - hence ramblings -
We will distribute it as a binary propagation.
It makes sense to arrange the logical tree such that if a node is NF,
then both its children are FW preferably, unless we run out of FWs.
In the same note, if a node is FW, then both its children are NF,
compulsorily.
This above logical tree formation given the rules looks good.
The head of the tree, and another NF node are the ones responsible for
accesing all the triggers that are displayed in channel.
Once they get the file information, they send out a "propagate AdNick"
CTCP to both its children. The children on receiving the propagate
CTCP, check if they have "AdNick"'s filelist. If they do they just
keep quiet. If they dont, they issue parent's trigger and FFLC sync.
On syncing, they now in turn send out a "propagate AdNick" to their
children. This process continues, till it reaches Nick's who have the
"AdNick"'s info and stop the propagation.
Also, note that there are two parallel propagations in progress. That
will take care of failures.
This sounds good so far.
How to construct the logical tree fitting the criteria. The key is that
all MMs in the group come up with the same logical tree.
Ah !!!!! Another thought. We dont really need to construct a logical tree.
Its enough if each MM chooses its two siblings without contention and
satisfying the tree criteria. (One way is for each to construct that logical
tree)
Algorithm:
Make two arrays. ArrayNF, ArrayFW. (ascending order of Nick Names)
Go thru CHANNEL_MAIN list of Nicks. If Nick is MM and NF append it in
ArrayNF. If Nick is MM and FW append it in ArrayFW.
Note all MMs have that list in ascending order. Hence will form
the same arrays within the group.
Now we build FinalArray as below:
Pick 1st from ArrayNF, put in FinalArray[1]
Pick 1st and 2nd from ArrayFW, put in FinalArray[2], FinalArray[3].
while picking and placing in Final Aray, just follow the two rules:
Rule 1: If node is NF, 1st priority -> get FW children. If FW children
not available, then get NF children.
Rule 2: If node is FW, only NF children. If NF children not available
then no children.
This forms the first tree.
For the second tree. Make two arrays ArrayNF and ArrayFW with
descending order of Nick Names. Generate tree using same procedure as
above.
Hence we have two trees.
The head of these two trees are the actual trigger accessers in
CHANNEL_MAIN.
PROBLEM: As tree gets bigger, it needs considerable more number of
NF clients for it to be effective. Basically all odd levels in the
tree consist of entirely NF MM clients. Hence to fill the 5th level
we need about 32 NF clients, etc. Hence a different strategy.
STRATEGY 2:
-----------
Assume the same NFArray and FWArray.
The FW Array consists of FWs and UNs too.
Two such arrays, one in ascending order, and one in descending order,
to get the two trees for redundancy.
Now the NFArray guys are a binary tree in themselves.
So NF1 is parent of NF2 and NF3 etc.
Hence NF1 gets trigger, propagates to NF2, NF3, who then propagate to
NF4, NF5, NF6, NF7, NF8 etc.
Parallelly, the same thing holds for the descending order list. NFlast
gets the trigger, propagates to its children etc.
During propagation, each NF node also propagates to 2 of its corresponding
FW children. Hence each NF node tries to propagate to 4 MM clients.
2 of which are MM NF clients. The other 2 are MM FW clients.
A MM client who is FW, does not propagate further.
This algorithm looks simpler and cleaner.
IMPORTANT: if this algo is in place, FFLC should not increment the update
count during exchanges.
Implementation: (Propagation Algorithm)
===============
IRCNickLists class additions:
- Note FW => FW or UN or MB in the Firewall state.
IRCNickLists.getFWMMcount(chan) // FW MM count (includes UN/MB/FW) - done
IRCNickLists.getNFMMcount(chan) // NF/UN MM count. - done
IRCNickLists.getNickFWMMindex(chan) // My FW MM index. - done
IRCNickLists.getNickNFMMindex(chan) // My NF MM index. - done
We already have functions to get our FW state ::getNickFirewall(chan,nick)
Once we know our index and state, if we are NF category,
We need to propagate to 2 NFs and 2 FWs. We use below to get them.
IRCNickLists.getNickInChannelAtIndexFWMM(chan, index, nick) - done
IRCNickLists.getNickInChannelAtIndexNFMM(chan, index, nick) - done
Write test cases for the above functions - done.
Algo:
FWcount = getFWMMcount(), NFcount = getNFMMcount()
MyFWIndex = getMyFWMMindex(), MyNFIndex = getMyNFMMindex()
returns 0 if not fitting NF or FW.
so one of them is valid.
ToTriggerThr algo:
For an Ad seen in main ->
If I am NF and first or last guy in list.
if (MyNFIndex == 1) || (MyNFIndex == NFcount) catch triggers.
If NFcount == 0, catch triggers. // no trigger catcher in group.
if (NFCount == 0) catch triggers.
// End of trigger catching for an ad seen in main - done.
On receiving a Propagate CTCP.
Do I have the PropagateNick's files in FilesDB with update count = 0
if yes, ignore.
if no, issue trigger of the guy who sent us the Propagate CTCP.
All triggers issued automatically (not manual triggers)
now need to be propagated, when the listing has been got.
ToTriggerThr -> when it issues the trigger, does add the
FileList in the FServPending Q. We could add a marker there
to identify it as a list to be propagated, on Dir listing
being obtained. so its called PropagationNick. We note down
in that field, which Nick's dir is trying to be propagated.
New field added called PropagatingNick in FilesDetail.
It is used in the FServPending Queue. So in ToTriggerThr()
if we issue a trigger (cause of ad in main), we mark that nick's
Ad that we see in PropagatingNick. DCCChatThr, when it has
finished getting the listing, will check if PropagatingNick was
set for this Fserv dir listing access. If it was, it will generate
4 propagation ctcps as described below.
Implementation:
- Add PropagatingNick in FilesDetail - done.
- Change copy/freeFilesDetail to take care of it - done.
- set PropagatingNick in ToTriggerThr() (Q'd in FServPending) - done.
Once DCCChatClient gets the listing and its marked as a propagate
listing. PropagationNick = Nick whose listing is got, we do ->
MyNFIndex = getMyNFMMindex()
if we are not NF then do nothing. end of story.
My NF children are 2 * MyNFIndex, 2 * MyNFIndex + 1
MyNFChild1 = getNickInChannelAtIndexNFMM(chan, 2 * MyNFIndex);
MyNFChild2 = getNickInChannelAtIndexNFMM(chan, 2 * MyNFIndex + 1);
My second tree (backward) children are:
SecondMyNFIndex = NFCount - MyNFIndex + 1;
SecondMyNFChild1 = NFCount - (SecondMyNFIndex * 2) + 1;
SecondMyNFChild2 = NFCount - (SecondMyNFIndex * 2 + 1) + 1;
My FW children are 2 * MyNFIndex - 1, 2 * MyNFIndex.
MyFWChild1 = getNickInChannelAtIndexFWMM(chan, 2 * MyNFIndex - 1)
MyFWChild2 = getNickInChannelAtIndexFWMM(chan, 2 * MyNFIndex)
/ctcp MyNFChild1 PROPAGATION PropagatedNick
/ctcp MyNFChild2 PROPAGATION PropagatedNick
/ctcp MyFWChild1 PROPAGATION PropagatedNick
/ctcp MyFWChild1 PROPAGATION PropagatedNick
(if the nicks are valid, that is) - done.
Now its left to the children to do whatever.
NOTE: The Propagation ctcp should also send our current sends/queue
information, as the child on receiving it will issue our trigger,
and ToTriggerThr(), needs to put it in its TriggerTemplate.
As ToTrigerThr() takes the help of TriggerParse class, we need to
make TriggerParse class handle the propagation ctcp.
Action on receiving a /ctcp PROPAGATION PropagatedNick (handled
by ToTriggerThr)
Check if we already have that Nicks info with update count 0.
If we dont, We issue the trigger, and attach PropagatedNick
That covers everything !
Implementation:
Add IC_CTCP_PROPAGATE for recognising a PROPAGATION ctcp. - done.
FromServerThr() to feed it to ToTriggerThr() - done.
ToTriggerThr() to ask TriggerParse class to decipher it. - done
So make TriggerParse class to recognize the PROPAGATION line.
"FromNick PROPAGATION PropagatedNick Sends TotSends Qs TotQs"
- done.
Make ToTriggerThr() to handle the PROPAGATECTCP along with FSERVCTCP
- done.
So in FFLC UpdateCount is transferred as is - no more increment by 1 - done
In ToTriggerThr(), if CTCPPROPAGATION, we do not issue trigger if
UpdateCount <= 1 of the nick which is trying to be propagated => we
just got it and possibly just propagated.
May 21st
k) Linux upgrade needs to set S_IRWXU | S_IRWXG on the upgraded binary.
May 22nd
l) In quit message for "Be Right Back", remove ':' if present as MM gives till
first received :
May 22nd
m) DCC sends do not succeed if the Nick is not present in CHANNEL_MAIN. Moved
this check to Helper::dccSend(), from TransferThr(). Added a UI message
in server tab, to let the sender know the reason for the failure.
May 22nd
n) Code walk thru - setNickFirewall() for our own Nick.
setNickFirewall(), called in many places, redundantly. Its called
erroneously in DCCThr.cpp
setNickFirewall() should be called for our own nick in DCCServerThr()
only. - checked and this was correct.
May 22nd
o) In DCCThr() after connecting to users dccserver, we do not check if
it connected and returned 151, in which case we shouldnt try the
dcc method. (Like Helper:dccSend())
May 22nd
q) Code walk thru - setNickFirewall() for remote Nick
setNickFirewall() should be called for remote nick in DCCThr().
when it connects to remote nicks DCCServer - done.
In DCCChatThr, we mark remote nick as not firewalled, on a successful
transaction with DCCCHatClient class. Hence change DCCChatClient
class to return bool indicating success/failure - done.
Helper:dccSend(), when we successfully connect to remote nicks
dccserver. - this wasnt in place - done.
May 22nd
r) Added temp code to print Propagation algo decisions in channel.
Code under #define DEBUG in ToTriggerThr() and DCCChatThr()
May 22nd
s) Propagation algo Tweak:
If PropagatedNick is our own nick - dont do it. (receiver - ToTriggerThr)
- done
Dont send a propagation to a nick for its own nick. (sender - DCCChatThr)
happens when I get listing of that nick and that nick is my child - done
May 22nd
t) In FFLC, we update fw_state only if we have the state as UNKNOWN.
But with chimero, someone is finding him to be NF when he infact is
firewalled. Debug ...
OK bug in DCCChatThr, marking a success chat as NF. It should mark if succes
and an outgoing (no ndccserver) connection.
May 22nd
u) If I change a nick and I have a password, it refuses to change it.
Bug introduced. - fixed.
May 22nd
v) The Upgrade algo messages all ops in Chat. This generates lof of messages,
which the serverblocks from the sender. Hence upgrade ctcp never reaches
the Upgrade server for some users. Hence differnt strategy.
We assign a nick, say "UpgradeMM" which will be the upgrade sever.
To get upgraded, we check if UpgradeMM is present in CHANNEL_CHAT and
is an op. We message it for an upgrade request. The Upgrade Server,
should also respond to indicate that no upgrades are required.
May 22nd
w) Changed Ad to have CLIENT_NAME_FULL.
May 23rd
x) Rollback Truncate File crashes.
May 23rd
y) UI to handle these *UPGRADE* messages:
*UPGRADE* TRIGGER <- handled by triggerUpgrade(bool);
*UPGRADE* DONE <- handled by upgradeDone()
*UPGRADE* NOTREQUIRED
*UPGRADE* NOUPGRADER
So we change upgradeDone() to upgradeNotify(), which then handles all
the 3 notification messages.
May 23rd
z) DCCServerThr(), we forgot to mark ourselves as not firewalled in getting
an incoming DCCServer connect for CHAT and SEND.
So the marking ourselves as not firewalled should also be moved to the
DCCChatThr() if CHAT, using our dccserver.
We accept all SENDS so can do that in DCCServerThr itself
Corrected it.
May 23rd
a) In Helper::dccSend(), we stop sends if Nick is not in Channel Main,
we should allow sends of the files which start with CLIENT_NAME though,
as it could be a trace file or Upgrade file.
May 23rd
b) Multiple items selected in SearchUIs crashes Client.
saveSelections had sel_number declared inside for loop, and initialised
to 0. -> for (...) { int sel_number = 0; ... }
Hence sel_number remained 0 in the loop each time it looped. Saving
all values only in the first entry. All the rest remained as garbage.
May 24th
c) filelist followed by small 'p' was returning serving list.
Changed to make it case insensitive.
May 24th
d) Put Left arrow before Search Text
May 24th
e) Rename "Search for Text in Files" to "Search in Files"
May 24th
f) Quit message can have ':' in it. Changed IC_QUIT processing.
May 24th
g) Moved deletion of OnlyOneSem to end of IRCClient.cpp, after endit(),
so that it is deleted only when client ends fully.
May 24th
h) Memory leak of FD->PropagatedNick fixed, which were not getting deleted.
Changed FilesDetail to call freeFilesDetailList() instead of deleting
the individual FD elements in exception conditions.
Removed Mutex protection inside freeFilesDetailList() as it wasnt
required.
May 24th
i) Got a SIGABRT crash which makes me think it was from FOX. Last FOX function
called was addToNickList(). so added a TRACE before and after it accesses
NickList->insertItem(). And looking at channel log, he crashed immediately
after mickey_mouse entered channel:
[15:53] * mickey_mouse ([email protected]) has joined #MasalaMate
[15:53] * h_u_l_L_a ([email protected]) Quit (Read error: Connection reset by peer)
Note: The last call before crash was TCPConnect::readData()
May 24th - open debug.
--- Released --- May 25th Version.
j) Propagation CTCP flood: If I see the Ad of Nick. It gets kicked. I access it
and send propagation to my children. They access my nick to get the
propagated nick's list. But I dont have any as the nick quit. So they send
out propagation in turns, and no one has it. And it comes back to me, and
I still dont have it. Endless loop. Hence, change as follows:
Firstly, chekc if nick is in channel before issuing trigger.
Secondly, if propagated nick is not in channel, dont issue trigger.
Thirdly, if a propagation CTCP, then at end of transaction, propagate
only if we indeed got the listing of the Propagated Nick.
First, Second taken care of in ToTriggerThr()
Third, taken care of in DCCChatThr()
--- Released --- May 26th Version - CVS Release tag = Beta26May2005
k) In Linux, alphakaya's server stops responding to new CHAT/FSERV/SEND etc
after a couple of hours. Basically new threads stop being spawned.
Possibly pthread_create() failing. We are creating threads, but not
pthread_join(), and the threads are non detached. Hence suspected thread
leakage in linux build. Have to explicity set pthread_attr and set the
state to detached_state before pthread_create for DCCChatThr, FileServerThr,
TransferThr. Changes in files: DCCServerThr.cpp, DCCThr.cpp, Helper.cpp.
Jul 13
--- Linux patch Release --- May 26th version
l) In above build, DCCServThr.cpp, had a misplaced '{' in the #ifdef
for the pthread_create() modification. Corrected that.
Jul 16
m) In Makefile added -lpthread for building StackTraceTest else it wasnt
working properly for Linux build.
Jul 16
n) Use backtrace() from execinfo.h for Linux port in StackTrace class,
to print the stack trace.
Jul 16
o) Change Makefile to generate map file for PRODUCTION build for the
UIClient, which can be used to get function name with the trace file.
Jul 16
p) Create a simple stacktrace() in MINGW version too. Added getfp() and
mingw32BackTrace(), in StackTrace.cpp. This doesnt work correctly as
of now. Before the signal, the stack is nice. Looking at the stack
in the signal, it just ha scurrent signal handler information alone.
This possibly could be a bug in gcc 3.4.2 for mingw port. As of now,
I do not see any way around it. Has to be revisited later.
Jul 16
q) In the Trace output, TRACE() macro, include the thread id too, so its
easy to find which line belongs to which thread. Hence for now, we
just call the function to get thread id, and hope not much of a performance
hit.
Jul 17
r) Some people have problem connecting out to port 6667. So we replicate
same server, one with port 6667 and the other with port 6665.
Jul 17
s) We respond to @find in chat channel - bug, we shouldnt.
Jul 17
t) In LINUX, spawn konqueror or nautilus to open the Partial Dir and
Serving Dir.
Jul 17
u) Make traces be saved in Serving Directory/Crash. We modify class
StackTrace to have a member -> setTraceDir(char *), which can be
set at application start, and whenever "set Serving Dir", is invoked.
We choose Serving Dir, as it is accessible from all clients.
Jul 17
v) Added Thread ID prints with the type of signal in the header of the
Trace file.
Jul 18
w) SEGV on exit in Linux, in WaitForThread(DCCChatThrH) in DCCServerThr().
Dont know why ?, but on Linux, threads are created detached, so that
pthread_join(), is errorneous anyway. So possibly put those waits,
under an #ifdef __MINGW32__. But nonetheless, they shouldnt core dump.
So possibly do this, for the non-detached threads created in
DCCServerThr.cpp, DCCThr.cpp, TimerThr.cpp (Helper.cpp)
Jul 19
x) DEBUG build in DCCChatThr.cpp, the NF tree and FW tree is not printed
at all - BUG
Jul 19
y) To not hog all bw, force socket buffer to 8192. We used to have it at
65535. Testing with alpha. - No good. So will take it off, and revert
it to 65535.
Jul 20
z) When we restart MM, it tries to send files as soon as we connect to IRC
server, but we havent yet got the nicklist. Hence the first nick which
should have got the send is disqualified, saying not in channel.
We need to delay more before attempting the first send as soon as we
join channel.
Changed TimerThr.cpp, so that it attemtps to send only if its been
at least 10 seconds since CHANNEL_MAIN was joined.
Jul 20
a) Record Upload/Download should be reset each time we restart MM.
This should not be saved in the Config File. As of now, it still saves
and reads from the config file. But we reset it to 0, as soon as we
read it from the config file.
Jul 20
b) Problem of TCPConnect class being piggy backed in FilesDetail, for the
sole purpose of getting its Download/Upload BPS. We introduced some
clumsy global locks and TCPConnect class pointers to keep track of
validity etc, which still had room for errors.
So a rework. We remove all the above. Make the individual threads
responsible for updating the FilesDetail for the corresponding
upload/download to reflect the correct data.
TransferThr is the thread we are talking about. It uses the Transfer
class to do the actual transfer. Transfer class also has access to
XGlobal and Nick/FileName, so it can directly update the correct
FilesDetail once in two seconds, which will be ideal.
New function to handle this Transfer::updateFilesDetail(bool dwnld);
Added one more function in FilesDetailList class called
FilesDetailList::updateFilesDetailNickFileConnectionDetails()
which will be used by Transfer::updateFilesDetail();
Remove the Connection related dirty copy in FilesDetailList::copyFiles...()
Once we are done with this, remove all the TCPConnect class static ptr
storage related code and mutex out.
Also remove the IRCClient, calling Connection->closeSocket() etc.
We have to change Transfer:: class, such that it gracefully exits
on checking XGlobal->isIRCQuit().
We still need the Connection in the FilesDetail structure.
This is used in disconnecting transfers if a nick leaves the channel
etc. Also for disconnecting the FileServer in progress, when exiting.
July 20
c) In Linux, issuing a get from a subdirectory of another server doesnt
update the q information correctly. This is cause the fully qualified
name of the file is in WINDOWS format, and we use getFileName() to
extract the filename. So add one more function in Utilities.cpp called
getWindowsFileName(), and use that call instead.
Jul 20
d) Downloads are always showing 100 %, when still in progress.
FilesDetailList::copyFiles...(), should still copy the Connection
pointer over.
Jul 20
e) An @find, !list did not have the preceding Nick Mode of the Nick
which was saying it.
Jul 21
f) Implement MaxUploadBps and MaxDwnldBps. These are per class CAPS.
Changes in class TCPConnect for there. For this to interact with
the application, we can have a XGlobal->... under the same names,
and let the TransferThr, update the TCPConnect classes at initial
and intermediate changes.
For per socket cap, we do the actual write call in sizes of the actual
cap/2 if write size is greater than cap/2
Same holds true for the read calls.
Tested the sends/gets.
Note - If I am downloading, then, the last packet loops in the select
call, and returns only after timeout is reached. Hence the end
game takes 3 minutes, from 99 % to COMPLETE. So, in the select
call we wait 1 second, and return if no data within that time,
only for readData()
Added TCPConnect::maxUploadBpsSleepTillOKToSend(), and
TCPConnect::maxDwnldBpsSleepTillOKToSend().
We can possibly add another check in these functions to make sure
that they dont sleep for more than a second.
July 22
h) Implement OverallMaxUploadBps and OverallMaxDwnldBps in TCPConnect class.
Made functions common to both per object CAP and class wide CAP.
July 22
i) CAP testing.
Now have to add commands for testing, like:
/cap upload each <value>
/cap upload all <value>
/cap download each <value>
/cap download all <value>
For these, changes in TabBookWindow.cpp
Also we update the cap values in XGlobal. Hence it too needs those
variables in there.
Also, Transfer.cpp, in upload() and download(), periodically scans the
XGlobal CAP variables and updates its settings. New function for that
called Transfer::updateCAPFromGlobals(). We call this in upload()
and download().
July 22
j) For IRCClient::endit() to end cleanly, rather than leaving the download
and upload hanging -> We keep monitoring the corresponding FilesDetail
till it gets to be empty. As the Transfer, does check for IRCQuit() and
exits.
July 22
k) For the CAP, have another variable which controls what all are CAPed.
For example, if I set a download CAP of 40000. Then an upload that is
going on, and if the download is at max, then it will get delayed in
trying to send the Ack, for waht it has received. Hence affecting
it.
Hence, by default, we do not monitor CAPing. We have to explicitly
do a call to TCPConnect::monitorForDwnldCap() and
TCPConnect::monitorForUploadCap(). With this we selectively
cap the corresponding down/up objects.
July 23
l) Make CAPs be 0 or > 511 for sanity. Corrected in both Global interface
thru /cap command and in TCPConnect class.
#define MIN_CAP_VALUE_BPS as 511
July 23
m) BUG: In the FileServer, when a nick queued for a file, and it was a nick
which had priority, we would enqueue before that nick. We should have
added ourselves, after the last of the priority holding nicks.
Made such that op gets earlier q position than voice etc.
July 23
n) BUG: FileServer::requeueTransfer() had a bug in which a file from a sub
directory would fail to requeue.
July 23
o) BUG: FileServer::fservDir(), lists only the first Directory, if
more than one directory exist like: Vision1, Vision2. In this case
it lists only Vision2. Note that CD to Vision1 does work.
Change in FileServer::fservCD(), str_index was 1 short.
July 23
p) People want to add Serving Directories across drives etc.
Hence suggestion is, to have a Dir -> Add Serving Dir.
Each time we Add, it will appear in the Dir menu, as:
Dir -> Open Serving Dir<n> etc.
To keep it simple we can have a fixed max of 4 dirs.
#define FSERV_MAX_SERVING_DIRECTORIES
Added char *XChange::ServingDir[4], for this purpose.
Change Helper::readConfigFile(), to read in ServingDir<1..4>
Change Helper::writeFServeConfig, to write in ServingDir<1..4>
So while generating the filelist, in Helper::recurGenerateMyFilesDB,
we need to remember which ServingDir the filename is associated with.
So have to add a field called ServingDirIndex in FilesDetailList
to hold 0 ... 3. Changed also FilesDetail::printDebug and
FilesDetail::copyFilesDetail()
change in Helper::generateMyFilesDB() to call the recur guy with
the index number too.
Hence if DownloadState = 'S' then use the ServingDirIndex to get
base dir in MyFilesDB entries.
Now hunt for all other occurances of ServingDir, to use the index.
GUI visual change:
DIR ->
Update Server
Open Partial Dir
Set Partial Dir
Open Serving Dir ->
Dir 1
dynamic Dir 2
dynamic Dir 3
dynamic Dir 4
Set Serving Dir ->
dynamic Dir 2
dynamic Dir 3
dynamic Dir 4
UnSet Serving Dir ->
dynamic Dir 2
dynamic Dir 3
dynamic Dir 4
July 24
q) Record BPS should be when a download/upload completes and more than
1 MB is transferred. Hence the XGlobal->RecordUploadBPS and
XGlobal->RecordDownloadBPS, should be updated in TransferThr and Transfer
once it finishes the transfer. Remove the 5 second call to
Helper::updateRecordBPS from TimerThr. Also get rid of
Helper::updateRecordBPS.
#define MIN_BYTES_TRANSFERRED_FOR_RECORD 1048576
July 24
r) Manual sending file to Chimero, on DCC timeout, its not requeueing.
That file does exist in the serving folders.
Ok, so we get File and Dir information from SendsInProgress, and use that
to get the FD from FilesDB. As its manual send, the Dir doesnt match,
and hence it returns NULL. What we should do is, use the FD we get
from SendsInProgress and use that to add it in QueuesInProgress,
initialising values like Connection etc.
Also, if the FD is a Manual Send, we should queue it in Q 1 so that it
auto resends.
July 25
s) File Server should have a configurable retry option on a send failure.
As of now we put it in q 2 if there is 1 member in q. But if there is
no one in q, we just discard the send. Someway to make it send again
without making it send indefinitely. (Example, rollback error related)
We can add a SendRetry field in FilesDetail for this purpose. Each time
it resends/requeues we keep increasing this.
Change in TimerThr, in which it delays 1 minute before resending if its
RetryCount is non zero.
July 25
t) When a DCC Send File gets in Q cause of a retry, and we select it and
try to Push it, in TabBookWindow, we mark it as of type 'M', and hence
the fullyqualified name gets messed up as the Serving Directory is
also prepended to get full file name. Hence, before we mark a file push
as 'M', check if its of type 'D'. If it is, leave type as is.
July 26
u) Trying to get file from arun200401. We get "Error writing to Socket."
message from him in a few seconds. Download goes nowhere.
TCPConnect::writeData(), possibly has to check for failure on the
select() call and the send() call. Check for EAGAIN is not being
done.
Added private function TCPConnect::errorNotOK()
this will return true if the failure is not OK to be retried.
July 26
v) Sends that are in progress, when we quit are lost and not saved in the
config file to be restarted the next time we restart.
This is because, on seeing isIRC_QUIT() (in Transfer.cpp), we return
without requeuing it in QueuesInProgress. On return, TransferThr.cpp
removes it from the SendsInProgress Queue. Hence lost.
July 26
w) CRASH: FromServerThr, closes the FD->Connection. Some other thread using that
same Connection, is inside writeData or any other functions, which expects
sane values for Sock. But already Connection is disconnected, and hence
Sock = SOCK_UNUSED = ~0. It then calls the select call with fd, which
crashes.
Hence, we should seriously consider removing the "Connection" from
FD, and instead have something called TCPConnectMessage which is char.
In Transfer::updateFilesDetail, as we update FD, we also check if the
FD is telling us to shut down the transfer. In this case, we close socket.
So we make updateFilesDetail return false, when connection closed, and
true otherwise, so that the caller is warned not to use Sock etc.
Note that we need to implement same mechanism in discoing for FileServer
too.
DwnldInitThr uses Nick, File to get FD. (cancelling a download)
FromServerThr uses Nick to get FD. (cancelling all sends to nick)
TabBookWindow can use Nick, File to get FD. (cancelling an xdcc download)
So for the above, we need to add functions in FilesDetail class:
updateFilesDetailAllNickConnectionMessage(Nick);
updateFilesDetailNickFileConnectionMessage(Nick, File);
These return true if update performed, else return false.
FileServer will need to have a function where it monitors the IRCQuit()
message and disconnects.
Changed FileServer.run(), FileServer.fservDir(), FileServer.Sends(),
FileServer.Queues()
Also have to change Helper::fservRecvMessage(), so that it returns
false on QUITing client, as its used by Helper::helperFServFilelist()
and Helper::helperFServNicklist()
July 27
x) Have to serialise MM to MM Serving list exchanges. This will make them
have better list maintenance, and will prevent stepping on each other.
This is part of the Propagation Algo tweak.
This involves Helper::helperFServFilelist() and
Helper::helperFServNicklist().
Case study: Say there are more than one FFLCs in progress. Lets consider
the filelist of Nick1.
say A, B, C have Nick1's list and each have a different checksum =>
Nick1's file list will be exchanged. Now say A has the least update count,
=> B and C want A's copy. While A's info is being update by B and C, say
D and E are transacting with B, then B will propagate 1/2 ass file list
information to D and E, each being different, depending on where the
transaction with A was at that time.
Hence a NickList exchange is OK => need not be serialised.
We need to serialise the FileList exchange in FFLC. Hence as of now,
seems like we need to serialise the functions which respond to a
FILELIST command and the function which receives the response for
FILELIST command.
We create a MUTEX in XChange class, and call it FFLC_Mutex, and use
that to serialise. Functions in XChange, to lock and unlock it.
XChange::lockFFLC(), XChange::unlockFFLC()
Lets try by locking the full nicklist/filelist transaction.
Also make no TimeOut for FilesDB
FileServer::fservNicklist(), FileServer::fservFilelist(),
Helper::helperFServStartEndlist() have been locked.
July 27
y) BUG: memory freed twice error in Helper::helperFServStartEndlist()
tmp_str was nont NULLed and in case where it broke of first do {, before
tmp_str got allocated, it would free that pointer. Hence LeakTracer
aborted.
Jul 30
z) We should possibly remove the "time to live" for FilesDB, and
make it 0. Flush possibly occurring only cause of UpdateCount.
This is part of the Propagation Algo tweak.
Jul 30
a) The FServ Ad doesnt prepend our Nick Mode, while displaying in UI.
Its generated by Helper::generateFServAd(), called from TimerThr.cpp
and FromServerThr.cpp. The FromServerThr() one is basically a NOTICE