2121from .TftpPacketTypes import *
2222from .TftpShared import *
2323
24+ if TYPE_CHECKING :
25+ from .TftpContexts import TftpContext
26+
27+
2428log = logging .getLogger ("partftpy.TftpStates" )
2529
2630###############################################################################
@@ -35,7 +39,7 @@ def __init__(self, context):
3539 """Constructor for setting up common instance variables. The involved
3640 file object is required, since in tftp there's always a file
3741 involved."""
38- self .context = context
42+ self .context = context # type: TftpContext
3943
4044 def handle (self , pkt , raddress , rport ):
4145 """An abstract method for handling a packet. It is expected to return
@@ -50,6 +54,9 @@ def handleOACK(self, pkt):
5054 log .info ("Successful negotiation of options" )
5155 # Set options to OACK options
5256 self .context .options = pkt .options
57+ tsize = pkt .options .get ("tsize" )
58+ if tsize :
59+ self .context .metrics .tsize = tsize
5360 for k , v in self .context .options .items ():
5461 log .info (" %s = %s" , k , v )
5562 else :
@@ -112,6 +119,7 @@ def sendDAT(self):
112119 dat .data = buffer
113120 dat .blocknumber = blocknumber
114121 self .context .metrics .bytes += len (dat .data )
122+ self .context .metrics .packets += 1
115123 # Testing hook
116124 if NETWORK_UNRELIABILITY > 0 and random .randrange (NETWORK_UNRELIABILITY ) == 0 :
117125 log .warning ("Skipping DAT packet %d for testing" , dat .blocknumber )
@@ -122,7 +130,7 @@ def sendDAT(self):
122130 )
123131 self .context .metrics .last_dat_time = time .time ()
124132 if self .context .packethook :
125- self .context .packethook (dat )
133+ self .context .packethook (dat , self . context )
126134 self .context .last_pkt = dat
127135 return finished
128136
@@ -175,6 +183,7 @@ def resendLast(self):
175183 assert self .context .last_pkt is not None
176184 log .warning ("Resending packet %s on sessions %s" , self .context .last_pkt , self )
177185 self .context .metrics .resent_bytes += len (self .context .last_pkt .buffer )
186+ self .context .metrics .resent_packets += 1
178187 self .context .metrics .add_dup (self .context .last_pkt )
179188 sendto_port = self .context .tidport
180189 if not sendto_port :
@@ -186,9 +195,10 @@ def resendLast(self):
186195 self .context .last_pkt .encode ().buffer , (self .context .host , sendto_port )
187196 )
188197 if self .context .packethook :
189- self .context .packethook (self .context .last_pkt )
198+ self .context .packethook (self .context .last_pkt , self . context )
190199
191200 def handleDat (self , pkt ):
201+ # type: (TftpPacket) -> TftpState
192202 """This method handles a DAT packet during a client download, or a
193203 server upload."""
194204 log .debug ("Handling DAT packet - block %d" , pkt .blocknumber )
@@ -202,6 +212,7 @@ def handleDat(self, pkt):
202212 log .debug ("Writing %d bytes to output file" , len (pkt .data ))
203213 self .context .fileobj .write (pkt .data )
204214 self .context .metrics .bytes += len (pkt .data )
215+ self .context .metrics .packets += 1
205216 # Check for end-of-file, any less than full data packet.
206217 if len (pkt .data ) < self .context .options ["blksize" ]:
207218 log .info ("End of file detected" )
@@ -354,6 +365,7 @@ def handle(self, pkt, raddress, rport):
354365 tsize = str (self .context .fileobj .tell ())
355366 self .context .fileobj .seek (0 , 0 )
356367 self .context .options ["tsize" ] = tsize
368+ self .context .metrics .tsize = tsize
357369
358370 if sendoack :
359371 # Note, next_block is 0 here since that's the proper
0 commit comments