未验证 提交 da78e3f5 编写于 作者: F fatedier 提交者: GitHub

Merge pull request #781 from fatedier/dev

bump version to 0.19.1
<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <title>frps dashboard</title> <link rel="shortcut icon" href="favicon.ico"></head> <body> <div id=app></div> <script type="text/javascript" src="manifest.js?33af4addd27a494b40c1"></script><script type="text/javascript" src="vendor.js?c2d294f9c0a40fd7073a"></script><script type="text/javascript" src="index.js?a0da222d4e0f906bc057"></script></body> </html>
\ No newline at end of file
<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <title>frps dashboard</title> <link rel="shortcut icon" href="favicon.ico"></head> <body> <div id=app></div> <script type="text/javascript" src="manifest.js?b90a32ccfb87def61aaa"></script><script type="text/javascript" src="vendor.js?f04985ef00f520142368"></script></body> </html>
\ No newline at end of file
此差异已折叠。
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,a){for(var u,i,f,l=0,s=[];l<t.length;l++)i=t[l],o[i]&&s.push(o[i][0]),o[i]=0;for(u in c)Object.prototype.hasOwnProperty.call(c,u)&&(e[u]=c[u]);for(r&&r(t,c,a);s.length;)s.shift()();if(a)for(l=0;l<a.length;l++)f=n(n.s=a[l]);return f};var t={},o={2:0};n.e=function(e){function r(){u.onerror=u.onload=null,clearTimeout(i);var n=o[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),o[e]=void 0)}var t=o[e];if(0===t)return new Promise(function(e){e()});if(t)return t[2];var c=new Promise(function(n,r){t=o[e]=[n,r]});t[2]=c;var a=document.getElementsByTagName("head")[0],u=document.createElement("script");u.type="text/javascript",u.charset="utf-8",u.async=!0,u.timeout=12e4,n.nc&&u.setAttribute("nonce",n.nc),u.src=n.p+""+e+".js?"+{0:"a0da222d4e0f906bc057",1:"c2d294f9c0a40fd7073a"}[e];var i=setTimeout(r,12e4);return u.onerror=u.onload=r,a.appendChild(u),c},n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n.oe=function(e){throw console.error(e),e}}([]);
\ No newline at end of file
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,u,c){for(var i,a,f,l=0,s=[];l<t.length;l++)a=t[l],o[a]&&s.push(o[a][0]),o[a]=0;for(i in u)Object.prototype.hasOwnProperty.call(u,i)&&(e[i]=u[i]);for(r&&r(t,u,c);s.length;)s.shift()();if(c)for(l=0;l<c.length;l++)f=n(n.s=c[l]);return f};var t={},o={1:0};n.e=function(e){function r(){i.onerror=i.onload=null,clearTimeout(a);var n=o[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),o[e]=void 0)}var t=o[e];if(0===t)return new Promise(function(e){e()});if(t)return t[2];var u=new Promise(function(n,r){t=o[e]=[n,r]});t[2]=u;var c=document.getElementsByTagName("head")[0],i=document.createElement("script");i.type="text/javascript",i.charset="utf-8",i.async=!0,i.timeout=12e4,n.nc&&i.setAttribute("nonce",n.nc),i.src=n.p+""+e+".js?"+{0:"f04985ef00f520142368"}[e];var a=setTimeout(r,12e4);return i.onerror=i.onload=r,c.appendChild(i),u},n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n.oe=function(e){throw console.error(e),e}}([]);
\ No newline at end of file
此差异已折叠。
此差异已折叠。
......@@ -272,6 +272,12 @@ func (pxy *XtcpProxy) InWorkConn(conn frpNet.Conn) {
}
clientConn.SetReadDeadline(time.Time{})
clientConn.Close()
if natHoleRespMsg.Error != "" {
pxy.Error("natHoleRespMsg get error info: %s", natHoleRespMsg.Error)
return
}
pxy.Trace("get natHoleRespMsg, sid [%s], client address [%s]", natHoleRespMsg.Sid, natHoleRespMsg.ClientAddr)
// Send sid to visitor udp address.
......
......@@ -235,6 +235,11 @@ func (sv *XtcpVisitor) handleConn(userConn frpNet.Conn) {
visitorConn.SetReadDeadline(time.Time{})
pool.PutBuf(buf)
if natHoleRespMsg.Error != "" {
sv.Error("natHoleRespMsg get error info: %s", natHoleRespMsg.Error)
return
}
sv.Trace("get natHoleRespMsg, sid [%s], client address [%s]", natHoleRespMsg.Sid, natHoleRespMsg.ClientAddr)
// Close visitorConn, so we can use it's local address.
......
......@@ -69,6 +69,7 @@ var (
sk string
serverName string
bindAddr string
bindPort int
)
func init() {
......
......@@ -40,6 +40,7 @@ func init() {
stcpCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
stcpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
stcpCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "", "", "bind addr")
stcpCmd.PersistentFlags().IntVarP(&bindPort, "bind_port", "", 0, "bind port")
stcpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
stcpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
......@@ -69,6 +70,7 @@ var stcpCmd = &cobra.Command{
cfg.LocalIp = localIp
cfg.LocalPort = localPort
cfg.BindAddr = bindAddr
cfg.BindPort = bindPort
cfg.UseEncryption = useEncryption
cfg.UseCompression = useCompression
......
......@@ -40,6 +40,7 @@ func init() {
xtcpCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
xtcpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
xtcpCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "", "", "bind addr")
xtcpCmd.PersistentFlags().IntVarP(&bindPort, "bind_port", "", 0, "bind port")
xtcpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
xtcpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
......@@ -69,6 +70,7 @@ var xtcpCmd = &cobra.Command{
cfg.LocalIp = localIp
cfg.LocalPort = localPort
cfg.BindAddr = bindAddr
cfg.BindPort = bindPort
cfg.UseEncryption = useEncryption
cfg.UseCompression = useCompression
......
......@@ -81,7 +81,7 @@ func init() {
rootCmd.PersistentFlags().StringVarP(&logWay, "log_way", "", "console", "log way")
rootCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
rootCmd.PersistentFlags().Int64VarP(&logMaxDays, "log_max_days", "", 3, "log_max_days")
rootCmd.PersistentFlags().StringVarP(&token, "token", "", "", "auth token")
rootCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
rootCmd.PersistentFlags().Int64VarP(&authTimeout, "auth_timeout", "", 900, "auth timeout")
rootCmd.PersistentFlags().StringVarP(&subDomainHost, "subdomain_host", "", "", "subdomain host")
rootCmd.PersistentFlags().Int64VarP(&maxPortsPerClient, "max_ports_per_client", "", 0, "max ports per client")
......
......@@ -262,7 +262,7 @@ func (cfg *DomainConf) checkForSvr() (err error) {
if cfg.SubDomain != "" {
if subDomainHost == "" {
return fmt.Errorf("subdomain is not supported because this feature is not enabled by frps")
return fmt.Errorf("subdomain is not supported because this feature is not enabled in remote frps")
}
if strings.Contains(cfg.SubDomain, ".") || strings.Contains(cfg.SubDomain, "*") {
return fmt.Errorf("'.' and '*' is not supported in subdomain")
......@@ -509,7 +509,7 @@ func (cfg *HttpProxyConf) CheckForCli() (err error) {
func (cfg *HttpProxyConf) CheckForSvr() (err error) {
if vhostHttpPort == 0 {
err = fmt.Errorf("type [http] not support when vhost_http_port is not set")
return fmt.Errorf("type [http] not support when vhost_http_port is not set")
}
if err = cfg.DomainConf.checkForSvr(); err != nil {
err = fmt.Errorf("proxy [%s] domain conf check error: %v", cfg.ProxyName, err)
......@@ -675,6 +675,10 @@ func (cfg *StcpProxyConf) CheckForCli() (err error) {
err = fmt.Errorf("bind_addr shouldn't be empty")
return
}
if cfg.BindPort == 0 {
err = fmt.Errorf("bind_port should be set")
return
}
}
return
}
......@@ -777,6 +781,10 @@ func (cfg *XtcpProxyConf) CheckForCli() (err error) {
err = fmt.Errorf("bind_addr shouldn't be empty")
return
}
if cfg.BindPort == 0 {
err = fmt.Errorf("bind_port should be set")
return
}
}
return
}
......
......@@ -163,6 +163,7 @@ type NatHoleResp struct {
Sid string `json:"sid"`
VisitorAddr string `json:"visitor_addr"`
ClientAddr string `json:"client_addr"`
Error string `json:"error"`
}
type NatHoleSid struct {
......
......@@ -106,10 +106,21 @@ func (nc *NatHoleController) HandleVisitor(m *msg.NatHoleVisitor, raddr *net.UDP
}
nc.mu.Lock()
clientCfg, ok := nc.clientCfgs[m.ProxyName]
if !ok || m.SignKey != util.GetAuthKey(clientCfg.Sk, m.Timestamp) {
if !ok {
nc.mu.Unlock()
errInfo := fmt.Sprintf("xtcp server for [%s] doesn't exist", m.ProxyName)
log.Debug(errInfo)
nc.listener.WriteToUDP(nc.GenNatHoleResponse(nil, errInfo), raddr)
return
}
if m.SignKey != util.GetAuthKey(clientCfg.Sk, m.Timestamp) {
nc.mu.Unlock()
errInfo := fmt.Sprintf("xtcp connection of [%s] auth failed", m.ProxyName)
log.Debug(errInfo)
nc.listener.WriteToUDP(nc.GenNatHoleResponse(nil, errInfo), raddr)
return
}
nc.sessions[sid] = session
nc.mu.Unlock()
log.Trace("handle visitor message, sid [%s]", sid)
......@@ -130,7 +141,7 @@ func (nc *NatHoleController) HandleVisitor(m *msg.NatHoleVisitor, raddr *net.UDP
// Wait client connections.
select {
case <-session.NotifyCh:
resp := nc.GenNatHoleResponse(raddr, session)
resp := nc.GenNatHoleResponse(session, "")
log.Trace("send nat hole response to visitor")
nc.listener.WriteToUDP(resp, raddr)
case <-time.After(time.Duration(NatHoleTimeout) * time.Second):
......@@ -149,16 +160,27 @@ func (nc *NatHoleController) HandleClient(m *msg.NatHoleClient, raddr *net.UDPAd
session.ClientAddr = raddr
session.NotifyCh <- struct{}{}
resp := nc.GenNatHoleResponse(raddr, session)
resp := nc.GenNatHoleResponse(session, "")
log.Trace("send nat hole response to client")
nc.listener.WriteToUDP(resp, raddr)
}
func (nc *NatHoleController) GenNatHoleResponse(raddr *net.UDPAddr, session *NatHoleSession) []byte {
func (nc *NatHoleController) GenNatHoleResponse(session *NatHoleSession, errInfo string) []byte {
var (
sid string
visitorAddr string
clientAddr string
)
if session != nil {
sid = session.Sid
visitorAddr = session.VisitorAddr.String()
clientAddr = session.ClientAddr.String()
}
m := &msg.NatHoleResp{
Sid: session.Sid,
VisitorAddr: session.VisitorAddr.String(),
ClientAddr: session.ClientAddr.String(),
Sid: sid,
VisitorAddr: visitorAddr,
ClientAddr: clientAddr,
Error: errInfo,
}
b := bytes.NewBuffer(nil)
err := msg.WriteMsg(b, m)
......
......@@ -19,7 +19,7 @@ import (
"strings"
)
var version string = "0.19.0"
var version string = "0.19.1"
func Full() string {
return version
......@@ -48,8 +48,8 @@ func Minor(v string) int64 {
// add every case there if server will not accept client's protocol and return false
func Compat(client string) (ok bool, msg string) {
if LessThan(client, "0.10.0") {
return false, "Please upgrade your frpc version to at least 0.10.0"
if LessThan(client, "0.18.0") {
return false, "Please upgrade your frpc version to at least 0.18.0"
}
return true, ""
}
......
......@@ -61,5 +61,5 @@ func TestCompact(t *testing.T) {
assert.True(ok)
ok, _ = Compat("0.10.0")
assert.True(ok)
assert.False(ok)
}
......@@ -49,7 +49,6 @@ func getHostFromAddr(addr string) (host string) {
type HttpReverseProxy struct {
proxy *ReverseProxy
tr *http.Transport
vhostRouter *VhostRouters
......
{
"presets": [
["es2015", { "modules": false }]
],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
\ No newline at end of file
}
此差异已折叠。
......@@ -10,9 +10,9 @@
"dependencies": {
"bootstrap": "^3.3.7",
"echarts": "^3.5.0",
"element-ui": "^1.2.5",
"element-ui": "^2.3.8",
"humanize-plus": "^1.8.2",
"vue": "^2.2.4",
"vue": "^2.5.16",
"vue-resource": "^1.2.1",
"vue-router": "^2.3.0",
"whatwg-fetch": "^2.0.3"
......@@ -25,6 +25,7 @@
"babel-core": "^6.21.0",
"babel-eslint": "^7.1.1",
"babel-loader": "^6.4.0",
"babel-plugin-component": "^1.1.1",
"babel-preset-es2015": "^6.13.2",
"css-loader": "^0.27.0",
"eslint": "^3.12.2",
......@@ -33,15 +34,15 @@
"file-loader": "^0.10.1",
"html-loader": "^0.4.5",
"html-webpack-plugin": "^2.24.1",
"less": "^2.7.2",
"less-loader": "^3.0.0",
"less": "^3.0.4",
"less-loader": "^4.1.0",
"postcss-loader": "^1.3.3",
"rimraf": "^2.5.4",
"style-loader": "^0.13.2",
"url-loader": "^0.5.8",
"vue-loader": "^11.1.4",
"url-loader": "^1.0.1",
"vue-loader": "^15.0.10",
"vue-template-compiler": "^2.1.8",
"webpack": "^2.2.0-rc.4",
"webpack-dev-server": "^2.11.0"
"webpack-dev-server": "^3.1.4"
}
}
......@@ -2,7 +2,7 @@
<div>
<el-table :data="proxies" :default-sort="{prop: 'name', order: 'ascending'}" style="width: 100%">
<el-table-column type="expand">
<template scope="props">
<template slot-scope="props">
<el-popover
ref="popover4"
placement="right"
......@@ -79,7 +79,7 @@
label="status"
prop="status"
sortable>
<template scope="scope">
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.status === 'online'">{{ scope.row.status }}</el-tag>
<el-tag type="danger" v-else>{{ scope.row.status }}</el-tag>
</template>
......
......@@ -2,7 +2,7 @@
<div>
<el-table :data="proxies" :default-sort="{prop: 'name', order: 'ascending'}" style="width: 100%">
<el-table-column type="expand">
<template scope="props">
<template slot-scope="props">
<el-popover
ref="popover4"
placement="right"
......@@ -73,7 +73,7 @@
label="status"
prop="status"
sortable>
<template scope="scope">
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.status === 'online'">{{ scope.row.status }}</el-tag>
<el-tag type="danger" v-else>{{ scope.row.status }}</el-tag>
</template>
......
......@@ -2,7 +2,7 @@
<div>
<el-table :data="proxies" :default-sort="{prop: 'name', order: 'ascending'}" style="width: 100%">
<el-table-column type="expand">
<template scope="props">
<template slot-scope="props">
<el-popover
ref="popover4"
placement="right"
......@@ -70,7 +70,7 @@
label="status"
prop="status"
sortable>
<template scope="scope">
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.status === 'online'">{{ scope.row.status }}</el-tag>
<el-tag type="danger" v-else>{{ scope.row.status }}</el-tag>
</template>
......
......@@ -2,7 +2,7 @@
<div>
<el-table :data="proxies" :default-sort="{prop: 'name', order: 'ascending'}" style="width: 100%">
<el-table-column type="expand">
<template scope="props">
<template slot-scope="props">
<el-popover
ref="popover4"
placement="right"
......@@ -70,7 +70,7 @@
label="status"
prop="status"
sortable>
<template scope="scope">
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.status === 'online'">{{ scope.row.status }}</el-tag>
<el-tag type="danger" v-else>{{ scope.row.status }}</el-tag>
</template>
......
import Vue from 'vue'
import ElementUI from 'element-ui'
import locale from 'element-ui/lib/locale/lang/en'
import 'element-ui/lib/theme-default/index.css'
//import ElementUI from 'element-ui'
import {
Button,
Form,
FormItem,
Row,
Col,
Table,
TableColumn,
Popover,
Menu,
Submenu,
MenuItem,
Tag
} from 'element-ui'
import lang from 'element-ui/lib/locale/lang/en'
import locale from 'element-ui/lib/locale'
import 'element-ui/lib/theme-chalk/index.css'
import './utils/less/custom.less'
import App from './App.vue'
import router from './router'
import 'whatwg-fetch'
Vue.use(ElementUI, { locale })
locale.use(lang)
Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Row)
Vue.use(Col)
Vue.use(Table)
Vue.use(TableColumn)
Vue.use(Popover)
Vue.use(Menu)
Vue.use(Submenu)
Vue.use(MenuItem)
Vue.use(Tag)
Vue.config.productionTip = false
new Vue({
......
import Vue from 'vue'
import ElementUI from 'element-ui'
\ No newline at end of file
const path = require('path')
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var VueLoaderPlugin = require('vue-loader/lib/plugin')
var url = require('url')
var publicPath = ''
module.exports = (options = {}) => ({
entry: {
vendor: './src/vendor',
index: './src/main.js'
vendor: './src/main'
},
output: {
path: path.resolve(__dirname, 'dist'),
......@@ -25,7 +25,7 @@ module.exports = (options = {}) => ({
module: {
rules: [{
test: /\.vue$/,
use: ['vue-loader']
loader: 'vue-loader'
}, {
test: /\.js$/,
use: ['babel-loader'],
......@@ -71,7 +71,21 @@ module.exports = (options = {}) => ({
new HtmlWebpackPlugin({
favicon: 'src/assets/favicon.ico',
template: 'src/index.html'
})
}),
new webpack.NormalModuleReplacementPlugin(/element-ui[\/\\]lib[\/\\]locale[\/\\]lang[\/\\]zh-CN/, 'element-ui/lib/locale/lang/en'),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: false,
comments: false,
compress: {
warnings: false
}
}),
new VueLoaderPlugin()
],
devServer: {
host: '127.0.0.1',
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册