def advertise_to_DNS(unique_id): """ Advertise unique_id to the zenodotus DNS server. We strip away whatever that follows the NAME_SERVER part of the unique_id. For instance, if our unique_id is abc.NAME_SERVER:1234@xyz, then we only advertise abc.NAME_SERVER. """ # IP that maps to the unique_id myip = emulcomm.getmyip() # Extract the part of unique_id up to the name server, # i.e. xyz.zenodotus.washington.edu, and discard whatever that follows name_server_pos = unique_id.find(NAME_SERVER) if name_server_pos > -1: unique_id = unique_id[0 : name_server_pos + len(NAME_SERVER)] else: raise Exception("Invalid unique_id format: '" + str(unique_id) + "'") advertise_success = False # We keep trying until successful advertisement (Fix for Ticket #956) while not advertise_success: try: advertise_announce(unique_id, myip, DNS_CACHE_TTL) servicelogger.log("[INFO]: Advertised " + str(unique_id) + " which maps to " + myip) advertise_success = True except Exception, error: if 'announce error' in str(error): # We can confidently drop the exception here. The advertisement service # can sometimes be flaky, yet it can guarantee advertisement of our # key-value pair on at least one of the three components. Thus, we are # printing the error message as a warning here. advertise_success = True else: advertise_success = False
def start_accepter(): global accepter_thread global affix_enabled global affix_stack_string # do this until we get the accepter started... while True: if not node_reset_config['reset_accepter'] and is_accepter_started(): # we're done, return the name! return myname_port else: # Just use getmyip(), this is the default behavior and will work if we have preferences set # We only want to call getmyip() once, rather than in the loop since this potentially avoids # rebuilding the allowed IP cache for each possible port bind_ip = emulcomm.getmyip() # Attempt to have the nodemanager listen on an available port. # Once it is able to listen, create a new thread and pass it the socket. # That new thread will be responsible for handling all of the incoming connections. for portindex in range(len(configuration['ports'])): possibleport = configuration['ports'][portindex] try: # There are two possible implementations available here: # 1) Use a raw (python) socket, and so we can have a timeout, as per ticket #881 # 2) Use a repy socket, but then possibly leak many connections. # Check to see if AFFIX is enabled. try: affix_enabled_lookup = advertise_lookup(enable_affix_key)[-1] servicelogger.log("affix_enabled_lookup is " + str(affix_enabled_lookup)) # Now we check if the last entry is True or False. if affix_enabled_lookup == 'True': affix_stack_string = advertise_lookup(affix_service_key)[-1] affix_enabled = True servicelogger.log("[INFO]: Current advertised Affix string: " + str(affix_stack_string)) else: affix_enabled = False except (AdvertiseError, TimeoutError), e: servicelogger.log("Trying to look up Affix enabled threw " + str(type(e)) + " " + str(e)) affix_enabled = False # Raise error on debug mode. if DEBUG_MODE: raise except ValueError: servicelogger.log("Trying to look up Affix enabled threw " + str(type(e)) + " " + str(e)) affix_enabled = False # Raise error on debug mode. if DEBUG_MODE: raise except IndexError: servicelogger.log("Trying to look up Affix enabled threw " + str(type(e)) + " " + str(e)) # This will occur if the advertise server returns an empty list. affix_enabled = False # Raise error on debug mode. if DEBUG_MODE: raise # If AFFIX is enabled, then we use AFFIX to open up a tcpserversocket. if affix_enabled: # Here we are going to use a for loop to find a second available port # for us to use for the LegacyAffix. Since the LegacyAffix opens up two # tcpserversocket, it needs two available ports. The first for a normal # repy listenforconnection call, the second for affix enabled # listenforconnection call. # We keep track of how many times we failed to listen with the Affix # framework. If we exceed 3, we default to Repy V2 API. Note that we # will try three times with each port, if we are unable to connect # with legacy Repy V2 API as well. fail_affix_count = 0 error_list = [] for affixportindex in range(portindex+1, len(configuration['ports'])): affixport = configuration['ports'][affixportindex] # Assign the nodemanager name to be the nodekey. We replace any whitespace in the # name and append zenodotus tag at the end. mypubkey = rsa_publickey_to_string(configuration['publickey']).replace(" ", "") myname = sha_hexhash(mypubkey) + '.zenodotus.poly.edu' myname_port = myname + ":" + str(possibleport) # Announce my Zenodotus name # XXX Save the handle, modify the announcement when my address changes! advertisepipe.add_to_pipe(myname, getmyip()) affix_legacy_string = "(CoordinationAffix)(LegacyAffix," + myname + "," + str(affixport) + ",0," affix_legacy_string += "(CoordinationAffix)" + affix_stack_string + ")" affix_object = AffixStackInterface(affix_legacy_string) # Now that we have found the Affix string and have created the AffixStackInterface # object, we will try to open up a listening tcp socket. If we fail to do so # 3 times, we will default to legacy Repy V2 socket. try: serversocket = affix_object.listenforconnection(myname, possibleport) servicelogger.log("[INFO]Started accepter thread with Affix string: " + affix_legacy_string) break except (AddressBindingError, AlreadyListeningError, DuplicateTupleError), e: servicelogger.log( "Failed to open listening socket with Affix on port: " + str(affixport) + ". Found error: " + str(e)) fail_affix_count += 1 error_list.append((type(e), str(e))) # If we fail more than 2 times, we will stop attempting to try listening # on a socket with the Affix framework. if fail_affix_count > 2: servicelogger.log("Failed to open socket using Affix after three attemps." + "Now resuming with legacy Repy socket. Errors were: " + str(error_list)) serversocket = timeout_listenforconnection(bind_ip, possibleport, 10) # assign the nodemanager name myname_port = str(bind_ip) + ":" + str(possibleport) break except Exception, e: servicelogger.log("[ERROR] Found Listenforconnection had exception: " + str(e)) raise else: # If AFFIX is not enabled, then we open up a normal tcpserversocket. # For now, we'll use the second method. serversocket = timeout_listenforconnection(bind_ip, possibleport,10) # assign the nodemanager name myname_port = str(bind_ip) + ":" + str(possibleport) # If there is no error, we were able to successfully start listening. # Create the thread, and start it up! accepter = nmconnectionmanager.AccepterThread(serversocket) accepter.start() # Now that we created an accepter, let's use it! set_accepter(accepter) # MOSHE: Is this thread safe!? # Now that waitforconn has been called, unset the accepter reset flag node_reset_config['reset_accepter'] = False
except Exception,e: exception_traceback_string = traceback.format_exc() servicelogger.log("[ERROR]: The following error occured when " \ + "modifying the crontab for the new 2009 " \ + "seattle crontab entry: " \ + exception_traceback_string) # get the external IP address... myip = None while True: try: # Try to find our external IP. myip = emulcomm.getmyip() except Exception, e: # Replace with InternetConnectivityError ? # If we aren't connected to the internet, emulcomm.getmyip() raises this: if len(e.args) >= 1 and e.args[0] == "Cannot detect a connection to the Internet.": # So we try again. pass else: # It wasn't emulcomm.getmyip()'s exception. re-raise. raise else: # We succeeded in getting our external IP. Leave the loop. break time.sleep(0.1) vesseldict = nmrequesthandler.initialize(myip, configuration['publickey'], version)
# with Affix-enabled calls. # Use the node's publickey to generate a name for our node. mypubkey = rsa_publickey_to_string(configuration['publickey']).replace( " ", "") affix_stack_name = sha_hexhash(mypubkey) enable_affix( '(CoordinationAffix)(MakeMeHearAffix)(NamingAndResolverAffix,' + affix_stack_name + ')') # get the external IP address... myip = None while True: try: # Try to find our external IP. myip = emulcomm.getmyip() except Exception, e: # Replace with InternetConnectivityError ? # If we aren't connected to the internet, emulcomm.getmyip() raises this: if len(e.args) >= 1 and e.args[ 0] == "Cannot detect a connection to the Internet.": # So we try again. pass else: # It wasn't emulcomm.getmyip()'s exception. re-raise. raise else: # We succeeded in getting our external IP. Leave the loop. break time.sleep(0.1) vesseldict = nmrequesthandler.initialize(myip, configuration['publickey'],
def start_accepter(): global accepter_thread global affix_enabled global affix_stack_string # do this until we get the accepter started... while True: if not node_reset_config['reset_accepter'] and is_accepter_started(): # we're done, return the name! return myname else: # Just use getmyip(), this is the default behavior and will work if we have preferences set # We only want to call getmyip() once, rather than in the loop since this potentially avoids # rebuilding the allowed IP cache for each possible port bind_ip = emulcomm.getmyip() # Attempt to have the nodemanager listen on an available port. # Once it is able to listen, create a new thread and pass it the socket. # That new thread will be responsible for handling all of the incoming connections. for portindex in range(len(configuration['ports'])): possibleport = configuration['ports'][portindex] try: # There are two possible implementations available here: # 1) Use a raw (python) socket, and so we can have a timeout, as per ticket #881 # 2) Use a repy socket, but then possibly leak many connections. # Check to see if AFFIX is enabled. try: affix_enabled_lookup = advertise_lookup(enable_affix_key)[-1] # Now we check if the last entry is True or False. if affix_enabled_lookup == 'True': affix_stack_string = advertise_lookup(affix_service_key)[-1] affix_enabled = True else: affix_enabled = False except AdvertiseError: affix_enabled = False except ValueError: affix_enabled = False except IndexError: # This will occur if the advertise server returns an empty list. affix_enabled = False # If AFFIX is enabled, then we use AFFIX to open up a tcpserversocket. if affix_enabled: # Here we are going to use a for loop to find a second available port # for us to use for the LegacyShim. Since the LegacyShim opens up two # tcpserversocket, it needs two available ports. The first for a normal # repy listenforconnection call, the second for shim enabled # listenforconnection call. for shimportindex in range(portindex+1, len(configuration['ports'])): shimport = configuration['ports'][shimportindex] affix_legacy_string = "(LegacyShim," + str(shimport) + ",0)" + affix_stack_string affix_object = ShimStackInterface(affix_legacy_string) serversocket = affix_object.listenforconnection(bind_ip, possibleport) servicelogger.log("[INFO]Started accepter thread with Affix string: " + affix_legacy_string) break else: # This is the case if we weren't able to find any port to listen on # With the legacy shim. raise ShimError("Unable to create create tcpserversocket with shims using port:" + str(possibleport)) else: # If AFFIX is not enabled, then we open up a normal tcpserversocket. # For now, we'll use the second method. serversocket = listenforconnection(bind_ip, possibleport) # If there is no error, we were able to successfully start listening. # Create the thread, and start it up! accepter = nmconnectionmanager.AccepterThread(serversocket) accepter.start() # Now that we created an accepter, let's use it! set_accepter(accepter) # MOSHE: Is this thread safe!? # Now that waitforconn has been called, unset the accepter reset flag node_reset_config['reset_accepter'] = False except Exception, e: # print bind_ip, port, e servicelogger.log("[ERROR]: when calling listenforconnection for the connection_handler: " + str(e)) servicelogger.log_last_exception() else: # assign the nodemanager name myname = str(bind_ip) + ":" + str(possibleport) break else: servicelogger.log("[ERROR]: cannot find a port for recvmess")
#connect to server lind_test_server.connect_syscall(clientsockfd, '127.0.0.1', 50300) #send each test with some delay, so that server processes each test cleanly. lind_test_server.send_syscall(clientsockfd, "A" * 100, 0) emultimer.sleep(0.1) lind_test_server.send_syscall(clientsockfd, "A" * 100, 0) emultimer.sleep(0.1) lind_test_server.send_syscall(clientsockfd, "A" * 100, 0) emultimer.sleep(0.1) lind_test_server.send_syscall(clientsockfd, "A" * 50, 0) emultimer.sleep(0.1) lind_test_server.close_syscall(clientsockfd) lind_test_server.connect_syscall(clientsockfd2, emulcomm.getmyip(), 50300) #send each test with some delay, so that server processes each test cleanly. lind_test_server.send_syscall(clientsockfd2, "A" * 100, 0) emultimer.sleep(0.1) lind_test_server.send_syscall(clientsockfd2, "A" * 100, 0) emultimer.sleep(0.1) lind_test_server.send_syscall(clientsockfd2, "A" * 100, 0) emultimer.sleep(0.1) lind_test_server.send_syscall(clientsockfd2, "A" * 50, 0) emultimer.sleep(0.1) #close the client & server sockets... lind_test_server.close_syscall(clientsockfd2) lind_test_server.close_syscall(serversockfd)
def start_accepter(): global accepter_thread global affix_enabled global affix_stack_string global zenodotus_advertise_handle # do this until we get the accepter started... while True: if not node_reset_config['reset_accepter'] and is_accepter_started(): # we're done, return the name! return myname_port else: # If we came here because a reset was initiated, kill the old # accepter thread server socket before starting a new one. try: accepter_thread.close_serversocket() servicelogger.log( "Closed previous accepter thread server socket.") except: # There was no accepter_thread, or it couldn't .close_serversocket(). # No problem -- this means nothing will be in the way of the new # serversocket. pass # Similarly, stop advertising my old Zenodotus name (if any), # ignoring potential errors. try: advertisepipe.remove_from_pipe(zenodotus_advertise_handle) except: pass # Just use getmyip(), this is the default behavior and will work if we have preferences set # We only want to call getmyip() once, rather than in the loop since this potentially avoids # rebuilding the allowed IP cache for each possible port bind_ip = emulcomm.getmyip() # Attempt to have the nodemanager listen on an available port. # Once it is able to listen, create a new thread and pass it the socket. # That new thread will be responsible for handling all of the incoming connections. for portindex in range(len(configuration['ports'])): possibleport = configuration['ports'][portindex] try: # There are two possible implementations available here: # 1) Use a raw (python) socket, and so we can have a timeout, as per ticket #881 # 2) Use a repy socket, but then possibly leak many connections. # Check to see if AFFIX is enabled. try: affix_enabled_lookup = advertise_lookup( enable_affix_key)[-1] servicelogger.log("affix_enabled_lookup is " + str(affix_enabled_lookup)) # Now we check if the last entry is True or False. if affix_enabled_lookup == 'True': affix_stack_string = advertise_lookup( affix_service_key)[-1] affix_enabled = True servicelogger.log( "[INFO]: Current advertised Affix string: " + str(affix_stack_string)) else: affix_enabled = False except (AdvertiseError, TimeoutError), e: servicelogger.log( "Trying to look up Affix enabled threw " + str(type(e)) + " " + str(e)) affix_enabled = False # Raise error on debug mode. if DEBUG_MODE: raise except ValueError: servicelogger.log( "Trying to look up Affix enabled threw " + str(type(e)) + " " + str(e)) affix_enabled = False # Raise error on debug mode. if DEBUG_MODE: raise except IndexError: servicelogger.log( "Trying to look up Affix enabled threw " + str(type(e)) + " " + str(e)) # This will occur if the advertise server returns an empty list. affix_enabled = False # Raise error on debug mode. if DEBUG_MODE: raise # If AFFIX is enabled, then we use AFFIX to open up a tcpserversocket. if affix_enabled: # Here we are going to use a for loop to find a second available port # for us to use for the LegacyAffix. Since the LegacyAffix opens up two # tcpserversocket, it needs two available ports. The first for a normal # repy listenforconnection call, the second for affix enabled # listenforconnection call. # We keep track of how many times we failed to listen with the Affix # framework. If we exceed 3, we default to Repy V2 API. Note that we # will try three times with each port, if we are unable to connect # with legacy Repy V2 API as well. fail_affix_count = 0 error_list = [] for affixportindex in range( portindex + 1, len(configuration['ports'])): affixport = configuration['ports'][affixportindex] # Assign the nodemanager name to be the nodekey. We replace any whitespace in the # name and append zenodotus tag at the end. mypubkey = rsa_publickey_to_string( configuration['publickey']).replace(" ", "") myname = sha_hexhash( mypubkey) + '.zenodotus.poly.edu' myname_port = myname + ":" + str(possibleport) # Announce my (new) Zenodotus name zenodotus_advertise_handle = advertisepipe.add_to_pipe( myname, getmyip()) affix_legacy_string = "(CoordinationAffix)(LegacyAffix," + myname + "," + str( affixport) + ",0," affix_legacy_string += "(CoordinationAffix)" + affix_stack_string + ")" affix_object = AffixStackInterface( affix_legacy_string) # Now that we have found the Affix string and have created the AffixStackInterface # object, we will try to open up a listening tcp socket. If we fail to do so # 3 times, we will default to legacy Repy V2 socket. try: serversocket = affix_object.listenforconnection( myname, possibleport) servicelogger.log( "[INFO]Started accepter thread with Affix string: " + affix_legacy_string) break except (AddressBindingError, AlreadyListeningError, DuplicateTupleError), e: servicelogger.log( "Failed to open listening socket with Affix on port: " + str(affixport) + ". Found error: " + str(e)) fail_affix_count += 1 error_list.append((type(e), str(e))) # If we fail more than 2 times, we will stop attempting to try listening # on a socket with the Affix framework. if fail_affix_count > 2: servicelogger.log( "Failed to open socket using Affix after three attemps." + "Now resuming with legacy Repy socket. Errors were: " + str(error_list)) serversocket = timeout_listenforconnection( bind_ip, possibleport, 10) # assign the nodemanager name myname_port = str(bind_ip) + ":" + str( possibleport) break except Exception, e: servicelogger.log( "[ERROR] Found Listenforconnection had exception: " + str(e)) raise else: # If AFFIX is not enabled, then we open up a normal tcpserversocket. # For now, we'll use the second method. serversocket = timeout_listenforconnection( bind_ip, possibleport, 10) # assign the nodemanager name myname_port = str(bind_ip) + ":" + str(possibleport) # If there is no error, we were able to successfully start listening. # Create the thread, and start it up! accepter = nmconnectionmanager.AccepterThread(serversocket) accepter.start() # Now that we created an accepter, let's use it! set_accepter(accepter) # MOSHE: Is this thread safe!? # Now that waitforconn has been called, unset the accepter reset flag node_reset_config['reset_accepter'] = False
else: use_nat = True # do this until we get the accepter started... while True: if is_accepter_started(): # we're done, return the name! return myname else: # Just use getmyip(), this is the default behavior and will work if we have preferences set # We only want to call getmyip() once, rather than in the loop since this potentially avoids # rebuilding the allowed IP cache for each possible port bind_ip = emulcomm.getmyip() for possibleport in configuration['ports']: try: if use_nat: # use the sha hash of the nodes public key with the vessel # number as an id for this node unique_id = rsa_publickey_to_string(configuration['publickey']) unique_id = sha_hexhash(unique_id) unique_id = unique_id+str(configuration['service_vessel']) servicelogger.log("[INFO]: Trying NAT wait") nat_waitforconn(unique_id, possibleport, nmconnectionmanager.connection_handler) # do a local waitforconn (not using a forowarder)
def main(): global configuration if not FOREGROUND: # Background ourselves. daemon.daemonize() # Check if we are running in testmode. if TEST_NM: nodemanager_pid = os.getpid() servicelogger.log("[INFO]: Running nodemanager in test mode on port 1224, "+ "pid %s." % str(nodemanager_pid)) nodeman_pid_file = open(os.path.join(os.getcwd(), 'nodemanager.pid'), 'w') # Write out the pid of the nodemanager process that we started to a file. # This is only done if the nodemanager was started in test mode. try: nodeman_pid_file.write(str(nodemanager_pid)) finally: nodeman_pid_file.close() else: # ensure that only one instance is running at a time... gotlock = runonce.getprocesslock("seattlenodemanager") if gotlock == True: # I got the lock. All is well... pass else: if gotlock: servicelogger.log("[ERROR]:Another node manager process (pid: " + str(gotlock) + ") is running") else: servicelogger.log("[ERROR]:Another node manager process is running") return servicelogger.log('[INFO]: This is Seattle release "' + version + "'") # Feature add for #1031: Log information about the system in the nm log... servicelogger.log('[INFO]:platform.python_version(): "' + str(platform.python_version())+'"') servicelogger.log('[INFO]:platform.platform(): "' + str(platform.platform())+'"') # uname on Android only yields 'Linux', let's be more specific. try: import android servicelogger.log('[INFO]:platform.uname(): Android / "' + str(platform.uname())+'"') except ImportError: servicelogger.log('[INFO]:platform.uname(): "'+str(platform.uname())+'"') # I'll grab the necessary information first... servicelogger.log("[INFO]:Loading config") # BUG: Do this better? Is this the right way to engineer this? configuration = persist.restore_object("nodeman.cfg") # If Seattle is not installed, the nodemanager will have no vesseldict # and an incomplete config. Log this problem and exit. try: if configuration["seattle_installed"] is not True: servicelogger.log("[ERROR]:Seattle is not installed. Run the Seattle installer to create the required configuration files before starting the nodemanager. Exiting.") harshexit.harshexit(10) except KeyError: # There isn't even a "seattle_installed" entry in this dict!? servicelogger.log("[ERROR]:The nodemanager configuration, nodeman.cfg, is corrupt. Exiting.") harshexit.harshexit(11) # Armon: initialize the network restrictions initialize_ip_interface_restrictions(configuration) # Enable Affix and overload various Repy network API calls # with Affix-enabled calls. # Use the node's publickey to generate a name for our node. mypubkey = rsa_publickey_to_string(configuration['publickey']).replace(" ", "") affix_stack_name = sha_hexhash(mypubkey) enable_affix('(CoordinationAffix)(MakeMeHearAffix)(NamingAndResolverAffix,' + affix_stack_name + ')') # get the external IP address... myip = None while True: try: # Try to find our external IP. myip = emulcomm.getmyip() except Exception, e: # Replace with InternetConnectivityError ? # If we aren't connected to the internet, emulcomm.getmyip() raises this: if len(e.args) >= 1 and e.args[0] == "Cannot detect a connection to the Internet.": # So we try again. pass else: # It wasn't emulcomm.getmyip()'s exception. re-raise. raise else: # We succeeded in getting our external IP. Leave the loop. break time.sleep(0.1)
mypubkey = rsa_publickey_to_string(configuration['publickey']).replace(" ", "") my_zeno_name = sha_hexhash(mypubkey) + '.zenodotus.poly.edu' # Check to see if Affix is enabled. If it is, we use the affix_object # that is returned. affix_enabled, affix_object, affix_legacy_string = check_and_create_affix_object(my_zeno_name) # If AFFIX is enabled, then we use AFFIX to open up a tcpserversocket. if affix_enabled: # Assign the nodemanager name to be the nodekey. We replace any whitespace in the # name and append zenodotus tag at the end. # Announce my (new) Zenodotus name zenodotus_advertise_handle = advertisepipe.add_to_pipe(my_zeno_name, emulcomm.getmyip()) # Now that we have found the Affix string and have created the AffixStackInterface # object, we will try to open up a listening tcp socket. If we get an error, we # fall back to using legacy Repy API. try: serversocket = affix_object.listenforconnection(my_zeno_name, localport) servicelogger.log("[INFO]Started accepter thread with Affix string: " + affix_legacy_string) except (AddressBindingError, AlreadyListeningError, DuplicateTupleError): servicelogger.log("Failed to open listening socket with Affix on port: " + str(localport) + ". Found error: " + str(e) + ". Trying legacy connection.") return old_timeout_listenforconnection(localip, localport, 10) else: # If we did not receive any error, we need to overwrite getmyip() with # the new address. global getmyip
lind_test_server.connect_syscall(clientsockfd, '127.0.0.1', 50300) #send each test with some delay, so that server processes each test cleanly. lind_test_server.send_syscall(clientsockfd, "A" * 100, 0) emultimer.sleep(0.1) lind_test_server.send_syscall(clientsockfd, "A" * 100, 0) emultimer.sleep(0.1) lind_test_server.send_syscall(clientsockfd, "A" * 100, 0) emultimer.sleep(0.1) lind_test_server.send_syscall(clientsockfd, "A" * 50, 0) emultimer.sleep(0.1) lind_test_server.close_syscall(clientsockfd) lind_test_server.connect_syscall(clientsockfd2, emulcomm.getmyip(), 50300) #send each test with some delay, so that server processes each test cleanly. lind_test_server.send_syscall(clientsockfd2, "A" * 100, 0) emultimer.sleep(0.1) lind_test_server.send_syscall(clientsockfd2, "A" * 100, 0) emultimer.sleep(0.1) lind_test_server.send_syscall(clientsockfd2, "A" * 100, 0) emultimer.sleep(0.1) lind_test_server.send_syscall(clientsockfd2, "A" * 50, 0) emultimer.sleep(0.1) #close the client & server sockets... lind_test_server.close_syscall(clientsockfd2)