summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2016-07-07 16:28:43 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2016-07-07 16:28:43 -0700
commit951038a304f44a23ad264aa02ed084608a9a0a42 (patch)
tree21141ed69f88ece74e80db0c5970d347f0544a66
parent912ee199ede66cf79151a67cabc97b09c475aa1b (diff)
downloadinfinitytier-951038a304f44a23ad264aa02ed084608a9a0a42.tar.gz
infinitytier-951038a304f44a23ad264aa02ed084608a9a0a42.zip
Ignore /bits in IP assignments and just copy it from the corresponding LAN-local route. Having each managed IP assignment have its own bits field was just a source of user error and poor UX and was completely worthless.
-rw-r--r--controller/SqliteNetworkController.cpp48
1 files changed, 29 insertions, 19 deletions
diff --git a/controller/SqliteNetworkController.cpp b/controller/SqliteNetworkController.cpp
index 5e340c54..3d2f52f2 100644
--- a/controller/SqliteNetworkController.cpp
+++ b/controller/SqliteNetworkController.cpp
@@ -756,27 +756,37 @@ NetworkController::ResultCode SqliteNetworkController::doNetworkConfigRequest(co
sqlite3_bind_text(_sGetIpAssignmentsForNode,1,network.id,16,SQLITE_STATIC);
sqlite3_bind_text(_sGetIpAssignmentsForNode,2,member.nodeId,10,SQLITE_STATIC);
while (sqlite3_step(_sGetIpAssignmentsForNode) == SQLITE_ROW) {
- const unsigned char *const ip = (const unsigned char *)sqlite3_column_blob(_sGetIpAssignmentsForNode,0);
- if ((!ip)||(sqlite3_column_bytes(_sGetIpAssignmentsForNode,0) != 16))
+ const unsigned char *const ipbytes = (const unsigned char *)sqlite3_column_blob(_sGetIpAssignmentsForNode,0);
+ if ((!ipbytes)||(sqlite3_column_bytes(_sGetIpAssignmentsForNode,0) != 16))
continue;
- const int ipNetmaskBits = sqlite3_column_int(_sGetIpAssignmentsForNode,1);
+ //const int ipNetmaskBits = sqlite3_column_int(_sGetIpAssignmentsForNode,1);
const int ipVersion = sqlite3_column_int(_sGetIpAssignmentsForNode,2);
- if ((ipVersion == 4)&&(ipNetmaskBits >= 0)&&(ipNetmaskBits <= 32)) {
- if (nc.staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES) {
- struct sockaddr_in *const v4ip = reinterpret_cast<struct sockaddr_in *>(&(nc.staticIps[nc.staticIpCount++]));
- v4ip->sin_family = AF_INET;
- v4ip->sin_port = Utils::hton((uint16_t)ipNetmaskBits);
- memcpy(&(v4ip->sin_addr.s_addr),ip + 12,4);
- }
- haveManagedIpv4AutoAssignment = true;
- } else if ((ipVersion == 6)&&(ipNetmaskBits >= 0)&&(ipNetmaskBits <= 128)) {
+
+ InetAddress ip;
+ if (ipVersion == 4)
+ ip = InetAddress(ipbytes + 12,4,0);
+ else if (ipVersion == 6)
+ ip = InetAddress(ipbytes,16,0);
+ else continue;
+
+ // IP assignments are only pushed if there is a corresponding local route. We also now get the netmask bits from
+ // this route, ignoring the netmask bits field of the assigned IP itself. Using that was worthless and a source
+ // of user error / poor UX.
+ int routedNetmaskBits = 0;
+ for(unsigned int rk=0;rk<nc.routeCount;++rk) {
+ if ( (!nc.routes[rk].via.ss_family) && (reinterpret_cast<const InetAddress *>(&(nc.routes[rk].target))->containsAddress(ip)) )
+ routedNetmaskBits = reinterpret_cast<const InetAddress *>(&(nc.routes[rk].target))->netmaskBits();
+ }
+
+ if (routedNetmaskBits > 0) {
if (nc.staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES) {
- struct sockaddr_in6 *const v6ip = reinterpret_cast<struct sockaddr_in6 *>(&(nc.staticIps[nc.staticIpCount++]));
- v6ip->sin6_family = AF_INET6;
- v6ip->sin6_port = Utils::hton((uint16_t)ipNetmaskBits);
- memcpy(v6ip->sin6_addr.s6_addr,ip,16);
+ ip.setPort(routedNetmaskBits);
+ nc.staticIps[nc.staticIpCount++] = ip;
}
- haveManagedIpv6AutoAssignment = true;
+ if (ipVersion == 4)
+ haveManagedIpv4AutoAssignment = true;
+ else if (ipVersion == 6)
+ haveManagedIpv6AutoAssignment = true;
}
}
@@ -1076,7 +1086,7 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpPOST(
sqlite3_bind_text(_sAllocateIp,2,addrs,10,SQLITE_STATIC);
sqlite3_bind_int(_sAllocateIp,3,(int)0 /*ZT_IP_ASSIGNMENT_TYPE_ADDRESS*/);
sqlite3_bind_blob(_sAllocateIp,4,(const void *)ipBlob,16,SQLITE_STATIC);
- sqlite3_bind_int(_sAllocateIp,5,(int)a.netmaskBits());
+ sqlite3_bind_int(_sAllocateIp,5,(int)a.netmaskBits()); // NOTE: this field is now ignored but set it anyway
sqlite3_bind_int(_sAllocateIp,6,ipVersion);
if (sqlite3_step(_sAllocateIp) != SQLITE_DONE)
return 500;
@@ -1775,7 +1785,7 @@ unsigned int SqliteNetworkController::_doCPGet(
(unsigned int)sqlite3_column_int(_sGetIpAssignmentsForNode,1)
);
responseBody.append(firstIp ? "\"" : ",\"");
- responseBody.append(_jsonEscape(ip.toString()));
+ responseBody.append(_jsonEscape(ip.toIpString()));
responseBody.push_back('"');
firstIp = false;
}