mirror of
https://github.com/tladesignz/dnstt.git
synced 2026-10-11 08:38:31 +03:00
67 lines
1.6 KiB
Go
67 lines
1.6 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
|
|
"www.bamsoftware.com/git/dnstt.git/turbotunnel"
|
|
)
|
|
|
|
type HTTPPacketConn struct {
|
|
urlString string
|
|
*turbotunnel.QueuePacketConn
|
|
}
|
|
|
|
func NewHTTPPacketConn(urlString string, numSenders int) (*HTTPPacketConn, error) {
|
|
c := &HTTPPacketConn{
|
|
urlString: urlString,
|
|
QueuePacketConn: turbotunnel.NewQueuePacketConn(dummyAddr{}, idleTimeout),
|
|
}
|
|
for i := 0; i < numSenders; i++ {
|
|
go func() {
|
|
for p := range c.QueuePacketConn.OutgoingQueue(dummyAddr{}) {
|
|
err := c.send(p)
|
|
if err != nil {
|
|
log.Printf("sender thread: %v", err)
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
return c, nil
|
|
}
|
|
|
|
// send sends a single packet in an HTTP request.
|
|
func (c *HTTPPacketConn) send(p []byte) error {
|
|
req, err := http.NewRequest("POST", c.urlString, bytes.NewReader(p))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req.Header.Set("Accept", "application/dns-message")
|
|
req.Header.Set("Content-Type", "application/dns-message")
|
|
resp, err := http.DefaultTransport.RoundTrip(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode != http.StatusOK || resp.Header.Get("Content-Type") != "application/dns-message" {
|
|
return fmt.Errorf("unexpected response")
|
|
}
|
|
body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 64000))
|
|
if err != nil {
|
|
// Don't report an error if we at least managed to send.
|
|
return nil
|
|
}
|
|
c.QueuePacketConn.QueueIncoming(body, dummyAddr{})
|
|
return nil
|
|
}
|
|
|
|
func (c *HTTPPacketConn) WriteTo(p []byte, addr net.Addr) (int, error) {
|
|
// Ignore addr.
|
|
return c.QueuePacketConn.WriteTo(p, dummyAddr{})
|
|
}
|