Python build Ssserver limit port connection number

Source: Internet
Author: User
Tags instance method

Create a new file, write the following, and save it as a socket.py file. Put it in the folder where Ssserver.exe is located

#!/usr/bin/python
#-*-Coding:utf-8-*-
#
# Copyright Falseen
#
# Licensed under the Apache License, Version 2.0 (the "License");
# You are not a use of this file except in compliance with the License.
# Obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# unless required by applicable or agreed to writing, software
# Distributed under the License is distributed on a "as is" BASIS,
# without warranties or CONDITIONS of any KIND, either express or implied.
# See the License for the specific language governing permissions and
# Limitations under the License.
#
#
# function: Limit the number of clients (based on IP judgment)
#
# Instructions for use: 1. Place this file in the SS root directory to take effect without additional setup (requires re-running SS).
# 2. Modify the Clean_time and ip_numbers of lines 53 and 54 to the number you want.
# 3. If your server has IPv6 and you want to restrict IP4 and IP6 separately, you can set the Only_port to False.
#
#
# principle: By default, the SS will refer to the socket file in the system when it is run, but after placing the socket file in the SS directory, the SS will refer to our custom socket file.
# then in this file again refer to the real socket package, and on the basis of the original socket to modify, the final SS call is through our modified socket file.
#
# so theoretically any Python program that references a socket package can use this file to limit the number of connected IPs.
#

From __future__ import absolute_import, Division, print_function, \
With_statement, Nested_scopes

Import Sys

Del sys.modules[' socket ']

Import Sys
Import time
Import logging
Import types

Path = Sys.path[0]
Sys.path.pop (0)

Import Socket # Importing a real socket package

Sys.path.insert (0, path)

Clean_time = 60        # Sets the time interval for cleaning up the IP, where no connected IP will be cleaned
Ip_numbers = 1          # Set the number of allowed IPs per port, that is, set the number of client ips
Only_port = true        # Sets whether to determine only the port. If true, only the port is determined. If False, it is strictly judged on the ip+ port.

# Dynamic Path class method
Def re_class_method (_class, Method_name, Re_method):
    method = GetAttr (_class, method_name)
    info = sys.version_info
    if info[0] >= 3:
  & nbsp;     setattr (_class, method_name,
                 types. Methodtype (Lambda *args, **kwds:re_method (method, *args, **kwds), _class))
    else:
         setattr (_class, method_name,
                 types. Methodtype (Lambda *args, **kwds:re_method (method, *args, **kwds), None, _class))

# Dynamic Path instance method
def re_self_method (self, Method_name, Re_method):
method = GetAttr (self, method_name)
SetAttr (self, method_name, types. Methodtype (Lambda *args, **kwds:re_method (method, *args, **kwds), Self, self))

# Processing TCP connections
def re_accept (Old_method, Self, *args, **kwds):

While True:

Return_value = Old_method (self, *args, **kwds)
Self_socket = return_value[0]
If Only_port:
Server_ip_port = '%s '% self.getsockname () [1]
Else
Server_ip_port = '%s_%s '% (self.getsockname () [0], Self.getsockname () [1])

CLIENT_IP = return_value[1][0]

Client_ip_list = [X[0].split (' # ') [0] for x in Self._list_client_ip[server_ip_port]]
If Len (self._list_client_ip[server_ip_port]) = = 0:
Logging.debug ("[Re_socket] first add%s"% client_ip)
Self._list_client_ip[server_ip_port].append (['%s#%s '% (Client_ip, Time.time ()), Self_socket])
Return Return_value

        if client_ip in client_ip_list:
             logging.debug ("[Re_socket] update socket in%s"% client_ip)
             _ip_index = Client_ip_list.index (client_ip)
             Self._list_client_ip[server_ip_port][_ip_index][0] = '%s#%s '% (Client_ip, Time.time ())
            self._ List_client_ip[server_ip_port][_ip_index].append (self_socket)
             return Return_value

        Else:
             If Len (Self._list_client_ip[server_ip_port]) < ip_numbers:
                 logging.debug ("[Re_socket] Add%s"% client_ip)
                 self._list_client_ip[ Server_ip_port].append (['%s#%s '% (Client_ip, Time.time ()), Self_socket])
                 return Return_value

For x in [x for X in Self._list_client_ip[server_ip_port]]:
is_closed = True
If Time.time ()-Float (X[0].split (' # ') [1]) > Clean_time:

