client.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  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. import (
  12. "2PPS/lib"
  13. "bufio"
  14. "bytes"
  15. "crypto/rand"
  16. "crypto/sha256"
  17. "crypto/tls"
  18. "encoding/json"
  19. "fmt"
  20. "log"
  21. "math/big"
  22. mr "math/rand"
  23. "net"
  24. "os"
  25. "sort"
  26. "strconv"
  27. "strings"
  28. "sync"
  29. "time"
  30. "unsafe"
  31. "golang.org/x/crypto/nacl/box"
  32. )
  33. type tweet struct {
  34. Topics []string
  35. Text string
  36. }
  37. const leader string = "127.0.0.1:4441"
  38. //needs to be changed at leader/client at the same time
  39. const numClients = 1000
  40. //mylimit=8000
  41. //sudo prlimit --nofile=$mylimit --pid $$; ulimit -n $mylimit
  42. //for every terminal
  43. const dataLength int = 256
  44. //Maximum Transport Unit
  45. const mtu int = 1100
  46. var dbWriteSize int
  47. var round int
  48. var topicList []string
  49. var archiveTopicList []string
  50. var neededSubscriptions int
  51. var publisherAmount int
  52. var goodPadding int
  53. var blocksReceived int
  54. var timeBounds []float64
  55. //this translates to a simulated round length of ~2h
  56. var speedUp float64 = 7200 / ((maxTimePerRound.Seconds()) * 3)
  57. var maxTimePerRound time.Duration = 1000 * time.Second
  58. var startTime int
  59. var archiveInterests = make([]int, 1)
  60. var sharedSecret [numClients][2][32]byte = createSharedSecret()
  61. var wantsArchive = make([]byte, 1)
  62. var leaderPublicKey *[32]byte
  63. var followerPublicKey *[32]byte
  64. var clientPrivateKey [numClients]*[32]byte
  65. var clientPublicKey [numClients]*[32]byte
  66. func main() {
  67. f, err := os.OpenFile("evalDataClient", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
  68. if err != nil {
  69. log.Fatalf("error opening file: %v", err)
  70. }
  71. defer f.Close()
  72. log.SetOutput(f)
  73. log.Println("simulated Duration", speedUp)
  74. wg := &sync.WaitGroup{}
  75. getTimeBounds()
  76. for i := 0; i < numClients; i++ {
  77. wg.Add(1)
  78. go client(i, f)
  79. time.Sleep(1 * time.Millisecond)
  80. }
  81. wg.Wait()
  82. }
  83. func client(clientNumber int, f *os.File) {
  84. generatedPublicKey, generatedPrivateKey, err := box.GenerateKey(rand.Reader)
  85. if err != nil {
  86. panic(err)
  87. }
  88. clientPrivateKey[clientNumber] = generatedPrivateKey
  89. clientPublicKey[clientNumber] = generatedPublicKey
  90. C.initializeCipher()
  91. //initializes the connection to the leader
  92. conf := &tls.Config{
  93. InsecureSkipVerify: true,
  94. }
  95. leaderConn, err := tls.Dial("tcp", leader, conf)
  96. if err != nil {
  97. panic(err)
  98. }
  99. leaderConn.SetDeadline(time.Time{})
  100. //receives topics first so client can participate asap
  101. receiveTopicLists(leaderConn)
  102. //gets the public keys of both servers
  103. var tmpLeaderPubKey [32]byte
  104. _, err = leaderConn.Read(tmpLeaderPubKey[:])
  105. if err != nil {
  106. panic(err)
  107. }
  108. leaderPublicKey = &tmpLeaderPubKey
  109. var tmpFollowerPubKey [32]byte
  110. _, err = leaderConn.Read(tmpFollowerPubKey[:])
  111. if err != nil {
  112. panic(err)
  113. }
  114. followerPublicKey = &tmpFollowerPubKey
  115. //sends own public key
  116. writeTo(leaderConn, clientPublicKey[clientNumber][:])
  117. neededSubscriptionsBytes := readFrom(leaderConn, 4)
  118. neededSubscriptions = byteToInt(neededSubscriptionsBytes)
  119. startTimeBytes := readFrom(leaderConn, 4)
  120. startTime = byteToInt(startTimeBytes)
  121. //setup ends above
  122. //while client is active he is always connected and has to participate
  123. for {
  124. //gets current phase
  125. phase := readFrom(leaderConn, 1)
  126. if phase[0] == 1 {
  127. //gets current dbWriteSize from leader
  128. dbWriteSizeBytes := readFrom(leaderConn, 4)
  129. dbWriteSize = byteToInt(dbWriteSizeBytes)
  130. //roundAsBytes := readFrom(leaderConn, 4)
  131. roundAsBytes := make([]byte, 4)
  132. _, err = leaderConn.Read(roundAsBytes)
  133. if err != nil {
  134. panic(err)
  135. }
  136. round = byteToInt(roundAsBytes)
  137. if clientNumber == 0 {
  138. fmt.Println("Round ", round)
  139. }
  140. //request virtualAddress from leader via pirQuery
  141. encryptedQueryLeader, encryptedQueryFollower := createAuditPIRQuery(clientNumber)
  142. sendQuerys(encryptedQueryLeader, encryptedQueryFollower, leaderConn, false)
  143. pos := receiveVirtualAddress(sharedSecret[clientNumber], leaderConn)
  144. tweet := getRealTweet(clientNumber)
  145. if clientNumber == numClients-1 {
  146. log.Println("Round", round)
  147. log.Println("publisherAmount", publisherAmount)
  148. log.Println("goodPadding", goodPadding)
  149. log.Println("blocksReceived", blocksReceived)
  150. log.Println("goodPadding Percentage", float64(goodPadding)/float64(blocksReceived))
  151. publisherAmount = 0
  152. }
  153. //prep the query
  154. dataSize := len(tweet)
  155. querySize := make([]byte, 4)
  156. cQuerySize := C.int(byteToInt(querySize))
  157. var dpfQueryA *C.uchar
  158. var dpfQueryB *C.uchar
  159. C.prepQuery(C.int(pos), C.int(dbWriteSize), (*C.uchar)(&tweet[0]), C.int(dataSize), &cQuerySize, &dpfQueryA, &dpfQueryB)
  160. intQuerySize := int(cQuerySize) //byteToInt(querySize)
  161. //write the query
  162. queryAPlaintext := C.GoBytes(unsafe.Pointer(dpfQueryA), C.int(intQuerySize))
  163. //encrypts queryA and appends it to message
  164. var nonce [24]byte
  165. //fill nonce with randomness
  166. _, err = rand.Read(nonce[:])
  167. if err != nil {
  168. panic("couldn't get randomness for nonce!")
  169. }
  170. dpfQueryAEncrypted := box.Seal(nonce[:], queryAPlaintext, &nonce, leaderPublicKey, clientPrivateKey[clientNumber])
  171. //encrypts queryB and appends it to message
  172. queryBPlaintext := C.GoBytes(unsafe.Pointer(dpfQueryB), C.int(intQuerySize))
  173. //fill nonce with randomness
  174. _, err = rand.Read(nonce[:])
  175. if err != nil {
  176. panic("couldn't get randomness for nonce!")
  177. }
  178. dpfQueryBEncrypted := box.Seal(nonce[:], queryBPlaintext, &nonce, followerPublicKey, clientPrivateKey[clientNumber])
  179. //writes the dpfQuery to the leader
  180. dpfLengthBytes := intToByte(len(dpfQueryAEncrypted))
  181. writeTo(leaderConn, dpfLengthBytes)
  182. writeTo(leaderConn, dpfQueryAEncrypted)
  183. writeTo(leaderConn, dpfQueryBEncrypted)
  184. C.free(unsafe.Pointer(dpfQueryA))
  185. C.free(unsafe.Pointer(dpfQueryB))
  186. } else if phase[0] == 3 {
  187. /*
  188. possible Values
  189. 0 : new client
  190. leader expects sharedSecrets, expects pirQuery
  191. 1 : update needed
  192. leader sends topicList, performs local update of sharedSecret, expects pirQuery
  193. 2 : no update needed
  194. nothing
  195. */
  196. subPhase := readFrom(leaderConn, 1)
  197. var encryptedQueryLeader, encryptedQueryFollower []byte
  198. //first time participating
  199. if subPhase[0] == 0 {
  200. receiveTopicLists(leaderConn)
  201. encryptedQueryLeader, encryptedQueryFollower = createPIRQuery(int(subPhase[0]), clientNumber)
  202. sendQuerys(encryptedQueryLeader, encryptedQueryFollower, leaderConn, false)
  203. }
  204. //updates the topic list and what client is interested in
  205. if subPhase[0] == 1 {
  206. receiveTopicLists(leaderConn)
  207. //updates local secret
  208. for index := 0; index < 2; index++ {
  209. sharedSecret[clientNumber][index] = sha256.Sum256(sharedSecret[clientNumber][index][:])
  210. }
  211. encryptedQueryLeader, encryptedQueryFollower = createPIRQuery(int(subPhase[0]), clientNumber)
  212. sendQuerys(encryptedQueryLeader, encryptedQueryFollower, leaderConn, false)
  213. }
  214. receiveTweets(sharedSecret[clientNumber], leaderConn, false, clientNumber)
  215. if len(archiveTopicList) > 0 {
  216. wantsArchive[0] = 0
  217. } else {
  218. wantsArchive[0] = 0
  219. }
  220. writeTo(leaderConn, wantsArchive)
  221. if wantsArchive[0] == 1 && len(archiveTopicList) > 0 {
  222. encryptedQueryLeader, encryptedQueryFollower = createPIRQuery(-1, clientNumber)
  223. sendQuerys(encryptedQueryLeader, encryptedQueryFollower, leaderConn, true)
  224. receiveTweets(sharedSecret[clientNumber], leaderConn, true, clientNumber)
  225. }
  226. } else {
  227. fmt.Println("Phase", phase)
  228. panic("somethin went wrong")
  229. }
  230. }
  231. }
  232. //creates and sends the pirQuerys for each server
  233. func createPIRQuery(subPhase int, clientNumber int) ([]byte, []byte) {
  234. //later this will be taken from gui, this is only for testing
  235. topicsOfInterest := make([]int, 1)
  236. topicsOfInterest[0] = mr.Intn(10)
  237. archiveInterests[0] = mr.Intn(10)
  238. tmpNeededSubscriptions := neededSubscriptions
  239. if tmpNeededSubscriptions > len(topicList) {
  240. tmpNeededSubscriptions = len(topicList)
  241. }
  242. tmptopicsOfInterest := make([]int, len(topicsOfInterest))
  243. copy(tmptopicsOfInterest, topicsOfInterest)
  244. tmpTopicList := make([]string, len(topicList))
  245. copy(tmpTopicList, topicList)
  246. if wantsArchive[0] == 1 && subPhase == -1 {
  247. tmpNeededSubscriptions = len(archiveInterests)
  248. if tmpNeededSubscriptions > len(archiveTopicList) {
  249. tmpNeededSubscriptions = len(archiveTopicList)
  250. }
  251. tmptopicsOfInterest = archiveInterests //todo! take archiveInterests from gui
  252. tmpTopicList = archiveTopicList
  253. }
  254. //creates fake topicsOfInterest if client is boooring
  255. if len(tmptopicsOfInterest) < tmpNeededSubscriptions && subPhase != -1 {
  256. tmptopicsOfInterest = addFakeInterests(len(tmpTopicList), tmptopicsOfInterest, false)
  257. }
  258. //pirQuery [topicsOfInterest][serverAmount][topicAmount]byte
  259. pirQuerys := make([][][]byte, len(tmptopicsOfInterest))
  260. for i := range pirQuerys {
  261. pirQuerys[i] = make([][]byte, 2)
  262. for j := range pirQuerys[i] {
  263. pirQuerys[i][j] = make([]byte, len(tmpTopicList))
  264. }
  265. }
  266. //for leader
  267. //pirQuery will be filled with random bits
  268. for topic := range tmptopicsOfInterest {
  269. for index := range tmpTopicList {
  270. bit, err := rand.Int(rand.Reader, big.NewInt(2))
  271. if err != nil {
  272. panic(err)
  273. }
  274. pirQuerys[topic][0][index] = byte(bit.Int64())
  275. }
  276. }
  277. tmptopicsOfInterestBytes := make([]byte, len(tmpTopicList))
  278. for index := range tmptopicsOfInterest {
  279. if tmptopicsOfInterest[index] == 1 {
  280. tmptopicsOfInterestBytes[index] = 1
  281. }
  282. }
  283. for topicIndex, topic := range tmptopicsOfInterest {
  284. for index := range tmpTopicList {
  285. if topic == index {
  286. if pirQuerys[topicIndex][0][index] == 1 {
  287. pirQuerys[topicIndex][1][index] = 0
  288. } else {
  289. pirQuerys[topicIndex][1][index] = 1
  290. }
  291. } else {
  292. if pirQuerys[topicIndex][0][index] == 0 {
  293. pirQuerys[topicIndex][1][index] = 0
  294. } else {
  295. pirQuerys[topicIndex][1][index] = 1
  296. }
  297. }
  298. }
  299. }
  300. //flattens the querys to be able to send them more efficently
  301. messagesFlattened := make([][]byte, 2)
  302. //adds the sharedSecret to the first pirQuery when first time participating
  303. if subPhase == 0 {
  304. for server := 0; server < 2; server++ {
  305. messagesFlattened[server] = append(messagesFlattened[server], sharedSecret[clientNumber][server][:]...)
  306. }
  307. }
  308. for server := range messagesFlattened {
  309. for topic := range pirQuerys {
  310. messagesFlattened[server] = append(messagesFlattened[server], pirQuerys[topic][server]...)
  311. }
  312. }
  313. var nonce [24]byte
  314. _, err := rand.Read(nonce[:])
  315. if err != nil {
  316. panic("couldn't get randomness for nonce!")
  317. }
  318. encryptedQueryLeader := box.Seal(nonce[:], messagesFlattened[0], &nonce, leaderPublicKey, clientPrivateKey[clientNumber])
  319. _, err = rand.Read(nonce[:])
  320. if err != nil {
  321. panic("couldn't get randomness for nonce!")
  322. }
  323. encryptedQueryFollower := box.Seal(nonce[:], messagesFlattened[1], &nonce, followerPublicKey, clientPrivateKey[clientNumber])
  324. return encryptedQueryLeader, encryptedQueryFollower
  325. }
  326. func sendQuerys(encryptedQueryLeader, encryptedQueryFollower []byte, leaderConn net.Conn, getArchive bool) {
  327. encryptedLength := len(encryptedQueryLeader)
  328. //sends the pirQuerysLength to the leader
  329. writeTo(leaderConn, intToByte(encryptedLength))
  330. //sends the pirQuerys to the leader
  331. writeTo(leaderConn, encryptedQueryLeader)
  332. writeTo(leaderConn, encryptedQueryFollower)
  333. if getArchive {
  334. writeTo(leaderConn, intToByte(len(archiveInterests)))
  335. }
  336. }
  337. func receiveVirtualAddress(sharedSecret [2][32]byte, leaderConn net.Conn) int {
  338. virtualAddressByte := readFrom(leaderConn, 4)
  339. //xores the sharedSecret
  340. for h := 0; h < 2; h++ {
  341. for i := 0; i < 4; i++ {
  342. virtualAddressByte[i] = virtualAddressByte[i] ^ sharedSecret[h][i]
  343. }
  344. }
  345. return byteToInt(virtualAddressByte)
  346. }
  347. func receiveTweets(sharedSecret [2][32]byte, leaderConn net.Conn, getArchive bool, clientNumber int) {
  348. tmpNeededSubscriptions := neededSubscriptions
  349. if tmpNeededSubscriptions > len(topicList) {
  350. tmpNeededSubscriptions = len(topicList)
  351. }
  352. if getArchive {
  353. tmpNeededSubscriptions = len(archiveInterests)
  354. if tmpNeededSubscriptions > len(archiveTopicList) {
  355. tmpNeededSubscriptions = len(archiveTopicList)
  356. }
  357. }
  358. for i := 0; i < tmpNeededSubscriptions; i++ {
  359. if !getArchive {
  360. blocksReceived++
  361. }
  362. //client receives tweets
  363. tweetsLengthBytes := readFrom(leaderConn, 4)
  364. tweetsLength := byteToInt(tweetsLengthBytes)
  365. tweets := readFrom(leaderConn, tweetsLength)
  366. //expand sharedSecret so it is of right length
  367. expandBy := len(tweets) / 32
  368. expandedSharedSecrets := make([][]byte, 2)
  369. for i := 0; i < 2; i++ {
  370. for j := 0; j < expandBy; j++ {
  371. expandedSharedSecrets[i] = append(expandedSharedSecrets[i], sharedSecret[i][:]...)
  372. }
  373. }
  374. //xors the received messge into the message to display
  375. for i := 0; i < 2; i++ {
  376. lib.Xor(expandedSharedSecrets[i][:], tweets)
  377. }
  378. index := strings.Index(string(tweets), ";;")
  379. if index != -1 {
  380. textArr := strings.Split(string(tweets), ";;;")
  381. text := textArr[:len(textArr)-1]
  382. if text[1] != "" {
  383. text[1] = text[1][1:]
  384. }
  385. ok := strings.Contains(text[0], text[1])
  386. if !ok {
  387. goodPadding++
  388. }
  389. } else if index == -1 && tweets[0] != 0 {
  390. fmt.Println("error")
  391. fmt.Println("round", round, string(tweets), "length", len(tweets))
  392. return
  393. }
  394. }
  395. }
  396. //creates a shared secret for each server
  397. func createSharedSecret() [numClients][2][32]byte {
  398. var tmpSharedSecret [numClients][2][32]byte
  399. for i := 0; i < numClients; i++ {
  400. for j := 0; j < 2; j++ {
  401. _, err := rand.Read(tmpSharedSecret[i][j][:])
  402. if err != nil {
  403. panic("couldn't get randomness for sharedSecret!")
  404. }
  405. }
  406. }
  407. return tmpSharedSecret
  408. }
  409. func createAuditPIRQuery(clientNumber int) ([]byte, []byte) {
  410. //pirQuery [serverAmount][dbWriteSize]byte
  411. pirQuerys := make([][]byte, 2)
  412. for i := range pirQuerys {
  413. pirQuerys[i] = make([]byte, dbWriteSize)
  414. }
  415. //for leader
  416. //pirQuery will be filled with random bits
  417. for index := range pirQuerys[0] {
  418. bit := mr.Intn(2)
  419. pirQuerys[0][index] = byte(bit)
  420. }
  421. copy(pirQuerys[1], pirQuerys[0])
  422. //the positon the virtual address will be taken from
  423. pos := mr.Intn(dbWriteSize)
  424. pirQuerys[0][pos] = 1
  425. pirQuerys[1][pos] = 0
  426. //flattens the querys to be able to send them more efficently
  427. messagesFlattened := make([][]byte, 2)
  428. //adds the sharedSecret to the pirQuery
  429. for server := 0; server < 2; server++ {
  430. messagesFlattened[server] = append(messagesFlattened[server], sharedSecret[clientNumber][server][:]...)
  431. }
  432. for server := 0; server < 2; server++ {
  433. messagesFlattened[server] = append(messagesFlattened[server], pirQuerys[server][:]...)
  434. }
  435. var nonce [24]byte
  436. _, err := rand.Read(nonce[:])
  437. if err != nil {
  438. panic("couldn't get randomness for nonce!")
  439. }
  440. encryptedQueryLeader := box.Seal(nonce[:], messagesFlattened[0], &nonce, leaderPublicKey, clientPrivateKey[clientNumber])
  441. _, err = rand.Read(nonce[:])
  442. if err != nil {
  443. panic("couldn't get randomness for nonce!")
  444. }
  445. encryptedQueryFollower := box.Seal(nonce[:], messagesFlattened[1], &nonce, followerPublicKey, clientPrivateKey[clientNumber])
  446. return encryptedQueryLeader, encryptedQueryFollower
  447. }
  448. //generates a topicOfInterest array with random values
  449. func addFakeInterests(max int, topicsOfInterest []int, doAuditing bool) []int {
  450. tmpNeededSubscriptions := neededSubscriptions
  451. if tmpNeededSubscriptions > len(topicList) {
  452. tmpNeededSubscriptions = len(topicList)
  453. }
  454. faketopicsOfInterest := make([]int, tmpNeededSubscriptions)
  455. maxInt := max
  456. //fills the array with unique random ascending values ranging from 0 to max
  457. for i := 0; i < tmpNeededSubscriptions; i++ {
  458. faketopicsOfInterest[i] = mr.Intn(maxInt)
  459. for j := 0; j < i; j++ {
  460. if faketopicsOfInterest[i] == faketopicsOfInterest[j] {
  461. i--
  462. break
  463. }
  464. }
  465. }
  466. if doAuditing {
  467. sort.Ints(faketopicsOfInterest)
  468. return faketopicsOfInterest
  469. }
  470. //adds unique and new random numbers to topicOfInterests until length is satisfied
  471. for _, number := range faketopicsOfInterest {
  472. if !inList(number, topicsOfInterest) {
  473. topicsOfInterest = append(topicsOfInterest, number)
  474. }
  475. if len(topicsOfInterest) == tmpNeededSubscriptions {
  476. break
  477. }
  478. }
  479. sort.Ints(topicsOfInterest)
  480. return topicsOfInterest
  481. }
  482. func inList(number int, list []int) bool {
  483. for _, element := range list {
  484. if element == number {
  485. return true
  486. }
  487. }
  488. return false
  489. }
  490. func receiveTopicLists(leaderConn net.Conn) {
  491. for i := 0; i < 2; i++ {
  492. topicListLength := readFrom(leaderConn, 4)
  493. recTopicList := readFrom(leaderConn, byteToInt(topicListLength))
  494. var tmpTopicList []string
  495. arrayReader := bytes.NewReader(recTopicList[:])
  496. json.NewDecoder(arrayReader).Decode(&tmpTopicList)
  497. if i == 0 {
  498. topicList = tmpTopicList
  499. } else {
  500. archiveTopicList = tmpTopicList
  501. }
  502. }
  503. }
  504. func getRealTweet(clientNumber int) []byte {
  505. fUserList, err := os.Open("/home/simon/goCode/tweets/userList")
  506. if err != nil {
  507. panic(err)
  508. }
  509. defer fUserList.Close()
  510. currentLine := 0
  511. scanner := bufio.NewScanner(fUserList)
  512. userID := ""
  513. for scanner.Scan() {
  514. if currentLine == clientNumber {
  515. userID = scanner.Text()
  516. break
  517. }
  518. currentLine++
  519. }
  520. if userID == "" {
  521. panic("no userID picked")
  522. }
  523. fTweets, err := os.Open("/home/simon/goCode/tweets/userTweets/" + userID)
  524. if err != nil {
  525. panic(err)
  526. }
  527. defer fTweets.Close()
  528. scanner = bufio.NewScanner(fTweets)
  529. lowerBound := timeBounds[round-1]
  530. upperBound := timeBounds[round]
  531. var tweet []byte
  532. for scanner.Scan() {
  533. //skips round 1, cause of 90% publisher rate
  534. if round == 1 {
  535. break
  536. }
  537. lineArr := strings.Split(scanner.Text(), ", \"hashtags\"")
  538. lineArr = strings.Split(lineArr[0], ": ")
  539. lineArr = strings.Split(lineArr[1], " \"")
  540. timestamp, _ := strconv.Atoi(lineArr[0])
  541. //transforms timestamp to current time
  542. timestamp -= 1351742400
  543. timestamp += startTime
  544. if float64(timestamp) > lowerBound && float64(timestamp) < upperBound {
  545. lineArr = strings.Split(scanner.Text(), "[\"")
  546. line := lineArr[1]
  547. lineArr = strings.Split(line, "\"]")
  548. line = lineArr[0]
  549. lineArr = strings.Split(line, ",")
  550. line = strings.Join(lineArr, "")
  551. topicLine := strings.Split(line, "\"")
  552. var topics []byte
  553. for index, topic := range topicLine {
  554. if index%2 == 1 {
  555. continue
  556. }
  557. if len(topics)+len(topic) > dataLength-10 {
  558. break
  559. }
  560. topics = append(topics, []byte(topic)[:]...)
  561. topics = append(topics, []byte(",")[0])
  562. }
  563. if len(topics) == 0 {
  564. break
  565. }
  566. topics = topics[:len(topics)-1]
  567. tweet = append(tweet, topics...)
  568. tweet = append(tweet, []byte(";")[0])
  569. r := mr.New(mr.NewSource(time.Now().UnixNano()))
  570. num := r.Intn(10000)
  571. if num == 0 {
  572. num = 1
  573. }
  574. tweet = append(tweet, []byte(strconv.Itoa(num) + ";;")[:]...)
  575. //adds padding
  576. length := dataLength - len(tweet)
  577. padding := make([]byte, length)
  578. rand.Read(padding)
  579. tweet = append(tweet, padding...)
  580. publisherAmount++
  581. return tweet
  582. }
  583. }
  584. tweet = make([]byte, dataLength)
  585. return tweet
  586. }
  587. func getTimeBounds() {
  588. timeBounds = make([]float64, 10000)
  589. timeBounds[0] = float64(time.Now().Unix())
  590. for index := range timeBounds {
  591. if index == 0 {
  592. continue
  593. }
  594. timeBounds[index] = timeBounds[index-1] + speedUp*(3*maxTimePerRound.Seconds()+2)
  595. }
  596. }
  597. func getRandomTweet(clientNumber int) []byte {
  598. var tweet []byte
  599. r := mr.New(mr.NewSource(time.Now().UnixNano()))
  600. maxTopics := r.Intn(6)
  601. if maxTopics == 0 {
  602. maxTopics = 1
  603. }
  604. maxInt := 100
  605. topicNumbers := make([]int, maxTopics)
  606. //fills the array with unique random ascending values ranging from 0 to maxInt
  607. for i := 0; i < maxTopics; i++ {
  608. topicNumbers[i] = mr.Intn(maxInt)
  609. for j := 0; j < i; j++ {
  610. if topicNumbers[i] == topicNumbers[j] {
  611. i--
  612. break
  613. }
  614. }
  615. }
  616. sort.Ints(topicNumbers)
  617. var topics []byte
  618. topicIndex := 0
  619. for i := 0; i < len(topicNumbers)*2; i++ {
  620. if i%2 == 0 {
  621. topics = append(topics, byte(topicNumbers[topicIndex]))
  622. topicIndex++
  623. } else if i != (len(topicNumbers)*2)-1 {
  624. topics = append(topics, []byte(",")[0])
  625. }
  626. }
  627. topics = append(topics, []byte(";")[0])
  628. num := r.Intn(100)
  629. if num == 0 {
  630. num = 1
  631. }
  632. text := []byte(strconv.Itoa(num) + ";")
  633. tweet = append(tweet, topics...)
  634. tweet = append(tweet, text...)
  635. tweet = append(tweet, []byte(";")[0])
  636. //adds padding
  637. length := dataLength - len(tweet)
  638. padding := make([]byte, length)
  639. rand.Read(padding)
  640. tweet = append(tweet, padding...)
  641. return tweet
  642. }
  643. //sends the array to the connection
  644. func writeTo(connection net.Conn, array []byte) {
  645. remainingLength := len(array)
  646. for remainingLength > 0 {
  647. if remainingLength >= mtu {
  648. _, err := connection.Write(array[:mtu])
  649. if err != nil {
  650. panic(err)
  651. }
  652. array = array[mtu:]
  653. remainingLength -= mtu
  654. } else {
  655. _, err := connection.Write(array)
  656. if err != nil {
  657. panic(err)
  658. }
  659. remainingLength = 0
  660. }
  661. }
  662. }
  663. //reads an array which is returned and of size "size" from the connection
  664. func readFrom(connection net.Conn, size int) []byte {
  665. var array []byte
  666. remainingSize := size
  667. for remainingSize > 0 {
  668. var err error
  669. toAppend := make([]byte, mtu)
  670. if remainingSize > mtu {
  671. _, err = connection.Read(toAppend)
  672. array = append(array, toAppend...)
  673. remainingSize -= mtu
  674. } else {
  675. _, err = connection.Read(toAppend[:remainingSize])
  676. array = append(array, toAppend[:remainingSize]...)
  677. remainingSize = 0
  678. }
  679. if err != nil {
  680. panic(err)
  681. }
  682. }
  683. return array
  684. }
  685. func intToByte(myInt int) (retBytes []byte) {
  686. retBytes = make([]byte, 4)
  687. retBytes[3] = byte((myInt >> 24) & 0xff)
  688. retBytes[2] = byte((myInt >> 16) & 0xff)
  689. retBytes[1] = byte((myInt >> 8) & 0xff)
  690. retBytes[0] = byte(myInt & 0xff)
  691. return
  692. }
  693. func byteToInt(myBytes []byte) (x int) {
  694. x = int(myBytes[3])<<24 + int(myBytes[2])<<16 + int(myBytes[1])<<8 + int(myBytes[0])
  695. return
  696. }