@@ -30,6 +30,7 @@ class << self; attr_accessor :hop_handlers end
30
30
attr_accessor :mclient # :nodoc:
31
31
attr_accessor :current_url # :nodoc:
32
32
attr_accessor :control # :nodoc:
33
+ attr_accessor :refs # :nodoc:
33
34
34
35
#
35
36
# Keeps track of what hops have active handlers
@@ -63,27 +64,33 @@ def setup_handler
63
64
#
64
65
def start_handler
65
66
uri = URI ( full_uri )
66
- #Our HTTP client for talking to the hop
67
+ # Our HTTP client for talking to the hop
67
68
self . mclient = Rex ::Proto ::Http ::Client . new (
68
69
uri . host ,
69
70
uri . port ,
70
71
{
71
72
'Msf' => framework
72
73
}
73
74
)
74
- #First we need to verify we will not stomp on another handler's hop
75
+ @running = true # So we know we can stop it
76
+ # If someone is already monitoring this hop, bump the refcount instead of starting a new thread
75
77
if ReverseHopHttp . hop_handlers . has_key? ( full_uri )
76
- raise RuntimeError , "Already running a handler for hop #{ full_uri } ."
78
+ ReverseHopHttp . hop_handlers [ full_uri ] . refs += 1
79
+ return
77
80
end
81
+
82
+ # Sometimes you just have to do everything yourself.
83
+ # Declare ownership of this hop and spawn a thread to monitor it.
84
+ self . refs = 1
78
85
ReverseHopHttp . hop_handlers [ full_uri ] = self
79
86
self . monitor_thread = Rex ::ThreadFactory . spawn ( 'ReverseHopHTTP' , false , uri ,
80
87
self ) do |uri , hop_http |
81
88
control = "#{ uri . request_uri } control"
82
89
hop_http . control = control
83
90
hop_http . send_new_stage ( control ) # send stage to hop
84
- @finish = false
85
91
delay = 1 # poll delay
86
- until @finish && hop_http . handlers . empty?
92
+ # Continue to loop as long as at least one handler or one session is depending on us
93
+ until hop_http . refs < 1 && hop_http . handlers . empty?
87
94
sleep delay
88
95
delay = delay + 1 if delay < 10 # slow down if we're not getting anything
89
96
crequest = hop_http . mclient . request_raw ( { 'method' => 'GET' , 'uri' => control } )
@@ -135,7 +142,11 @@ def start_handler
135
142
# Stops the handler and monitoring thread
136
143
#
137
144
def stop_handler
138
- @finish = true
145
+ # stop_handler is called like 3 times, don't decrement refcount unless we're still running
146
+ if @running
147
+ ReverseHopHttp . hop_handlers [ full_uri ] . refs -= 1
148
+ @running = false
149
+ end
139
150
end
140
151
141
152
#
0 commit comments