aboutsummaryrefslogtreecommitdiff
path: root/src/common/util.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2005-08-03 20:42:17 +0000
committerNick Mathewson <nickm@torproject.org>2005-08-03 20:42:17 +0000
commit11ff0aba80d7ccc77e52040e99d20d38046c25d1 (patch)
tree9ca1fc07701b7ff81917b69af599302e31dd7136 /src/common/util.c
parentceb02cee2c021ae34d07d431a6e13a02827adf5d (diff)
downloadtor-11ff0aba80d7ccc77e52040e99d20d38046c25d1.tar
tor-11ff0aba80d7ccc77e52040e99d20d38046c25d1.tar.gz
Make clients regenerate their keys when their IP address changes.
svn:r4688
Diffstat (limited to 'src/common/util.c')
-rw-r--r--src/common/util.c59
1 files changed, 57 insertions, 2 deletions
diff --git a/src/common/util.c b/src/common/util.c
index bbe31ff11..390889d4c 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -695,7 +695,8 @@ int parse_iso_time(const char *cp, time_t *t) {
* must be 1 if fd was returned by socket() or accept(), and 0 if fd
* was returned by open(). Return the number of bytes written, or -1
* on error. Only use if fd is a blocking fd. */
-int write_all(int fd, const char *buf, size_t count, int isSocket) {
+int
+write_all(int fd, const char *buf, size_t count, int isSocket) {
size_t written = 0;
int result;
@@ -716,7 +717,8 @@ int write_all(int fd, const char *buf, size_t count, int isSocket) {
* was returned by socket() or accept(), and 0 if fd was returned by
* open(). Return the number of bytes read, or -1 on error. Only use
* if fd is a blocking fd. */
-int read_all(int fd, char *buf, size_t count, int isSocket) {
+int
+read_all(int fd, char *buf, size_t count, int isSocket) {
size_t numread = 0;
int result;
@@ -1319,6 +1321,59 @@ is_plausible_address(const char *name)
return 1;
}
+/**
+ * Set *<b>addr</b> to the host-order IPv4 address (if any) of whatever
+ * interface connects to the internet. This address should only be used in
+ * checking whether our address has changed. Return 0 on success, -1 on
+ * failure.
+ */
+int
+get_interface_address(uint32_t *addr)
+{
+ int sock=-1, r=-1;
+ struct sockaddr_in target_addr, my_addr;
+ socklen_t my_addr_len = sizeof(my_addr);
+
+ tor_assert(addr);
+ *addr = 0;
+
+ sock = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
+ if (sock < 0) {
+ int e = tor_socket_errno(-1);
+ log_fn(LOG_WARN, "unable to create socket: %s", tor_socket_strerror(e));
+ goto err;
+ }
+
+ memset(&target_addr, 0, sizeof(target_addr));
+ target_addr.sin_family = AF_INET;
+ /* discard port */
+ target_addr.sin_port = 9;
+ /* 18.0.0.1 (Don't worry: no packets are sent. We just need a real address
+ * on the internet.) */
+ target_addr.sin_addr.s_addr = htonl(0x12000001);
+
+ if (connect(sock,(struct sockaddr *)&target_addr,sizeof(target_addr))<0) {
+ int e = tor_socket_errno(sock);
+ log_fn(LOG_WARN, "connnect() failed: %s", tor_socket_strerror(e));
+ goto err;
+ }
+
+ /* XXXX Can this be right on IPv6 clients? */
+ if (getsockname(sock, &my_addr, &my_addr_len)) {
+ int e = tor_socket_errno(sock);
+ log_fn(LOG_WARN, "getsockname() failed: %s", tor_socket_strerror(e));
+ goto err;
+ }
+
+ *addr = ntohl(my_addr.sin_addr.s_addr);
+
+ r=0;
+ err:
+ if (sock >= 0)
+ tor_close_socket(sock);
+ return r;
+}
+
/* =====
* Process helpers
* ===== */