示例#1
0
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
示例#2
0
def start_accepter():
    global accepter_thread

    # 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

            # Use getmyip() to find the IP address the nodemanager should
            # listen on for incoming connections. This will work correctly
            # if IP/interface preferences have been 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 = 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 possibleport in configuration['ports']:
                try:
                    # Use a Repy socket for listening. This lets us override
                    # the listenforconnection function with a version using an
                    # Affix stack easily; furthermore, we can transparently use
                    # the Repy sockettimeout library to protect against malicious
                    # clients that feed us endless data (or no data) to tie up
                    # the connection.
                    try:
                        serversocket = timeout_listenforconnection(
                            bind_ip, possibleport, 10)
                    except (AlreadyListeningError, DuplicateTupleError), e:
                        # These are rather dull errors that will result in us
                        # trying a different port. Don't print a stack trace.
                        servicelogger.log(
                            "[ERROR]: listenforconnection for address " +
                            bind_ip + ":" + str(possibleport) +
                            " failed with error '" + repr(e) + "'. Retrying.")
                        continue

                    # Assign the nodemanager name.
                    # We re-retrieve our address using getmyip as we may now be using
                    # a zenodotus name instead.
                    myname_port = str(getmyip()) + ":" + 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:
                    # print bind_ip, port, e
                    servicelogger.log(
                        "[ERROR] setting up nodemanager serversocket " +
                        "on address " + bind_ip + ":" + str(possibleport) +
                        ": " + repr(e))
                    servicelogger.log_last_exception()
                else:
                    break
示例#3
0
def start_accepter():
  global accepter_thread

  # 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


      # 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 = 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.
      
          # For now, we'll use the second method and use the sockettimeout
          # library so we can still use a timeout to ensure we don't have
          # any malicious clients that feed us endless data (or no data)
          # to tie up the connection. Note that if we are using Affix,
          # we will be using a TimeoutAffix to achieve the equivalent
          # outcome.
          serversocket = timeout_listenforconnection(bind_ip, possibleport,10)

          # assign the nodemanager name.
          # We re-retrieve our address using getmyip as we may now be using
          # a zenodotus name instead.
          myname_port = str(getmyip()) + ":" + 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:
          # print bind_ip, port, e
          servicelogger.log("[ERROR]: when calling listenforconnection for the connection_handler: " + str(e))
          servicelogger.log_last_exception()
        else:
          break

      else:
        servicelogger.log("[ERROR]: cannot find a port for recvmess")