Ejemplo n.º 1
0
    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()
Ejemplo n.º 2
0
    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