Guest User

Untitled

a guest
Jul 22nd, 2018
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.17 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. "io/ioutil"
  7. "net"
  8. "crypto/sha256"
  9. "io"
  10. "crypto/rand"
  11. "crypto/rc4"
  12. "bytes"
  13. "encoding/binary"
  14. "sync"
  15. "time"
  16. "runtime"
  17. pseudoRand "math/rand"
  18. "os"
  19. "os/signal"
  20. "crypto/md5"
  21. )
  22.  
  23. func errorPanic(err error, format string, a ...interface{}) {
  24. if err != nil {
  25. fmt.Errorf(format, a)
  26. panic(err)
  27. }
  28. }
  29.  
  30. type vxlanHeader struct {
  31. flags uint16
  32. group uint16
  33. vxlanId uint32
  34. }
  35.  
  36. type Config struct {
  37. UpLinkPort int `json:"upLocalPort"`
  38. UpLinkRemote string `json:"upRemoteIp"`
  39. UpLinkRemotePort int `json:"upRemotePort"`
  40. LocalSocketPoolSize int `json:"poolSize"`
  41. LocalPoolUpdateTime int `json:"poolUpdate"`
  42. DownLinkPort int `json:"downPort"`
  43. DownLinkRemote string `json:"downRemoteIp"`
  44. DownLinkRemotePort int `json:"downRemotePort"`
  45. Key string `json:"key"`
  46. VxlanId uint32 `json:"vxlanId"`
  47. }
  48.  
  49. func (c *Config) load(f string) {
  50. jsonBytes, err := ioutil.ReadFile(f)
  51. errorPanic(err, "open file %s error %+v \n", f, err)
  52. err = json.Unmarshal(jsonBytes, c)
  53. errorPanic(err, "Unmarshal file %s error %+v \n", f, err)
  54. }
  55.  
  56. const nonceSize int = 8
  57. const sumSize int = md5.Size
  58.  
  59. type NotSafeCipher struct {
  60. key []byte
  61. vxlanBytes []byte
  62. }
  63.  
  64. func newRc4(k string, vxlanId uint32) (*NotSafeCipher) {
  65. ret := NotSafeCipher{}
  66. keyHash := sha256.Sum256([]byte(k))
  67. ret.key = keyHash[:]
  68. h := &vxlanHeader{flags: 0x0800, group: 0, vxlanId: vxlanId * 256}
  69. buf := new(bytes.Buffer)
  70. err := binary.Write(buf, binary.BigEndian, h)
  71. errorPanic(err, "binary.Write error \n")
  72. binary.Write(buf, binary.BigEndian, h)
  73. ret.vxlanBytes = buf.Bytes()
  74. return &ret
  75. }
  76.  
  77. func (c *NotSafeCipher) getNonceKey(nonce []byte) []byte {
  78. sha := sha256.New()
  79. sha.Write(nonce)
  80. sha.Write(c.key)
  81. return sha.Sum(nil)
  82. }
  83.  
  84. func (c *NotSafeCipher) Encrypt(udpPackage []byte) error {
  85. plainData := udpPackage[nonceSize:]
  86. nonce := udpPackage[:nonceSize]
  87. udpData := udpPackage[nonceSize:len(udpPackage)-sumSize]
  88. sumData := udpPackage[len(udpPackage)-sumSize:]
  89. if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
  90. fmt.Errorf("rand.Reader error %+v \n", err)
  91. return err
  92. }
  93. nonceRc4, err := rc4.NewCipher(c.getNonceKey(nonce))
  94. if err != nil {
  95. fmt.Errorf("rc4.NewCipher error %+v \n", err)
  96. return err
  97. }
  98. checkSum := md5.Sum(udpData)
  99. copy(sumData, checkSum[:])
  100. nonceRc4.XORKeyStream(plainData, plainData)
  101. return nil
  102. }
  103.  
  104. type checkSumError struct {
  105. }
  106.  
  107. func (checkSumError) Error() string {
  108. return "checkSumError"
  109. }
  110.  
  111. func (c *NotSafeCipher) Decrypt(udpPackage []byte) error {
  112. cipherData := udpPackage[nonceSize:]
  113. nonce := udpPackage[:nonceSize]
  114. nonceRc4, err := rc4.NewCipher(c.getNonceKey(nonce))
  115. if err != nil {
  116. fmt.Errorf("rc4.NewCipher error %+v \n", err)
  117. return err
  118. }
  119. nonceRc4.XORKeyStream(cipherData, cipherData)
  120. udpData := udpPackage[nonceSize:len(udpPackage)-sumSize]
  121. sumData := udpPackage[len(udpPackage)-sumSize:]
  122. checkSum := md5.Sum(udpData)
  123. if bytes.Equal(sumData, checkSum[:]) == false {
  124. fmt.Errorf("check sum error\n")
  125. return checkSumError{}
  126. }
  127. copy(nonce, c.vxlanBytes)
  128. return nil
  129. }
  130.  
  131. type UpLinkSrever struct {
  132. listenConn *net.UDPConn
  133. clientPool []*net.UDPConn
  134. sync.RWMutex
  135. rc4 *NotSafeCipher
  136. conf *Config
  137. plainChan chan []byte
  138. cipherChan chan []byte
  139. stopChan chan interface{}
  140. }
  141.  
  142. func getUdpConn(port int) (ret *net.UDPConn, err error) {
  143. ret, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("0.0.0.0"), Port: port})
  144. return
  145. }
  146.  
  147. func newUpServer(c *Config) *UpLinkSrever {
  148. var err error = nil
  149. ret := &UpLinkSrever{}
  150. ret.conf = c
  151. ret.listenConn, err = getUdpConn(c.UpLinkPort)
  152. errorPanic(err, "creat UpLinkPort listenConn error \n")
  153. err = ret.upDatePool()
  154. errorPanic(err, "creat pool error \n")
  155. ret.rc4 = newRc4(c.Key, c.VxlanId)
  156. ret.stopChan = make(chan interface{}, 2)
  157. ret.plainChan = make(chan []byte, 5000)
  158. ret.cipherChan = make(chan []byte, 5000)
  159. go ret.handleSend()
  160. for i := 0; i < runtime.NumCPU(); i++ {
  161. go ret.handleEncrypt()
  162. }
  163. go ret.handleListen()
  164. go ret.updateTimer()
  165. return ret
  166. }
  167.  
  168. func (s *UpLinkSrever) handleSend() {
  169. cipherChan := s.cipherChan
  170. poolSize := s.conf.LocalSocketPoolSize
  171. remoteAddr := &net.UDPAddr{IP: net.ParseIP(s.conf.UpLinkRemote), Port: s.conf.UpLinkRemotePort}
  172. stopChan := s.stopChan
  173. for {
  174. select {
  175. case udpPackage, ok := <-cipherChan:
  176. if ok == false {
  177. fmt.Errorf("upLink cipherChan broken, exit\n")
  178. return
  179. }
  180. pos := pseudoRand.Intn(poolSize)
  181. s.RLock()
  182. conn := s.clientPool[pos]
  183. if _, err := conn.WriteToUDP(udpPackage, remoteAddr); err != nil {
  184. fmt.Errorf("up link conn.WriteToUDP error %+v \n", err)
  185. }
  186. s.RUnlock()
  187. case <-stopChan:
  188. return
  189. }
  190. }
  191. }
  192.  
  193. func (s *UpLinkSrever) handleEncrypt() {
  194. plainChan := s.plainChan
  195. cipherChan := s.cipherChan
  196. rc4Cipher := s.rc4
  197. stopChan := s.stopChan
  198. for {
  199. select {
  200. case udpPackage, ok := <-plainChan:
  201. if ok == false {
  202. fmt.Errorf("upLink plainChan broken, exit\n")
  203. return
  204. }
  205. if err := rc4Cipher.Encrypt(udpPackage); err != nil {
  206. fmt.Errorf("Encrypt error, drop package \n")
  207. } else {
  208. cipherChan <- udpPackage
  209. }
  210. case <-stopChan:
  211. return
  212. }
  213. }
  214. }
  215.  
  216. func (s *UpLinkSrever) handleListen() {
  217. listenConn := s.listenConn
  218. plainChan := s.plainChan
  219. for {
  220. data := make([]byte, 1500)
  221. n, _, err := listenConn.ReadFromUDP(data)
  222. if err != nil {
  223. fmt.Errorf("error in upLink listenConn.ReadFromUDP %+v \n", err)
  224. return
  225. }
  226. if (n + sumSize) > 1500 {
  227. fmt.Errorf("package is too large, pls reduce your vxlan mtu\n")
  228. continue
  229. }
  230. plainChan <- data[:n + sumSize]
  231. }
  232. }
  233.  
  234. func (s *UpLinkSrever) updateTimer() {
  235. delay := time.Duration(s.conf.LocalPoolUpdateTime)
  236. t := time.NewTimer(delay * time.Second)
  237. stopChan := s.stopChan
  238. for {
  239. select {
  240. case <-t.C:
  241. if err := s.upDatePool(); err != nil {
  242. fmt.Errorf("error in upDatePool %+v \n", err)
  243. t.Reset(delay / 2 * time.Second)
  244. } else {
  245. t.Reset(delay * time.Second)
  246. }
  247. case <-stopChan:
  248. return
  249. }
  250. }
  251. }
  252.  
  253. func (s *UpLinkSrever) upDatePool() (err error) {
  254. err = nil
  255. newPool := make([]*net.UDPConn, s.conf.LocalSocketPoolSize)
  256. defer func() {
  257. if newPool == nil {
  258. return
  259. }
  260. for _, conn := range newPool {
  261. if conn != nil {
  262. conn.Close()
  263. }
  264. }
  265. }()
  266. for i := range newPool {
  267. newPool[i], err = getUdpConn(0)
  268. if err != nil {
  269. return
  270. }
  271. }
  272. s.Lock()
  273. defer s.Unlock()
  274. s.clientPool, newPool = newPool, s.clientPool
  275. return
  276. }
  277.  
  278. func (s *UpLinkSrever) getListenConn() *net.UDPConn {
  279. return s.listenConn
  280. }
  281.  
  282. func (s *UpLinkSrever) stop() {
  283. close(s.stopChan)
  284. close(s.plainChan)
  285. close(s.cipherChan)
  286. s.listenConn.Close()
  287. for _, conn := range s.clientPool {
  288. conn.Close()
  289. }
  290. }
  291.  
  292. type DownLinkSrever struct {
  293. listenConn *net.UDPConn
  294. sendConn *net.UDPConn
  295. rc4 *NotSafeCipher
  296. conf *Config
  297. plainChan chan []byte
  298. cipherChan chan []byte
  299. stopChan chan interface{}
  300. }
  301.  
  302. func newDownServer(c *Config, sendConn *net.UDPConn) *DownLinkSrever {
  303. ret := &DownLinkSrever{}
  304. var err error = nil
  305. ret.sendConn = sendConn
  306. ret.listenConn, err = getUdpConn(c.DownLinkPort)
  307. errorPanic(err, "creat DownLinkPort listenConn error \n")
  308. ret.rc4 = newRc4(c.Key, c.VxlanId)
  309. ret.conf = c
  310. ret.plainChan = make(chan []byte, 5000)
  311. ret.cipherChan = make(chan []byte, 5000)
  312. ret.stopChan = make(chan interface{}, 2)
  313. go ret.handleSend()
  314. for i := 0; i < runtime.NumCPU(); i++ {
  315. go ret.handleEncrypt()
  316. }
  317. go ret.handleListen()
  318. return ret
  319. }
  320.  
  321. func (s *DownLinkSrever) handleSend() {
  322. plainChan := s.plainChan
  323. stopChan := s.stopChan
  324. conn := s.sendConn
  325. remoteAddr := &net.UDPAddr{IP: net.ParseIP(s.conf.DownLinkRemote), Port: s.conf.DownLinkRemotePort}
  326. for {
  327. select {
  328. case udpPackage, ok := <-plainChan:
  329. if ok == false {
  330. fmt.Errorf("downLink plainChan broken \n")
  331. return
  332. }
  333. if _, err := conn.WriteToUDP(udpPackage, remoteAddr); err != nil {
  334. fmt.Errorf("up link conn.WriteToUDP error %+v \n", err)
  335. }
  336. case <- stopChan:
  337. return
  338. }
  339. }
  340. }
  341.  
  342. func (s *DownLinkSrever) handleEncrypt() {
  343. plainChan := s.plainChan
  344. cipherChan := s.cipherChan
  345. rc4Cipher := s.rc4
  346. stopChan := s.stopChan
  347. for {
  348. select {
  349. case udpPackage, ok := <-cipherChan:
  350. if ok == false {
  351. fmt.Errorf("upLink plainChan broken\n")
  352. return
  353. }
  354. if len(udpPackage) < nonceSize + sumSize + 16 {
  355. fmt.Errorf("size error, drop package \n")
  356. continue
  357. }
  358. if err := rc4Cipher.Decrypt(udpPackage); err != nil {
  359. fmt.Errorf("Encrypt error, drop package \n")
  360. } else {
  361. plainChan <- udpPackage[:len(udpPackage) - sumSize]
  362. }
  363. case <-stopChan:
  364. return
  365. }
  366. }
  367. }
  368.  
  369. func (s *DownLinkSrever) handleListen() {
  370. listenConn := s.listenConn
  371. cipherChan := s.cipherChan
  372. for {
  373. data := make([]byte, 1500)
  374. n, _, err := listenConn.ReadFromUDP(data)
  375. if err != nil {
  376. fmt.Errorf("error in downLink listenConn.ReadFromUDP %+v \n", err)
  377. return
  378. }
  379. cipherChan <- data[:n]
  380. }
  381. }
  382.  
  383. func (s *DownLinkSrever) stop() {
  384. close(s.stopChan)
  385. close(s.plainChan)
  386. close(s.cipherChan)
  387. s.listenConn.Close()
  388. }
  389.  
  390. func main() {
  391. pseudoRand.Seed(time.Now().Unix())
  392. c := &Config{}
  393. if len(os.Args) > 1 {
  394. c.load(os.Args[1])
  395. } else {
  396. c.load("./conf.json")
  397. }
  398. up := newUpServer(c)
  399. down := newDownServer(c, up.getListenConn())
  400. signalChan := make(chan os.Signal, 2)
  401. signal.Notify(signalChan, os.Interrupt)
  402. <-signalChan
  403. up.stop()
  404. down.stop()
  405. }
Add Comment
Please, Sign In to add comment