コード例 #1
0
ファイル: main.go プロジェクト: ineiti/prifi
func startTrustee(tno int) {
	tg := dcnet.TestSetup(nil, suite, factory, nclients, ntrustees)
	me := tg.Trustees[tno]

	conn := openRelay(tno | 0x80)
	println("trustee", tno, "connected")

	// Just generate ciphertext cells and stream them to the server.
	for {
		// Produce a cell worth of trustee ciphertext
		tslice := me.Coder.TrusteeEncode(payloadlen)

		// Send it to the relay
		//println("trustee slice")
		//println(hex.Dump(tslice))
		n, err := conn.Write(tslice)
		if n < len(tslice) || err != nil {
			panic("can't write to socket: " + err.Error())
		}
	}
}
コード例 #2
0
ファイル: main.go プロジェクト: ineiti/prifi
func startClient(clino int) {
	fmt.Printf("startClient %d\n", clino)

	tg := dcnet.TestSetup(nil, suite, factory, nclients, ntrustees)
	me := tg.Clients[clino]
	clisize := me.Coder.ClientCellSize(payloadlen)

	rconn := openRelay(clino)
	fromrelay := make(chan connbuf)
	go clientReadRelay(rconn, fromrelay)
	println("client", clino, "connected")

	// We're the "slot owner" - start an HTTP proxy
	newconn := make(chan net.Conn)
	upload := make(chan []byte)
	close := make(chan int)
	conns := make([]net.Conn, 1) // reserve conns[0]
	if clino == 0 {
		go clientListen(":1080", newconn)
		//go clientListen(":8080",newconn)
	}

	// Client/proxy main loop
	upq := make([][]byte, 0)
	totupcells := uint64(0)
	totupbytes := uint64(0)
	for {
		select {
		case conn := <-newconn: // New TCP connection
			cno := len(conns)
			conns = append(conns, conn)
			//fmt.Printf("new conn %d %p %p\n", cno, conn, conns[cno])
			go clientConnRead(cno, conn, upload, close)

		case buf := <-upload: // Upstream data from client
			upq = append(upq, buf)

		case cno := <-close: // Connection closed
			conns[cno] = nil

		case cbuf := <-fromrelay: // Downstream cell from relay
			//print(".")

			cno := cbuf.cno
			//if cno != 0 || len(cbuf.buf) != 0 {
			//	fmt.Printf("v %d (conn %d)\n",
			//			len(cbuf.buf), cno)
			//}
			if cno > 0 && cno < len(conns) && conns[cno] != nil {
				buf := cbuf.buf
				blen := len(buf)
				//println(hex.Dump(buf))
				if blen > 0 {
					// Data from relay for this connection
					n, err := conns[cno].Write(buf)
					if n < blen {
						panic("Write to client: " +
							err.Error())
					}
				} else {
					// Relay indicating EOF on this conn
					fmt.Printf("upstream closed conn %d",
						cno)
					conns[cno].Close()
				}
			}

			// XXX account for downstream cell in history

			// Produce and ship the next upstream cell
			var p []byte
			if len(upq) > 0 {
				p = upq[0]
				upq = upq[1:]
				//fmt.Printf("^ %d\n", len(p))
			}
			slice := me.Coder.ClientEncode(p, payloadlen, me.History)
			//println("client slice")
			//println(hex.Dump(slice))
			if len(slice) != clisize {
				panic("client slice wrong size")
			}
			n, err := rconn.Write(slice)
			if n != len(slice) {
				panic("Write to relay conn: " + err.Error())
			}

			totupcells++
			totupbytes += uint64(payloadlen)
			//fmt.Printf("sent %d upstream cells, %d bytes\n",
			//		totupcells, totupbytes)
		}
	}
}
コード例 #3
0
ファイル: relay.go プロジェクト: ineiti/prifi
func startRelay() {
	tg := dcnet.TestSetup(nil, suite, factory, nclients, ntrustees)
	me := tg.Relay

	// Start our own local HTTP proxy for simplicity.
	/*
		go func() {
			proxy := goproxy.NewProxyHttpServer()
			proxy.Verbose = true
			println("Starting HTTP proxy")
			log.Fatal(http.ListenAndServe(":8888", proxy))
		}()
	*/

	lsock, err := net.Listen("tcp", bindport)
	if err != nil {
		panic("Can't open listen socket:" + err.Error())
	}

	// Wait for all the clients and trustees to connect
	ccli := 0
	ctru := 0
	csock := make([]net.Conn, nclients)
	tsock := make([]net.Conn, ntrustees)
	for ccli < nclients || ctru < ntrustees {
		fmt.Printf("Waiting for %d clients, %d trustees\n",
			nclients-ccli, ntrustees-ctru)

		conn, err := lsock.Accept()
		if err != nil {
			panic("Listen error:" + err.Error())
		}

		b := make([]byte, 1)
		n, err := conn.Read(b)
		if n < 1 || err != nil {
			panic("Read error:" + err.Error())
		}

		node := int(b[0] & 0x7f)
		if b[0]&0x80 == 0 && node < nclients {
			if csock[node] != nil {
				panic("Oops, client connected twice")
			}
			csock[node] = conn
			ccli++
		} else if b[0]&0x80 != 0 && node < ntrustees {
			if tsock[node] != nil {
				panic("Oops, trustee connected twice")
			}
			tsock[node] = conn
			ctru++
		} else {
			panic("illegal node number")
		}
	}
	println("All clients and trustees connected")

	// Create ciphertext slice buffers for all clients and trustees
	clisize := me.Coder.ClientCellSize(payloadlen)
	cslice := make([][]byte, nclients)
	for i := 0; i < nclients; i++ {
		cslice[i] = make([]byte, clisize)
	}
	trusize := me.Coder.TrusteeCellSize(payloadlen)
	tslice := make([][]byte, ntrustees)
	for i := 0; i < ntrustees; i++ {
		tslice[i] = make([]byte, trusize)
	}

	// Periodic stats reporting
	begin := time.Now()
	report := begin
	period, _ := time.ParseDuration("3s")
	totupcells := int64(0)
	totupbytes := int64(0)
	totdowncells := int64(0)
	totdownbytes := int64(0)

	conns := make(map[int]chan<- []byte)
	downstream := make(chan connbuf)
	nulldown := connbuf{} // default empty downstream cell
	window := 2           // Maximum cells in-flight
	inflight := 0         // Current cells in-flight
	for {
		//print(".")

		// Show periodic reports
		now := time.Now()
		if now.After(report) {
			duration := now.Sub(begin).Seconds()
			fmt.Printf("@ %f sec: %d cells, %f cells/sec, %d upbytes, %f upbytes/sec, %d downbytes, %f downbytes/sec\n",
				duration,
				totupcells, float64(totupcells)/duration,
				totupbytes, float64(totupbytes)/duration,
				totdownbytes, float64(totdownbytes)/duration)

			// Next report time
			report = now.Add(period)
		}

		// See if there's any downstream data to forward.
		var downbuf connbuf
		select {
		case downbuf = <-downstream: // some data to forward downstream
			//fmt.Printf("v %d\n", len(dbuf)-6)
		default: // nothing at the moment to forward
			downbuf = nulldown
		}
		dlen := len(downbuf.buf)
		dbuf := make([]byte, 6+dlen)
		binary.BigEndian.PutUint32(dbuf[0:4], uint32(downbuf.cno))
		binary.BigEndian.PutUint16(dbuf[4:6], uint16(dlen))
		copy(dbuf[6:], downbuf.buf)

		// Broadcast the downstream data to all clients.
		for i := 0; i < nclients; i++ {
			//fmt.Printf("client %d -> %d downstream bytes\n",
			//		i, len(dbuf)-6)
			n, err := csock[i].Write(dbuf)
			if n != 6+dlen {
				panic("Write to client: " + err.Error())
			}
		}
		totdowncells++
		totdownbytes += int64(dlen)
		//fmt.Printf("sent %d downstream cells, %d bytes \n",
		//		totdowncells, totdownbytes)

		inflight++
		if inflight < window {
			continue // Get more cells in flight
		}

		me.Coder.DecodeStart(payloadlen, me.History)

		// Collect a cell ciphertext from each trustee
		for i := 0; i < ntrustees; i++ {
			n, err := io.ReadFull(tsock[i], tslice[i])
			if n < trusize {
				panic("Read from client: " + err.Error())
			}
			//println("trustee slice")
			//println(hex.Dump(tslice[i]))
			me.Coder.DecodeTrustee(tslice[i])
		}

		// Collect an upstream ciphertext from each client
		for i := 0; i < nclients; i++ {
			n, err := io.ReadFull(csock[i], cslice[i])
			if n < clisize {
				panic("Read from client: " + err.Error())
			}
			//println("client slice")
			//println(hex.Dump(cslice[i]))
			me.Coder.DecodeClient(cslice[i])
		}

		outb := me.Coder.DecodeCell()
		inflight--

		totupcells++
		totupbytes += int64(payloadlen)
		//fmt.Printf("received %d upstream cells, %d bytes\n",
		//		totupcells, totupbytes)

		// Process the decoded cell
		if outb == nil {
			continue // empty or corrupt upstream cell
		}
		if len(outb) != payloadlen {
			panic("DecodeCell produced wrong-size payload")
		}

		// Decode the upstream cell header (may be empty, all zeros)
		cno := int(binary.BigEndian.Uint32(outb[0:4]))
		uplen := int(binary.BigEndian.Uint16(outb[4:6]))
		//fmt.Printf("^ %d (conn %d)\n", uplen, cno)
		if cno == 0 {
			continue // no upstream data
		}
		conn := conns[cno]
		if conn == nil { // client initiating new connection
			conn = relayNewConn(cno, downstream)
			conns[cno] = conn
		}
		if 6+uplen > payloadlen {
			log.Printf("upstream cell invalid length %d", 6+uplen)
			continue
		}
		conn <- outb[6 : 6+uplen]
	}
}