For y in X[1:]:
Try
Y.getpeername () # To determine if the connection is closed
is_closed = False
Break
Except: # If an exception is thrown, the connection is closed and the socket can be closed
Logging.debug ("[Re_socket] Close and remove the time out socket 1/%s"% (Len (x[1:]))
                             X.remove (y)

                     if not is_closed:
                         logging.debug (' [Re_socket] the%s still exists and Update Last_time '% str (x[1].getpeername () [0])
                         _ip_index = Client_ip_list.index (x [0].split (' # ') [0])
                         self._list_client_ip[server_ip_port][_ip_index][0] = '%s#% S '% (X[0].split (' # ') [0], Time.time ())

                     Else:
                         logging.info ("[Re_socket] Remove Time Out IP and add new IP%s"% c LIENT_IP)
                         self._list_client_ip[server_ip_port].remove (x)
                          self._list_client_ip[server_ip_port].append (['%s#%s '% (Client_ip, Time.time ()), Self_socket])
                         return Return_value

if Int (time.time ())% 5 = = 0:
Logging.debug ("[Re_socket] the port%s client more then the%s"% (Server_ip_port, ip_numbers))

# Handling UDP connections
def re_recvfrom (Old_method, Self, *args, **kwds):

    while True:
        return_value = Old_method (*args, * * Kwds)
        self_socket = '
         If Only_port:
            server_ip_port = '%s '% Self.getsockname () [1]
        else:
             server_ip_port = '%s_%s '% (self.getsockname () [0], Self.getsockname () [1])
        client_ip = return_value[1][0]
         Client_ip_list = [X[0].split (' # ') [0] for x in Self._list_client_ip[server_ip_port]]

If Len (self._list_client_ip[server_ip_port]) = = 0:
Logging.debug ("[Re_socket] first add%s"% client_ip)
Self._list_client_ip[server_ip_port].append (['%s#%s '% (Client_ip, Time.time ()), Self_socket])
Return Return_value

If client_ip in Client_ip_list:
Logging.debug ("[Re_socket] update socket in%s"% client_ip)
_ip_index = Client_ip_list.index (CLIENT_IP)
Self._list_client_ip[server_ip_port][_ip_index][0] = '%s#%s '% (Client_ip, time.time ())
Return Return_value
Else
If Len (Self._list_client_ip[server_ip_port]) < ip_numbers:
Logging.debug ("[Re_socket] Add%s"% client_ip)
Self._list_client_ip[server_ip_port].append (['%s#%s '% (Client_ip, Time.time ()), Self_socket])
Return Return_value

For x in [x for X in Self._list_client_ip[server_ip_port]]:
is_closed = True
If Time.time ()-Float (X[0].split (' # ') [1]) > Clean_time:

For y in X[1:]:
Try
Y.getpeername () # To determine if the connection is closed
is_closed = False
Break
Except: # If an exception is thrown, the connection is closed and the socket can be closed
Logging.debug ("[Re_socket] Close and remove the time out socket 1/%s"% (Len (x[1:]))
X.remove (y)

                     if not is_closed:
                         logging.debug (' [Re_socket] the%s still exists and Update Last_time '% str (x[1].getpeername () [0])
                         _ip_index = Client_ip_list.index (x [0].split (' # ') [0])
                         self._list_client_ip[server_ip_port][_ip_index][0] = '%s#% S '% (X[0].split (' # ') [0], Time.time ())

                     Else:
                         logging.info ("[Re_socket] Remove Time Out IP and add new IP%s"% c LIENT_IP)
                         self._list_client_ip[server_ip_port].remove (x)
                          self._list_client_ip[server_ip_port].append (['%s#%s '% (Client_ip, Time.time ()), Self_socket])
                         return Return_value

if Int (time.time ())% 5 = = 0:
Logging.debug ("[Re_socket] the port%s client more then the%s"% (Server_ip_port, ip_numbers))
New_tuple = [B ', return_value[1]]
Return_value = tuple (new_tuple)
Return Return_value

def re_bind (Old_method, Self, *args, **kwds):
If Only_port:
Port = '%s '% args[0][1]
Else
Port = '%s_%s '% (args[0][0], args[0][1])
Self._list_client_ip[port] = []
Re_self_method (self, ' recvfrom ', Re_recvfrom)
Old_method (self, *args, **kwds)

SetAttr (Socket.socket, ' _list_client_ip ', {})
Re_class_method (Socket.socket, ' bind ', re_bind)
Re_class_method (Socket.socket, ' accept ', re_accept)

Python build Ssserver limit port connection number

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.