作者:SiroDia
项目:csu
func addr(prot pb.CreateSocketRequest_SocketProtocol, ap *pb.AddressPort) net.Addr {
if ap == nil {
return nil
}
switch prot {
case pb.CreateSocketRequest_TCP:
return &net.TCPAddr{
IP: net.IP(ap.PackedAddress),
Port: int(*ap.Port),
}
case pb.CreateSocketRequest_UDP:
return &net.UDPAddr{
IP: net.IP(ap.PackedAddress),
Port: int(*ap.Port),
}
}
panic("unknown protocol " + prot.String())
}
作者:SiroDia
项目:csu
// DialTimeout is like Dial but takes a timeout.
// The timeout includes name resolution, if required.
func DialTimeout(c appengine.Context, protocol, addr string, timeout time.Duration) (*Conn, error) {
var deadline time.Time
if timeout > 0 {
deadline = time.Now().Add(timeout)
}
host, portStr, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
port, err := strconv.Atoi(portStr)
if err != nil {
return nil, fmt.Errorf("socket: bad port %q: %v", portStr, err)
}
var prot pb.CreateSocketRequest_SocketProtocol
switch protocol {
case "tcp":
prot = pb.CreateSocketRequest_TCP
case "udp":
prot = pb.CreateSocketRequest_UDP
default:
return nil, fmt.Errorf("socket: unknown protocol %q", protocol)
}
packedAddrs, resolved, err := resolve(c, ipFamilies, host, deadline)
if err != nil {
return nil, fmt.Errorf("socket: failed resolving %q: %v", host, err)
}
if len(packedAddrs) == 0 {
return nil, fmt.Errorf("no addresses for %q", host)
}
packedAddr := packedAddrs[0] // use first address
fam := pb.CreateSocketRequest_IPv4
if len(packedAddr) == net.IPv6len {
fam = pb.CreateSocketRequest_IPv6
}
req := &pb.CreateSocketRequest{
Family: fam.Enum(),
Protocol: prot.Enum(),
RemoteIp: &pb.AddressPort{
Port: proto.Int32(int32(port)),
PackedAddress: packedAddr,
},
}
if resolved {
req.RemoteIp.HostnameHint = &host
}
res := &pb.CreateSocketReply{}
if err := c.Call("remote_socket", "CreateSocket", req, res, opts(deadline)); err != nil {
return nil, err
}
return &Conn{
c: c,
desc: res.GetSocketDescriptor(),
prot: prot,
local: res.ProxyExternalIp,
remote: req.RemoteIp,
}, nil
}