玉兔远程控制 0.1.0-bate8
载入中...
搜索中...
未找到
BackendFtpServer.cpp
1// Copyright Copyright (c) Kang Lin studio, All Rights Reserved
2// Author: Kang Lin <kl222@126.com>
3
4#include <QSslSocket>
5#include <QLoggingCategory>
6#include "BackendFtpServer.h"
7#include "OperateFtpServer.h"
8
9static Q_LOGGING_CATEGORY(log, "FtpServer.Backend")
11 : CBackend(pOperate)
12 , m_pOperate(pOperate)
13 , m_pServer(nullptr)
14 , m_nTotal(0)
15 , m_nDisconnect(0)
16{
17 qDebug(log) << Q_FUNC_INFO;
18 m_Para = m_pOperate->GetParameter();
19}
20
21CBackendFtpServer::~CBackendFtpServer()
22{
23 qDebug(log) << Q_FUNC_INFO;
24}
25
26CBackend::OnInitReturnValue CBackendFtpServer::OnInit()
27{
28 qDebug(log) << Q_FUNC_INFO;
29 if(m_pServer) {
30 qCritical(log) << "Server is exist";
31 return OnInitReturnValue::Fail;
32 }
33
34 m_nTotal = 0;
35 m_nDisconnect = 0;
36 m_Sockets.clear();
37 emit sigConnectCount(m_nTotal, m_Sockets.size(), m_nDisconnect);
38
39 CSecurityLevel::Levels securityLevel;
40 QString szUser;
41 QString szPassword;
42 auto &net = m_Para->m_Net;
43 if(!m_Para->GetAnonymousLogin()) {
44 auto &user = net.m_User;
45 szUser = user.GetUser();
46 szPassword = user.GetPassword();
47 if(!szPassword.isEmpty())
48 securityLevel |= CSecurityLevel::Level::Authentication;
49 }
50
51 m_pServer = new CFtpServer(this, m_Para->GetRoot(), net.GetPort(),
52 szUser, szPassword,
53 m_Para->GetReadOnly());
54 if(!m_pServer) {
55 qCritical(log) << "Failed to new CFtpServer";
56 return OnInitReturnValue::Fail;
57 }
58
59 m_pServer->SetFilter(this);
60 bool bListen = false;
61 if(m_Para->GetListenAll()) {
62 bListen = m_pServer->Listening();
63 if(bListen) {
64 QString szMsg = tr("Ftp server listen on all address port %1. the lan ip is %2")
65 .arg(net.GetPort()).arg(m_pServer->lanIp());
66 qInfo(log) << szMsg;
67 emit sigInformation(szMsg);
68 } else {
69 QString szErr = tr("Failed to Ftp server is listening on %1")
70 .arg(net.GetPort());
71 qCritical(log) << szErr;
72 emit sigError(-1, szErr);
73 return OnInitReturnValue::Fail;
74 }
75 } else {
76 QString szErr;
77 if(m_Para->GetListen().isEmpty()) {
78 szErr = tr("Failed: Ftp server is not set to listen on any address");
79 qCritical(log) << szErr;
80 emit sigError(-1, szErr);
81 return OnInitReturnValue::Fail;
82 }
83 foreach (auto a, m_Para->GetListen()) {
84 QHostAddress addr(a);
85 bListen = m_pServer->Listening(addr);
86 if(!bListen) {
87 szErr = tr("Failed to Ftp server is listening on %1:%2")
88 .arg(addr.toString()).arg(net.GetPort());
89 qCritical(log) << szErr;
90 emit sigError(-1, szErr);
91 return OnInitReturnValue::Fail;
92 }
93 if(!szErr.isEmpty())
94 szErr += "; ";
95 szErr += addr.toString() + ":" + QString::number(net.GetPort());
96 }
97 if(bListen) {
98 QString szMsg = tr("Ftp server is listening on ") + szErr;
99 qInfo(log) << szMsg;
100 emit sigInformation(szMsg);
101 }
102 }
103
104 emit sigSecurityLevel(securityLevel);
105 return OnInitReturnValue::NotUseOnProcess;
106}
107
109{
110 qDebug(log) << Q_FUNC_INFO;
111 if(m_pServer)
112 delete m_pServer;
113 return 0;
114}
115
116bool CBackendFtpServer::onFilter(QSslSocket *socket)
117{
118 bool bFilte = false;
119 if(!socket) return true;
120 QString szIP = socket->peerAddress().toString();
121
122 QStringList white = m_Para->GetWhitelist();
123 QStringList black = m_Para->GetBlacklist();
124 bool bInWhite = false;
125 if(!white.isEmpty()) {
126 foreach(auto i, white) {
127 QHostAddress addr(szIP);
128 auto sub = QHostAddress::parseSubnet(i);
129 if(addr.isInSubnet(sub.first, sub.second)) {
130 bInWhite = true;
131 break;
132 }
133 }
134 }
135
136 if(!bInWhite && !black.isEmpty()) {
137 foreach(auto i, black) {
138 QHostAddress addr(szIP);
139 auto sub = QHostAddress::parseSubnet(i);
140 if(addr.isInSubnet(sub.first, sub.second)) {
141 qInfo(log) << "Filet" << szIP << "in blacklist";
142 return true;
143 }
144 }
145 }
146
147 if(bFilte) return true;
148
149 if(m_Para->GetConnectCount() >= 0 && m_Para->GetConnectCount() <= m_Sockets.size()) {
150 qDebug(log) << "Exceeded the allowed number of connections:" << m_Para->GetConnectCount();
151 return true;
152 }
153
154 bool check = false;
155 check = connect(socket, SIGNAL(disconnected()),
156 this, SLOT(slotDisconnected()));
157 Q_ASSERT(check);
158
159 quint16 port = socket->peerPort();
160 m_Sockets.append(socket);
161 m_nTotal++;
162 emit sigConnectCount(m_nTotal, m_Sockets.size(), m_nDisconnect);
163 emit sigConnected(szIP, port);
164 qDebug(log) << "Current connect count:" << m_Sockets.size()
165 << "; new connect from:" << szIP + ":" + QString::number(port);
166 return false;
167}
168
169void CBackendFtpServer::slotDisconnected()
170{
171 QSslSocket *socket = qobject_cast<QSslSocket*>(sender());
172 if(!socket) return;
173 m_Sockets.removeAll(socket);
174 m_nDisconnect++;
175 emit sigConnectCount(m_nTotal, m_Sockets.size(), m_nDisconnect);
176 QString ip = socket->peerAddress().toString();
177 quint16 port = socket->peerPort();
178 emit sigDisconnected(ip, port);
179 qDebug(log) << "Current connect count:" << m_Sockets.size()
180 << "; remove connect:" << socket->peerAddress().toString();
181}
182
183void CBackendFtpServer::slotDisconnect(const QString& szIp, quint16 port)
184{
185 foreach (auto s, m_Sockets) {
186 if(s->peerAddress().toString() == szIp && s->peerPort() == port){
187 s->disconnectFromHost();
188 }
189 }
190}
virtual int OnClean() override
清理
virtual OnInitReturnValue OnInit() override
初始化
后端接口。它由协议插件实现。 它默认启动一个定时器来开启一个非 Qt 事件循环(就是普通的循环处理)。 详见: Start()、 slotTimeOut()、 OnProcess() 。 当然,它仍然支...
Definition Backend.h:42
void sigInformation(const QString &szInfo)
从后台线程中触发在主线程中显示信息,不阻塞后台线程
void sigError(const int nError, const QString &szError=QString())
当有错误产生时触发
void sigSecurityLevel(CSecurityLevel::Levels level)
当安全级别改变时触发