| 189 | } |
| 190 | |
| 191 | func (s *Server) embedHandleConnect(req *request) error { |
| 192 | defer func() { |
| 193 | _ = req.Conn.Close() |
| 194 | }() |
| 195 | target, err := s.ProxyDial(s.Context, "tcp", req.DestinationAddr.Address()) |
| 196 | if err != nil { |
| 197 | if err := sendReply(req.Conn, rejectedReply, nil); err != nil { |
| 198 | return fmt.Errorf("failed to send reply: %v", err) |
| 199 | } |
| 200 | return fmt.Errorf("connect to %v failed: %w", req.DestinationAddr, err) |
| 201 | } |
| 202 | defer func() { |
| 203 | _ = target.Close() |
| 204 | }() |
| 205 | local := target.LocalAddr().(*net.TCPAddr) |
| 206 | bind := address{IP: local.IP, Port: local.Port} |
| 207 | if err := sendReply(req.Conn, grantedReply, &bind); err != nil { |
| 208 | return fmt.Errorf("failed to send reply: %v", err) |
| 209 | } |
| 210 | |
| 211 | var buf1, buf2 []byte |
| 212 | if s.BytesPool != nil { |
| 213 | buf1 = s.BytesPool.Get() |
| 214 | buf2 = s.BytesPool.Get() |
| 215 | defer func() { |
| 216 | s.BytesPool.Put(buf1) |
| 217 | s.BytesPool.Put(buf2) |
| 218 | }() |
| 219 | } else { |
| 220 | buf1 = make([]byte, 32*1024) |
| 221 | buf2 = make([]byte, 32*1024) |
| 222 | } |
| 223 | return statute.Tunnel(s.Context, target, req.Conn, buf1, buf2) |
| 224 | } |
| 225 | |
| 226 | func sendReply(w io.Writer, resp reply, addr *address) error { |
| 227 | _, err := w.Write([]byte{0, byte(resp)}) |