def _connected(self, client_id): client = self.clients.find_id(client_id) if not client: self.instance_com.push_output( 'ERROR Unknown client connected client_id=%s' % client_id) self.instance_com.client_kill(client_id) return self.set_iptables_rules( client['iptables_rules'], client['ip6tables_rules'], ) timestamp = utils.now() doc = { '_id': client['doc_id'], 'user_id': client['user_id'], 'server_id': self.server.id, 'host_id': settings.local.host_id, 'timestamp': timestamp, 'platform': client['platform'], 'type': client['user_type'], 'device_name': client['device_name'], 'mac_addr': client['mac_addr'], 'network': self.server.network, 'real_address': client['real_address'], 'virt_address': client['virt_address'], 'virt_address6': client['virt_address6'], 'host_address': self.route_addr, 'host_address6': settings.local.host.local_addr6, 'dns_servers': client['dns_servers'], 'dns_suffix': client['dns_suffix'], 'connected_since': int(timestamp.strftime('%s')), } if settings.local.sub_active and \ settings.local.sub_plan == 'enterprise': domain = (client['user_name'].split('@')[0] + '.' + client['org_name']).lower() domain_hash = hashlib.md5() domain_hash.update(domain) domain_hash = bson.binary.Binary(domain_hash.digest(), subtype=bson.binary.MD5_SUBTYPE) doc['domain'] = domain_hash doc['domain_name'] = domain doc['virt_address_num'] = utils.ip_to_long( client['virt_address'].split('/')[0]) try: self.collection.insert(doc) if self.server.route_clients: messenger.publish('client', { 'state': True, 'server_id': self.server.id, 'virt_address': client['virt_address'], 'virt_address6': client['virt_address6'], 'host_address': self.route_addr, 'host_address6': settings.local.host.local_addr6, }) except: logger.exception('Error adding client', 'server', server_id=self.server.id, ) self.instance_com.client_kill(client_id) return self.clients.update_id(client_id, { 'timestamp': time.time(), }) self.clients_queue.append(client_id) self.instance_com.push_output( 'User connected user_id=%s' % client['user_id']) self.send_event()
def get_virt_addr(self, org_id, user_id, mac_addr, doc_id): address_dynamic = False disconnected = set() subnet = '/%s' % self.ip_network.prefixlen virt_address = self.server.get_ip_addr(org_id, user_id) if not virt_address: logger.error('User missing ip address', 'clients', server_id=self.server.id, instance_id=self.instance.id, user_id=user_id, multi_device=self.server.multi_device, network=self.server.network, user_count=self.server.user_count, ) if virt_address and self.server.multi_device: if self.server.replicating: doc = self.pool_collection.find_one({ '_id': utils.ip_to_long(virt_address.split('/')[0]), }) if doc: if doc['server_id'] == self.server.id and \ doc['user_id'] == user_id and \ doc['mac_addr'] == mac_addr: response = self.pool_collection.update({ '_id': utils.ip_to_long( virt_address.split('/')[0]), 'server_id': self.server.id, 'user_id': user_id, 'mac_addr': mac_addr, }, {'$set': { 'server_id': self.server.id, 'user_id': user_id, 'mac_addr': mac_addr, 'client_id': doc_id, 'timestamp': utils.now(), }}) if response['updatedExisting']: messenger.publish('instance', [ 'user_disconnect_id', user_id, doc['client_id'], ]) disconnected.add(doc['client_id']) else: virt_address = None else: virt_address = None else: try: self.pool_collection.insert({ '_id': utils.ip_to_long( virt_address.split('/')[0]), 'server_id': self.server.id, 'user_id': user_id, 'mac_addr': mac_addr, 'client_id': doc_id, 'timestamp': utils.now(), }) except pymongo.errors.DuplicateKeyError: virt_address = None if mac_addr: messenger.publish('instance', [ 'user_disconnect_mac', user_id, settings.local.host_id, mac_addr, ]) else: if mac_addr: for clnt in self.clients.find({ 'user_id': user_id, 'mac_addr': mac_addr, }): self.instance_com.client_kill(clnt['id']) if self.clients.find({'virt_address': virt_address}): virt_address = None if not virt_address: if self.server.replicating and self.server.multi_device: doc = self.pool_collection.find_and_modify({ 'server_id': self.server.id, 'user_id': None, }, { 'server_id': self.server.id, 'user_id': user_id, 'mac_addr': mac_addr, 'client_id': doc_id, 'timestamp': utils.now(), }, new=True) if doc: address_dynamic = True virt_address = utils.long_to_ip(doc['_id']) + subnet else: doc = self.server_collection.find_one({ '_id': self.server.id, }, { 'pool_cursor': True, }) last_addr = doc.get('pool_cursor') if last_addr: last_addr = ipaddress.IPv4Address( utils.long_to_ip(last_addr)) network = ipaddress.IPv4Network(self.server.network) ip_pool = utils.get_ip_pool_reverse(network, last_addr) if ip_pool: for ip_addr in ip_pool: try: self.pool_collection.insert({ '_id': long(ip_addr._ip), 'server_id': self.server.id, 'user_id': user_id, 'mac_addr': mac_addr, 'client_id': doc_id, 'timestamp': utils.now(), }) virt_address = str(ip_addr) + subnet address_dynamic = True break except pymongo.errors.DuplicateKeyError: continue self.server_collection.update({ '_id': self.server.id, 'status': ONLINE, }, {'$set': { 'pool_cursor': utils.ip_to_long( virt_address.split('/')[0]), }}) else: while True: try: ip_addr = self.ip_pool.pop() except IndexError: break ip_addr += subnet if not self.clients.find({'virt_address': ip_addr}): virt_address = ip_addr address_dynamic = True if not virt_address: logger.error('Unable to assign ip address, pool full', 'clients', server_id=self.server.id, instance_id=self.instance.id, user_id=user_id, multi_device=self.server.multi_device, network=self.server.network, user_count=self.server.user_count, ) return virt_address, address_dynamic