client.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. package main
  2. /*
  3. #cgo CFLAGS: -O2
  4. #cgo LDFLAGS: -lcrypto -lm
  5. #include "../c/dpf.h"
  6. #include "../c/okvClient.h"
  7. #include "../c/dpf.c"
  8. #include "../c/okvClient.c"
  9. */
  10. import "C"
  11. //sssssssssssss
  12. import (
  13. "2PPS/lib"
  14. "bytes"
  15. "crypto/rand"
  16. "crypto/sha256"
  17. "crypto/tls"
  18. "encoding/json"
  19. "fmt"
  20. "math/big"
  21. mr "math/rand"
  22. "net"
  23. "sort"
  24. "strconv"
  25. "strings"
  26. "sync"
  27. "time"
  28. "unsafe"
  29. "golang.org/x/crypto/nacl/box"
  30. )
  31. type tweet struct {
  32. Topics []string
  33. Text string
  34. }
  35. const leader string = "127.0.0.1:4441"
  36. //needs to be changed at leader/follower/client at the same time
  37. const numClients = 200
  38. const dataLength int = 128
  39. const numThreads int = 12
  40. //Maximum Transport Unit
  41. const mtu int = 1100
  42. var dbWriteSize int
  43. var round int
  44. var topicList []string
  45. var archiveTopicList []string
  46. var neededSubscriptions int
  47. //todo! expand this for multiple clients
  48. var archiveInterests = make([]int, 1)
  49. var sharedSecret [numClients][2][32]byte = createSharedSecret()
  50. var wantsArchive = make([]byte, 1)
  51. var leaderPublicKey *[32]byte
  52. var followerPublicKey *[32]byte
  53. var clientPrivateKey [numClients]*[32]byte
  54. var clientPublicKey [numClients]*[32]byte
  55. func main() {
  56. wg := &sync.WaitGroup{}
  57. for i := 0; i < numClients; i++ {
  58. wg.Add(1)
  59. go client(i)
  60. }
  61. wg.Wait()
  62. }
  63. func client(clientNumber int) {
  64. generatedPublicKey, generatedPrivateKey, err := box.GenerateKey(rand.Reader)
  65. if err != nil {
  66. panic(err)
  67. }
  68. clientPrivateKey[clientNumber] = generatedPrivateKey
  69. clientPublicKey[clientNumber] = generatedPublicKey
  70. C.initializeCipher()
  71. //initializes the connection to the leader
  72. conf := &tls.Config{
  73. InsecureSkipVerify: true,
  74. }
  75. leaderConn, err := tls.Dial("tcp", leader, conf)
  76. if err != nil {
  77. panic(err)
  78. }
  79. leaderConn.SetDeadline(time.Time{})
  80. //receives topics first so client can participate asap
  81. receiveTopicLists(leaderConn)
  82. //gets the public keys of both servers
  83. var tmpLeaderPubKey [32]byte
  84. _, err = leaderConn.Read(tmpLeaderPubKey[:])
  85. if err != nil {
  86. panic(err)
  87. }
  88. leaderPublicKey = &tmpLeaderPubKey
  89. var tmpFollowerPubKey [32]byte
  90. _, err = leaderConn.Read(tmpFollowerPubKey[:])
  91. if err != nil {
  92. panic(err)
  93. }
  94. followerPublicKey = &tmpFollowerPubKey
  95. //sends own public key
  96. writeTo(leaderConn, clientPublicKey[clientNumber][:])
  97. neededSubscriptionsBytes := readFrom(leaderConn, 4)
  98. neededSubscriptions = byteToInt(neededSubscriptionsBytes)
  99. //setup ends above
  100. //while client is active he is always connected and has to participate
  101. for {
  102. //gets current phase
  103. phase := readFrom(leaderConn, 1)
  104. //fmt.Println("Phase ", phase[0])
  105. if phase[0] == 1 {
  106. //gets current dbWriteSize from leader
  107. dbWriteSizeBytes := readFrom(leaderConn, 4)
  108. dbWriteSize = byteToInt(dbWriteSizeBytes)
  109. //todo! put into tweet creation
  110. //roundAsBytes := readFrom(leaderConn, 4)
  111. roundAsBytes := make([]byte, 4)
  112. _, err = leaderConn.Read(roundAsBytes)
  113. if err != nil {
  114. panic(err)
  115. }
  116. round = byteToInt(roundAsBytes)
  117. //request virtualAddress from leader via pirQuery
  118. encryptedQueryLeader, encryptedQueryFollower := createAuditPIRQuery(clientNumber)
  119. sendQuerys(encryptedQueryLeader, encryptedQueryFollower, leaderConn, false)
  120. pos := receiveVirtualAddress(sharedSecret[clientNumber], leaderConn)
  121. tweet := getTweet(clientNumber)
  122. //prep the query
  123. dataSize := len(tweet)
  124. querySize := make([]byte, 4)
  125. cQuerySize := C.int(byteToInt(querySize))
  126. var dpfQueryA *C.uchar
  127. var dpfQueryB *C.uchar
  128. C.prepQuery(C.int(pos), C.int(dbWriteSize), (*C.uchar)(&tweet[0]), C.int(dataSize), &cQuerySize, &dpfQueryA, &dpfQueryB)
  129. intQuerySize := int(cQuerySize) //byteToInt(querySize)
  130. //write the query
  131. queryAPlaintext := C.GoBytes(unsafe.Pointer(dpfQueryA), C.int(intQuerySize))
  132. //encrypts queryA and appends it to message
  133. var nonce [24]byte
  134. //fill nonce with randomness
  135. _, err = rand.Read(nonce[:])
  136. if err != nil {
  137. panic("couldn't get randomness for nonce!")
  138. }
  139. dpfQueryAEncrypted := box.Seal(nonce[:], queryAPlaintext, &nonce, leaderPublicKey, clientPrivateKey[clientNumber])
  140. //encrypts queryB and appends it to message
  141. queryBPlaintext := C.GoBytes(unsafe.Pointer(dpfQueryB), C.int(intQuerySize))
  142. //fill nonce with randomness
  143. _, err = rand.Read(nonce[:])
  144. if err != nil {
  145. panic("couldn't get randomness for nonce!")
  146. }
  147. dpfQueryBEncrypted := box.Seal(nonce[:], queryBPlaintext, &nonce, followerPublicKey, clientPrivateKey[clientNumber])
  148. //writes the dpfQuery to the leader
  149. dpfLengthBytes := intToByte(len(dpfQueryAEncrypted))
  150. writeTo(leaderConn, dpfLengthBytes)
  151. writeTo(leaderConn, dpfQueryAEncrypted)
  152. writeTo(leaderConn, dpfQueryBEncrypted)
  153. C.free(unsafe.Pointer(dpfQueryA))
  154. C.free(unsafe.Pointer(dpfQueryB))
  155. } else if phase[0] == 3 {
  156. /*
  157. possible Values
  158. 0 : new client
  159. leader expects sharedSecrets, expects pirQuery
  160. 1 : update needed
  161. leader sends topicList, performs local update of sharedSecret, expects pirQuery
  162. 2 : no update needed
  163. nothing
  164. */
  165. subPhase := readFrom(leaderConn, 1)
  166. var encryptedQueryLeader, encryptedQueryFollower []byte
  167. //first time participating
  168. if subPhase[0] == 0 {
  169. receiveTopicLists(leaderConn)
  170. encryptedQueryLeader, encryptedQueryFollower = createPIRQuery(int(subPhase[0]), clientNumber)
  171. sendQuerys(encryptedQueryLeader, encryptedQueryFollower, leaderConn, false)
  172. }
  173. //updates the topic list and what client is interested in
  174. if subPhase[0] == 1 {
  175. receiveTopicLists(leaderConn)
  176. //updates local secret
  177. for index := 0; index < 2; index++ {
  178. sharedSecret[clientNumber][index] = sha256.Sum256(sharedSecret[clientNumber][index][:])
  179. }
  180. encryptedQueryLeader, encryptedQueryFollower = createPIRQuery(int(subPhase[0]), clientNumber)
  181. sendQuerys(encryptedQueryLeader, encryptedQueryFollower, leaderConn, false)
  182. }
  183. receiveTweets(sharedSecret[clientNumber], leaderConn, false, clientNumber)
  184. if len(archiveTopicList) > 0 {
  185. wantsArchive[0] = 0 //archive test
  186. } else {
  187. wantsArchive[0] = 0
  188. }
  189. writeTo(leaderConn, wantsArchive)
  190. if wantsArchive[0] == 1 && len(archiveTopicList) > 0 {
  191. encryptedQueryLeader, encryptedQueryFollower = createPIRQuery(-1, clientNumber)
  192. sendQuerys(encryptedQueryLeader, encryptedQueryFollower, leaderConn, true)
  193. receiveTweets(sharedSecret[clientNumber], leaderConn, true, clientNumber)
  194. }
  195. } else {
  196. fmt.Println("Phase", phase)
  197. panic("somethin went wrong")
  198. }
  199. }
  200. }
  201. //creates and sends the pirQuerys for each server
  202. func createPIRQuery(subPhase int, clientNumber int) ([]byte, []byte) {
  203. //later this will be taken from gui, this is only for testing
  204. topicsOFInterest := make([]int, 10)
  205. topicsOFInterest[0] = 0
  206. topicsOFInterest[1] = 1
  207. topicsOFInterest[9] = 1
  208. archiveInterests[0] = 1
  209. //todo! repeat for archive
  210. tmpNeededSubscriptions := neededSubscriptions
  211. if tmpNeededSubscriptions > len(topicList) {
  212. tmpNeededSubscriptions = len(topicList)
  213. }
  214. tmptopicsOfInterest := make([]int, len(topicList))
  215. copy(tmptopicsOfInterest, topicsOFInterest)
  216. tmpTopicList := make([]string, len(topicList))
  217. copy(tmpTopicList, topicList)
  218. if wantsArchive[0] == 1 && subPhase == -1 {
  219. tmpNeededSubscriptions = len(archiveInterests)
  220. if tmpNeededSubscriptions > len(archiveTopicList) {
  221. tmpNeededSubscriptions = len(archiveTopicList)
  222. }
  223. copy(tmptopicsOfInterest, archiveInterests) //archiveInterests from gui
  224. copy(tmpTopicList, archiveTopicList)
  225. }
  226. //creates fake topicsOfInterest if client is boooring
  227. if len(tmptopicsOfInterest) < tmpNeededSubscriptions && subPhase != -1 {
  228. tmptopicsOfInterest = addFakeInterests(len(tmpTopicList), tmptopicsOfInterest, false)
  229. }
  230. //pirQuery [topicsofinterest][serverAmount][topicAmount]byte
  231. pirQuerys := make([][][]byte, len(tmptopicsOfInterest))
  232. for i := range pirQuerys {
  233. pirQuerys[i] = make([][]byte, 2)
  234. for j := range pirQuerys[i] {
  235. pirQuerys[i][j] = make([]byte, len(tmpTopicList))
  236. }
  237. }
  238. //for leader
  239. //pirQuery will be filled with random bits
  240. for topic := range tmptopicsOfInterest {
  241. for index := range tmpTopicList {
  242. bit, err := rand.Int(rand.Reader, big.NewInt(2))
  243. if err != nil {
  244. panic(err)
  245. }
  246. pirQuerys[topic][0][index] = byte(bit.Int64())
  247. }
  248. }
  249. tmptopicsOfInterestBytes := make([]byte, tmpNeededSubscriptions)
  250. for index := range tmptopicsOfInterestBytes {
  251. if tmptopicsOfInterest[index] == 1 {
  252. tmptopicsOfInterestBytes[index] = 1
  253. }
  254. }
  255. for topic := range tmptopicsOfInterest {
  256. for index := range tmpTopicList {
  257. if topic == index {
  258. if pirQuerys[topic][0][index] == 1 {
  259. pirQuerys[topic][1][index] = 0
  260. } else {
  261. pirQuerys[topic][1][index] = 1
  262. }
  263. } else {
  264. if pirQuerys[topic][0][index] == 0 {
  265. pirQuerys[topic][1][index] = 0
  266. } else {
  267. pirQuerys[topic][1][index] = 1
  268. }
  269. }
  270. }
  271. }
  272. //flattens the querys to be able to send them more efficently
  273. messagesFlattened := make([][]byte, 2)
  274. //adds the sharedSecret to the first pirQuery when first time participating
  275. if subPhase == 0 {
  276. for server := 0; server < 2; server++ {
  277. messagesFlattened[server] = append(messagesFlattened[server], sharedSecret[clientNumber][server][:]...)
  278. }
  279. }
  280. for server := range messagesFlattened {
  281. for topic := range pirQuerys {
  282. messagesFlattened[server] = append(messagesFlattened[server], pirQuerys[topic][server]...)
  283. }
  284. }
  285. var nonce [24]byte
  286. _, err := rand.Read(nonce[:])
  287. if err != nil {
  288. panic("couldn't get randomness for nonce!")
  289. }
  290. encryptedQueryLeader := box.Seal(nonce[:], messagesFlattened[0], &nonce, leaderPublicKey, clientPrivateKey[clientNumber])
  291. _, err = rand.Read(nonce[:])
  292. if err != nil {
  293. panic("couldn't get randomness for nonce!")
  294. }
  295. encryptedQueryFollower := box.Seal(nonce[:], messagesFlattened[1], &nonce, followerPublicKey, clientPrivateKey[clientNumber])
  296. return encryptedQueryLeader, encryptedQueryFollower
  297. }
  298. func sendQuerys(encryptedQueryLeader, encryptedQueryFollower []byte, leaderConn net.Conn, getArchive bool) {
  299. encryptedLength := len(encryptedQueryLeader)
  300. //sends the pirQuerysLength to the leader
  301. writeTo(leaderConn, intToByte(encryptedLength))
  302. //sends the pirQuerys to the leader
  303. writeTo(leaderConn, encryptedQueryLeader)
  304. writeTo(leaderConn, encryptedQueryFollower)
  305. if getArchive {
  306. writeTo(leaderConn, intToByte(len(archiveInterests)))
  307. }
  308. }
  309. func receiveVirtualAddress(sharedSecret [2][32]byte, leaderConn net.Conn) int {
  310. virtualAddressByte := readFrom(leaderConn, 4)
  311. //xores the sharedSecret
  312. for h := 0; h < 2; h++ {
  313. for i := 0; i < 4; i++ {
  314. virtualAddressByte[i] = virtualAddressByte[i] ^ sharedSecret[h][i]
  315. }
  316. }
  317. return byteToInt(virtualAddressByte)
  318. }
  319. func receiveTweets(sharedSecret [2][32]byte, leaderConn net.Conn, getArchive bool, clientNumber int) {
  320. tmpNeededSubscriptions := neededSubscriptions
  321. if tmpNeededSubscriptions > len(topicList) {
  322. tmpNeededSubscriptions = len(topicList)
  323. }
  324. if getArchive {
  325. tmpNeededSubscriptions = len(archiveInterests)
  326. if tmpNeededSubscriptions > len(archiveTopicList) {
  327. tmpNeededSubscriptions = len(archiveTopicList)
  328. }
  329. }
  330. for i := 0; i < tmpNeededSubscriptions; i++ {
  331. //client receives tweets
  332. tweetsLengthBytes := readFrom(leaderConn, 4)
  333. tweetsLength := byteToInt(tweetsLengthBytes)
  334. tweets := readFrom(leaderConn, tweetsLength)
  335. //fmt.Println(tweets[:10])
  336. //expand sharedSecret so it is of right length
  337. expandBy := len(tweets) / 32
  338. expandedSharedSecrets := make([][]byte, 2)
  339. for i := 0; i < 2; i++ {
  340. for j := 0; j < expandBy; j++ {
  341. expandedSharedSecrets[i] = append(expandedSharedSecrets[i], sharedSecret[i][:]...)
  342. }
  343. }
  344. //xors the received messge into the message to display
  345. for i := 0; i < 2; i++ {
  346. lib.Xor(expandedSharedSecrets[i][:], tweets)
  347. }
  348. //fmt.Println("PubKey", clientPublicKey[clientNumber], "Bytes", tweets)
  349. index := strings.Index(string(tweets), ";;;")
  350. if index != -1 {
  351. fmt.Println("Round", round, "Tweets length", len(tweets))
  352. /*
  353. fmt.Println("Correct")
  354. fmt.Println("PubKey", clientPublicKey[clientNumber])
  355. text := string(tweets)[:index]
  356. fmt.Println("Round", round, "Text", text[:5], "Length", len(tweets))
  357. */
  358. } else {
  359. fmt.Println("error")
  360. fmt.Println("pubKey", clientPublicKey[clientNumber])
  361. fmt.Println("round", round, "text:", string(tweets[:5]), "length", len(tweets))
  362. return
  363. //panic("received text not of correct format")
  364. }
  365. }
  366. }
  367. //creates a shared secret for each server
  368. func createSharedSecret() [numClients][2][32]byte {
  369. var tmpSharedSecret [numClients][2][32]byte
  370. for i := 0; i < numClients; i++ {
  371. for j := 0; j < 2; j++ {
  372. _, err := rand.Read(tmpSharedSecret[i][j][:])
  373. if err != nil {
  374. panic("couldn't get randomness for sharedSecret!")
  375. }
  376. }
  377. }
  378. return tmpSharedSecret
  379. }
  380. func createAuditPIRQuery(clientNumber int) ([]byte, []byte) {
  381. //pirQuery [serverAmount][dbWriteSize]byte
  382. pirQuerys := make([][]byte, 2)
  383. for i := range pirQuerys {
  384. pirQuerys[i] = make([]byte, dbWriteSize)
  385. }
  386. //for leader
  387. //pirQuery will be filled with random bits
  388. for index := range pirQuerys[0] {
  389. bit := mr.Intn(2)
  390. pirQuerys[0][index] = byte(bit)
  391. }
  392. copy(pirQuerys[1], pirQuerys[0])
  393. //the positon the virtual address will be taken from
  394. pos := mr.Intn(dbWriteSize)
  395. pirQuerys[0][pos] = 1
  396. pirQuerys[1][pos] = 0
  397. //flattens the querys to be able to send them more efficently
  398. messagesFlattened := make([][]byte, 2)
  399. //adds the sharedSecret to the pirQuery
  400. for server := 0; server < 2; server++ {
  401. messagesFlattened[server] = append(messagesFlattened[server], sharedSecret[clientNumber][server][:]...)
  402. }
  403. for server := 0; server < 2; server++ {
  404. messagesFlattened[server] = append(messagesFlattened[server], pirQuerys[server][:]...)
  405. }
  406. var nonce [24]byte
  407. _, err := rand.Read(nonce[:])
  408. if err != nil {
  409. panic("couldn't get randomness for nonce!")
  410. }
  411. encryptedQueryLeader := box.Seal(nonce[:], messagesFlattened[0], &nonce, leaderPublicKey, clientPrivateKey[clientNumber])
  412. _, err = rand.Read(nonce[:])
  413. if err != nil {
  414. panic("couldn't get randomness for nonce!")
  415. }
  416. encryptedQueryFollower := box.Seal(nonce[:], messagesFlattened[1], &nonce, followerPublicKey, clientPrivateKey[clientNumber])
  417. return encryptedQueryLeader, encryptedQueryFollower
  418. }
  419. //generates a topicOfInterest array with random values
  420. func addFakeInterests(max int, topicsOfInterest []int, doAuditing bool) []int {
  421. tmpNeededSubscriptions := neededSubscriptions
  422. if tmpNeededSubscriptions > len(topicList) {
  423. tmpNeededSubscriptions = len(topicList)
  424. }
  425. fakeTopicsOfInterest := make([]int, tmpNeededSubscriptions)
  426. maxInt := max
  427. //fills the array with unique random ascending values ranging from 0 to max
  428. for i := 0; i < tmpNeededSubscriptions; i++ {
  429. fakeTopicsOfInterest[i] = mr.Intn(maxInt)
  430. for j := 0; j < i; j++ {
  431. if fakeTopicsOfInterest[i] == fakeTopicsOfInterest[j] {
  432. i--
  433. break
  434. }
  435. }
  436. }
  437. if doAuditing {
  438. sort.Ints(fakeTopicsOfInterest)
  439. return fakeTopicsOfInterest
  440. }
  441. //adds unique and new random numbers to topicOfInterests until length is satisfied
  442. for _, number := range fakeTopicsOfInterest {
  443. if !inList(number, topicsOfInterest) {
  444. topicsOfInterest = append(topicsOfInterest, number)
  445. }
  446. if len(topicsOfInterest) == tmpNeededSubscriptions {
  447. break
  448. }
  449. }
  450. sort.Ints(topicsOfInterest)
  451. return topicsOfInterest
  452. }
  453. func inList(number int, list []int) bool {
  454. for _, element := range list {
  455. if element == number {
  456. return true
  457. }
  458. }
  459. return false
  460. }
  461. func receiveTopicLists(leaderConn net.Conn) {
  462. for i := 0; i < 2; i++ {
  463. topicListLength := readFrom(leaderConn, 4)
  464. recTopicList := readFrom(leaderConn, byteToInt(topicListLength))
  465. var tmpTopicList []string
  466. arrayReader := bytes.NewReader(recTopicList[:])
  467. json.NewDecoder(arrayReader).Decode(&tmpTopicList)
  468. if i == 0 {
  469. topicList = tmpTopicList
  470. } else {
  471. archiveTopicList = tmpTopicList
  472. }
  473. }
  474. }
  475. func getTweet(clientNumber int) []byte {
  476. var tweet []byte
  477. r := mr.New(mr.NewSource(time.Now().UnixNano()))
  478. maxTopics := r.Intn(6)
  479. if maxTopics == 0 {
  480. maxTopics = 1
  481. }
  482. maxInt := numClients * 5
  483. topicNumbers := make([]int, maxTopics)
  484. //fills the array with unique random ascending values ranging from 0 to maxInt
  485. for i := 0; i < maxTopics; i++ {
  486. topicNumbers[i] = mr.Intn(maxInt)
  487. for j := 0; j < i; j++ {
  488. if topicNumbers[i] == topicNumbers[j] {
  489. i--
  490. break
  491. }
  492. }
  493. }
  494. sort.Ints(topicNumbers)
  495. //fmt.Println("topicNumbers", topicNumbers)
  496. var topics []byte
  497. topicIndex := 0
  498. for i := 0; i < len(topicNumbers)*2; i++ {
  499. if i%2 == 0 {
  500. topics = append(topics, byte(topicNumbers[topicIndex]))
  501. topicIndex++
  502. } else if i != (len(topicNumbers)*2)-1 {
  503. topics = append(topics, []byte(",")[0])
  504. }
  505. }
  506. topics = append(topics, []byte(";")[0])
  507. num := r.Intn(100)
  508. if num == 0 {
  509. num = 1
  510. }
  511. text := []byte(strconv.Itoa(num) + ";")
  512. tweet = append(tweet, topics...)
  513. tweet = append(tweet, text...)
  514. tweet = append(tweet, []byte(";")[0])
  515. //fmt.Println("writing", string(text))
  516. //adds padding
  517. length := dataLength - len(tweet)
  518. padding := make([]byte, length)
  519. rand.Read(padding)
  520. tweet = append(tweet, padding...)
  521. return tweet
  522. }
  523. //sends the array to the connection
  524. func writeTo(connection net.Conn, array []byte) {
  525. remainingLength := len(array)
  526. for remainingLength > 0 {
  527. if remainingLength >= mtu {
  528. _, err := connection.Write(array[:mtu])
  529. if err != nil {
  530. panic(err)
  531. }
  532. array = array[mtu:]
  533. remainingLength -= mtu
  534. } else {
  535. _, err := connection.Write(array)
  536. if err != nil {
  537. panic(err)
  538. }
  539. remainingLength = 0
  540. }
  541. }
  542. }
  543. //reads an array which is returned and of size "size" from the connection
  544. func readFrom(connection net.Conn, size int) []byte {
  545. var array []byte
  546. remainingSize := size
  547. for remainingSize > 0 {
  548. var err error
  549. toAppend := make([]byte, mtu)
  550. if remainingSize > mtu {
  551. _, err = connection.Read(toAppend)
  552. array = append(array, toAppend...)
  553. remainingSize -= mtu
  554. } else {
  555. _, err = connection.Read(toAppend[:remainingSize])
  556. array = append(array, toAppend[:remainingSize]...)
  557. remainingSize = 0
  558. }
  559. if err != nil {
  560. panic(err)
  561. }
  562. }
  563. return array
  564. }
  565. func intToByte(myInt int) (retBytes []byte) {
  566. retBytes = make([]byte, 4)
  567. retBytes[3] = byte((myInt >> 24) & 0xff)
  568. retBytes[2] = byte((myInt >> 16) & 0xff)
  569. retBytes[1] = byte((myInt >> 8) & 0xff)
  570. retBytes[0] = byte(myInt & 0xff)
  571. return
  572. }
  573. func byteToInt(myBytes []byte) (x int) {
  574. x = int(myBytes[3])<<24 + int(myBytes[2])<<16 + int(myBytes[1])<<8 + int(myBytes[0])
  575. return
  576. }