|
Lines 153-181
Link Here
|
| 153 |
int sock, gaierr; |
153 |
int sock, gaierr; |
| 154 |
struct addrinfo hints, *res; |
154 |
struct addrinfo hints, *res; |
| 155 |
|
155 |
|
| 156 |
/* |
|
|
| 157 |
* If we are running as root and want to connect to a privileged |
| 158 |
* port, bind our own socket to a privileged port. |
| 159 |
*/ |
| 160 |
if (privileged) { |
| 161 |
int p = IPPORT_RESERVED - 1; |
| 162 |
PRIV_START; |
| 163 |
sock = rresvport_af(&p, ai->ai_family); |
| 164 |
PRIV_END; |
| 165 |
if (sock < 0) |
| 166 |
error("rresvport: af=%d %.100s", ai->ai_family, |
| 167 |
strerror(errno)); |
| 168 |
else |
| 169 |
debug("Allocated local port %d.", p); |
| 170 |
return sock; |
| 171 |
} |
| 172 |
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); |
156 |
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); |
| 173 |
if (sock < 0) |
157 |
if (sock < 0) { |
| 174 |
error("socket: %.100s", strerror(errno)); |
158 |
error("socket: %.100s", strerror(errno)); |
|
|
159 |
return sock; |
| 160 |
} |
| 161 |
if (!privileged && !options.bind_address) |
| 162 |
return sock; |
| 175 |
|
163 |
|
| 176 |
/* Bind the socket to an alternative local IP address */ |
164 |
/* Bind the socket to an alternative local IP address */ |
| 177 |
if (options.bind_address == NULL) |
|
|
| 178 |
return sock; |
| 179 |
|
165 |
|
| 180 |
memset(&hints, 0, sizeof(hints)); |
166 |
memset(&hints, 0, sizeof(hints)); |
| 181 |
hints.ai_family = ai->ai_family; |
167 |
hints.ai_family = ai->ai_family; |
|
Lines 189-200
Link Here
|
| 189 |
close(sock); |
175 |
close(sock); |
| 190 |
return -1; |
176 |
return -1; |
| 191 |
} |
177 |
} |
| 192 |
if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { |
178 |
|
| 193 |
error("bind: %s: %s", options.bind_address, strerror(errno)); |
179 |
if (privileged) { |
| 194 |
close(sock); |
180 |
int rc; |
| 195 |
freeaddrinfo(res); |
181 |
|
| 196 |
return -1; |
182 |
PRIV_START; |
| 197 |
} |
183 |
rc = bindresvport_sa(sock, res->ai_addr); |
|
|
184 |
PRIV_END; |
| 185 |
if (rc < 0) { |
| 186 |
error("bindresvport_sa: %s: %s", options.bind_address, |
| 187 |
strerror(errno)); |
| 188 |
close(sock); |
| 189 |
sock = -1; |
| 190 |
} |
| 191 |
} else |
| 192 |
if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { |
| 193 |
error("bind: %s: %s", options.bind_address, |
| 194 |
strerror(errno)); |
| 195 |
close(sock); |
| 196 |
sock = -1; |
| 197 |
} |
| 198 |
|
| 198 |
freeaddrinfo(res); |
199 |
freeaddrinfo(res); |
| 199 |
return sock; |
200 |
return sock; |
| 200 |
} |
201 |
} |