mssql_browser/
browse_instance_dac.rs1use super::error::*;
2use super::info::*;
3use super::socket::{UdpSocket, UdpSocketFactory};
4use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
5
6const CLNT_UCAST_DAC: u8 = 0x0F;
9
10const SVR_RESP: u8 = 0x05;
12
13#[cfg(any(feature = "tokio", feature = "async-std"))]
19pub async fn browse_instance_dac(
20 remote_addr: IpAddr,
21 instance_name: &str,
22) -> Result<
23 DacInfo,
24 BrowserError<
25 <super::socket::DefaultSocketFactory as UdpSocketFactory>::Error,
26 <<super::socket::DefaultSocketFactory as UdpSocketFactory>::Socket as UdpSocket>::Error,
27 >,
28> {
29 let mut factory = super::socket::DefaultSocketFactory::new();
30 browse_instance_dac_inner(remote_addr, instance_name, &mut factory).await
31}
32
33pub async fn browse_instance_dac_inner<SF: UdpSocketFactory>(
39 remote_addr: IpAddr,
40 instance_name: &str,
41 socket_factory: &mut SF,
42) -> Result<DacInfo, BrowserError<SF::Error, <SF::Socket as UdpSocket>::Error>> {
43 const VERSION: u8 = 0x01;
44
45 if instance_name.len() > super::MAX_INSTANCE_NAME_LEN {
46 return Err(BrowserError::InstanceNameTooLong);
47 }
48
49 let local_addr = if remote_addr.is_ipv4() {
50 IpAddr::V4(Ipv4Addr::UNSPECIFIED)
51 } else {
52 IpAddr::V6(Ipv6Addr::UNSPECIFIED)
53 };
54
55 let bind_to = SocketAddr::new(local_addr, 0);
56 let mut socket = socket_factory
57 .bind(&bind_to)
58 .await
59 .map_err(BrowserError::BindFailed)?;
60
61 let remote = SocketAddr::new(remote_addr, 1434);
62 socket
63 .connect(&remote)
64 .await
65 .map_err(|e| BrowserError::ConnectFailed(remote, e))?;
66
67 let mut buffer = [0u8; 2 + super::MAX_INSTANCE_NAME_LEN + 1];
68 buffer[0] = CLNT_UCAST_DAC;
69 buffer[1] = VERSION;
70 buffer[2..(2 + instance_name.len())].copy_from_slice(instance_name.as_bytes()); let buffer_len = 3 + instance_name.len();
72 socket
73 .send(&buffer[0..buffer_len])
74 .await
75 .map_err(|e| BrowserError::SendFailed(remote, e))?;
76
77 let mut buffer = [0u8; 6];
78
79 let bytes_received = socket
80 .recv(&mut buffer)
81 .await
82 .map_err(BrowserError::ReceiveFailed)?;
83
84 if bytes_received < 1 {
85 return Err(BrowserError::ProtocolError(
86 BrowserProtocolError::UnexpectedToken {
87 expected: BrowserProtocolToken::MessageIdentifier(SVR_RESP),
88 found: BrowserProtocolToken::EndOfMessage,
89 },
90 ));
91 }
92
93 if buffer[0] != SVR_RESP {
94 return Err(BrowserError::ProtocolError(
95 BrowserProtocolError::UnexpectedToken {
96 expected: BrowserProtocolToken::MessageIdentifier(SVR_RESP),
97 found: BrowserProtocolToken::MessageIdentifier(buffer[0]),
98 },
99 ));
100 }
101
102 if bytes_received < 3 {
103 return Err(BrowserError::ProtocolError(
104 BrowserProtocolError::UnexpectedToken {
105 expected: BrowserProtocolToken::MessageLength,
106 found: BrowserProtocolToken::EndOfMessage,
107 },
108 ));
109 }
110
111 let packet_size = u16::from_le_bytes([buffer[1], buffer[2]]) as usize;
112 if packet_size != buffer.len() {
113 return Err(BrowserError::ProtocolError(
114 BrowserProtocolError::LengthMismatch {
115 datagram: bytes_received,
116 header: packet_size,
117 },
118 ));
119 }
120
121 if bytes_received < 4 {
122 return Err(BrowserError::ProtocolError(
123 BrowserProtocolError::UnexpectedToken {
124 expected: BrowserProtocolToken::DacVersion(VERSION),
125 found: BrowserProtocolToken::EndOfMessage,
126 },
127 ));
128 }
129
130 if buffer[3] != VERSION {
131 return Err(BrowserError::ProtocolError(
132 BrowserProtocolError::UnexpectedToken {
133 expected: BrowserProtocolToken::DacVersion(VERSION),
134 found: BrowserProtocolToken::DacVersion(buffer[3]),
135 },
136 ));
137 }
138
139 if bytes_received < 6 {
140 return Err(BrowserError::ProtocolError(
141 BrowserProtocolError::UnexpectedToken {
142 expected: BrowserProtocolToken::DacPort,
143 found: BrowserProtocolToken::EndOfMessage,
144 },
145 ));
146 }
147
148 let port = u16::from_le_bytes([buffer[4], buffer[5]]);
149 return Ok(DacInfo { port });
150}