Просмотр исходного кода

Faketls works now

tags/v2.0.0-rc1
9seconds 5 лет назад
Родитель
Сommit
f0efa4697e
4 измененных файлов: 82 добавлений и 9 удалений
  1. 70
    0
      mtglib/internal/faketls/conn.go
  2. 2
    0
      mtglib/internal/faketls/record/init.go
  3. 2
    4
      mtglib/internal/relay/conn.go
  4. 8
    5
      mtglib/proxy.go

+ 70
- 0
mtglib/internal/faketls/conn.go Просмотреть файл

1
+package faketls
2
+
3
+import (
4
+	"bytes"
5
+	"fmt"
6
+	"net"
7
+
8
+	"github.com/9seconds/mtg/v2/mtglib/internal/faketls/record"
9
+)
10
+
11
+type Conn struct {
12
+	net.Conn
13
+
14
+	readBuffer bytes.Buffer
15
+}
16
+
17
+func (c *Conn) Read(p []byte) (int, error) {
18
+	if n, _ := c.readBuffer.Read(p); n > 0 {
19
+		return n, nil
20
+	}
21
+
22
+	rec := record.AcquireRecord()
23
+	defer record.ReleaseRecord(rec)
24
+
25
+	for {
26
+		if err := rec.Read(c.Conn); err != nil {
27
+			return 0, err // nolint: wrapcheck
28
+		}
29
+
30
+		switch rec.Type { // nolint: exhaustive
31
+		case record.TypeChangeCipherSpec:
32
+		case record.TypeApplicationData:
33
+			rec.Payload.WriteTo(&c.readBuffer)
34
+
35
+			n, err := c.readBuffer.Read(p)
36
+
37
+			return n, err
38
+		default:
39
+			return 0, fmt.Errorf("unsupported record type %v", rec.Type)
40
+		}
41
+	}
42
+}
43
+
44
+func (c *Conn) Write(p []byte) (int, error) {
45
+	rec := record.AcquireRecord()
46
+	defer record.ReleaseRecord(rec)
47
+
48
+	rec.Type = record.TypeApplicationData
49
+	rec.Version = record.Version12
50
+	written := 0
51
+
52
+	for len(p) > 0 {
53
+		chunkSize := record.TLSMaxRecordSize
54
+		if chunkSize > len(p) {
55
+			chunkSize = len(p)
56
+		}
57
+
58
+		rec.Payload.Reset()
59
+		rec.Payload.Write(p[:chunkSize])
60
+
61
+		if err := rec.Dump(c.Conn); err != nil {
62
+			return 0, err
63
+		}
64
+
65
+		written += chunkSize
66
+		p = p[chunkSize:]
67
+	}
68
+
69
+	return written, nil
70
+}

+ 2
- 0
mtglib/internal/faketls/record/init.go Просмотреть файл

2
 
2
 
3
 import "fmt"
3
 import "fmt"
4
 
4
 
5
+const TLSMaxRecordSize = 65535 // max uint16
6
+
5
 type Type uint8
7
 type Type uint8
6
 
8
 
7
 const (
9
 const (

+ 2
- 4
mtglib/internal/relay/conn.go Просмотреть файл

9
 }
9
 }
10
 
10
 
11
 func (c conn) Read(p []byte) (int, error) {
11
 func (c conn) Read(p []byte) (int, error) {
12
-	ctx := c.relay.ctx
13
 	n, err := c.ReadWriteCloser.Read(p)
12
 	n, err := c.ReadWriteCloser.Read(p)
14
 
13
 
15
 	select {
14
 	select {
16
-	case <-ctx.Done():
15
+	case <-c.relay.ctx.Done():
17
 	case c.relay.tickChannel <- struct{}{}:
16
 	case c.relay.tickChannel <- struct{}{}:
18
 	}
17
 	}
19
 
18
 
21
 }
20
 }
22
 
21
 
23
 func (c conn) Write(p []byte) (int, error) {
22
 func (c conn) Write(p []byte) (int, error) {
24
-	ctx := c.relay.ctx
25
 	n, err := c.ReadWriteCloser.Write(p)
23
 	n, err := c.ReadWriteCloser.Write(p)
26
 
24
 
27
 	select {
25
 	select {
28
-	case <-ctx.Done():
26
+	case <-c.relay.ctx.Done():
29
 	case c.relay.tickChannel <- struct{}{}:
27
 	case c.relay.tickChannel <- struct{}{}:
30
 	}
28
 	}
31
 
29
 

+ 8
- 5
mtglib/proxy.go Просмотреть файл

4
 	"context"
4
 	"context"
5
 	"errors"
5
 	"errors"
6
 	"fmt"
6
 	"fmt"
7
-	"io"
8
 	"net"
7
 	"net"
9
 	"sync"
8
 	"sync"
10
 	"time"
9
 	"time"
59
 		ctx.logger.Info("Stream has been finished")
58
 		ctx.logger.Info("Stream has been finished")
60
 	}()
59
 	}()
61
 
60
 
62
-	if err := p.doFakeTLSHandshake(ctx, ctx.clientConn); err != nil {
61
+	if err := p.doFakeTLSHandshake(ctx); err != nil {
63
 		p.logger.InfoError("faketls handshake is failed", err)
62
 		p.logger.InfoError("faketls handshake is failed", err)
64
 
63
 
65
 		return
64
 		return
122
 	p.workerPool.Release()
121
 	p.workerPool.Release()
123
 }
122
 }
124
 
123
 
125
-func (p *Proxy) doFakeTLSHandshake(ctx *streamContext, conn io.ReadWriter) error {
124
+func (p *Proxy) doFakeTLSHandshake(ctx *streamContext) error {
126
 	rec := record.AcquireRecord()
125
 	rec := record.AcquireRecord()
127
 	defer record.ReleaseRecord(rec)
126
 	defer record.ReleaseRecord(rec)
128
 
127
 
129
-	if err := rec.Read(conn); err != nil {
128
+	if err := rec.Read(ctx.clientConn); err != nil {
130
 		return fmt.Errorf("cannot read client hello: %w", err)
129
 		return fmt.Errorf("cannot read client hello: %w", err)
131
 	}
130
 	}
132
 
131
 
145
 		return fmt.Errorf("anti replay attack from %s", ctx.ClientIP().String())
144
 		return fmt.Errorf("anti replay attack from %s", ctx.ClientIP().String())
146
 	}
145
 	}
147
 
146
 
148
-	if err := faketls.SendWelcomePacket(conn, p.secret.Key[:], hello); err != nil {
147
+	if err := faketls.SendWelcomePacket(ctx.clientConn, p.secret.Key[:], hello); err != nil {
149
 		return fmt.Errorf("cannot send a welcome packet: %w", err)
148
 		return fmt.Errorf("cannot send a welcome packet: %w", err)
150
 	}
149
 	}
151
 
150
 
151
+	ctx.clientConn = &faketls.Conn{
152
+		Conn: ctx.clientConn,
153
+	}
154
+
152
 	return nil
155
 	return nil
153
 }
156
 }
154
 
157
 

Загрузка…
Отмена
Сохранить