Changeset 94521 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Apr 7, 2022 3:18:48 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DrvCloudTunnel.cpp
r93394 r94521 87 87 /** SSH connection timeout in seconds. */ 88 88 long ulTimeoutInSecounds; 89 90 /** Primary proxy type. */ 91 char *pszPrimaryProxyType; 92 /** Primary proxy server IP address. */ 93 char *pszPrimaryProxyHost; 94 /** Primary proxy server port. */ 95 uint16_t u16PrimaryProxyPort; 96 /** Primary proxy user. */ 97 char *pszPrimaryProxyUser; 98 /** Primary proxy password. */ 99 char *pszPrimaryProxyPassword; 100 101 /** Secondary proxy type. */ 102 char *pszSecondaryProxyType; 103 /** Secondary proxy server IP address. */ 104 char *pszSecondaryProxyHost; 105 /** Secondary proxy server port. */ 106 uint16_t u16SecondaryProxyPort; 107 /** Secondary proxy user. */ 108 char *pszSecondaryProxyUser; 109 /** Secondary proxy password. */ 110 char *pszSecondaryProxyPassword; 111 89 112 /** Cloud tunnel instance string. */ 90 113 char *pszInstance; … … 1025 1048 rc = drvCloudTunnelExecuteRemoteCommand(pThis, "sudo ip link set dev %s address %RTmac", pThis->pszCloudPrimaryInterface, pThis->targetMac.au8); 1026 1049 if (RT_SUCCESS(rc)) 1050 rc = drvCloudTunnelExecuteRemoteCommand(pThis, "sudo ifconfig %s 0.0.0.0", pThis->pszCloudPrimaryInterface); /* Make sure no IP is configured on primary */ 1051 if (RT_SUCCESS(rc)) 1027 1052 rc = drvCloudTunnelExecuteRemoteCommand(pThis, "sudo ip link set dev %s master br0", pThis->pszCloudPrimaryInterface); 1028 1053 if (RT_SUCCESS(rc)) … … 1127 1152 1128 1153 1129 static int drvCloudTunnel SwitchToSecondary(PDRVCLOUDTUNNEL pThis)1154 static int drvCloudTunnelNewSession(PDRVCLOUDTUNNEL pThis, bool fPrimary) 1130 1155 { 1131 1156 pThis->pSshSession = ssh_new(); … … 1139 1164 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS, 1140 1165 N_("Failed to set SSH_OPTIONS_USER")); 1141 if (ssh_options_set(pThis->pSshSession, SSH_OPTIONS_HOST, pThis->pszPrimaryIP) < 0)1166 if (ssh_options_set(pThis->pSshSession, SSH_OPTIONS_HOST, fPrimary ? pThis->pszPrimaryIP : pThis->pszSecondaryIP) < 0) 1142 1167 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS, 1143 1168 N_("Failed to set SSH_OPTIONS_HOST")); … … 1147 1172 N_("Failed to set SSH_OPTIONS_TIMEOUT")); 1148 1173 1174 const char *pcszProxyType = fPrimary ? pThis->pszPrimaryProxyType : pThis->pszSecondaryProxyType; 1175 if (pcszProxyType) 1176 { 1177 char szProxyCmd[1024]; 1178 1179 const char *pcszProxyUser = fPrimary ? pThis->pszPrimaryProxyUser : pThis->pszSecondaryProxyUser; 1180 if (pcszProxyUser) 1181 RTStrPrintf(szProxyCmd, sizeof(szProxyCmd), "#VBoxProxy%s %s %u %s %s", 1182 fPrimary ? pThis->pszPrimaryProxyType : pThis->pszSecondaryProxyType, 1183 fPrimary ? pThis->pszPrimaryProxyHost : pThis->pszSecondaryProxyHost, 1184 fPrimary ? pThis->u16PrimaryProxyPort : pThis->u16SecondaryProxyPort, 1185 fPrimary ? pThis->pszPrimaryProxyUser : pThis->pszSecondaryProxyUser, 1186 fPrimary ? pThis->pszPrimaryProxyPassword : pThis->pszSecondaryProxyPassword); 1187 else 1188 RTStrPrintf(szProxyCmd, sizeof(szProxyCmd), "#VBoxProxy%s %s %u", 1189 fPrimary ? pThis->pszPrimaryProxyType : pThis->pszSecondaryProxyType, 1190 fPrimary ? pThis->pszPrimaryProxyHost : pThis->pszSecondaryProxyHost, 1191 fPrimary ? pThis->u16PrimaryProxyPort : pThis->u16SecondaryProxyPort); 1192 LogRel(("%s: using proxy command '%s'\n", pThis->pszInstance, szProxyCmd)); 1193 if (ssh_options_set(pThis->pSshSession, SSH_OPTIONS_PROXYCOMMAND, szProxyCmd) < 0) 1194 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS, 1195 N_("Failed to set SSH_OPTIONS_PROXYCOMMAND")); 1196 } 1197 1149 1198 int rc = ssh_connect(pThis->pSshSession); 1150 if (rc != SSH_OK)1199 for (int cAttempt = 1; rc != SSH_OK && cAttempt <= 5; cAttempt++) 1151 1200 { 1152 1201 ssh_disconnect(pThis->pSshSession); 1153 1202 /* One more time, just to be sure. */ 1154 LogRel(("%s: failed to connect to %s, retrying...\n", pThis->pszInstance, pThis->pszPrimaryIP)); 1203 LogRel(("%s: failed to connect to %s, retrying(#%d)...\n", pThis->pszInstance, 1204 fPrimary ? pThis->pszPrimaryIP : pThis->pszSecondaryIP, cAttempt)); 1205 RTThreadSleep(10000); /* Sleep 10 seconds, then retry */ 1155 1206 rc = ssh_connect(pThis->pSshSession); 1156 1207 } 1157 1208 if (rc != SSH_OK) 1158 1209 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS, 1159 N_("CloudTunnel: Failed to connect to primary interface"));1210 N_("CloudTunnel: Failed to connect to %s interface"), fPrimary ? "primary" : "secondary"); 1160 1211 1161 1212 rc = ssh_userauth_publickey(pThis->pSshSession, NULL, pThis->SshKey); … … 1164 1215 N_("Failed to authenticate with public key")); 1165 1216 1217 return VINF_SUCCESS; 1218 } 1219 1220 static int drvCloudTunnelSwitchToSecondary(PDRVCLOUDTUNNEL pThis) 1221 { 1222 int rc = drvCloudTunnelNewSession(pThis, true /* fPrimary */); 1166 1223 /* 1167 1224 * Establish temporary console channel and configure the cloud instance 1168 1225 * to bridge the tunnel channel to instance's primary interface. 1169 1226 */ 1170 rc = drvCloudTunnelCloudInstanceInitialConfig(pThis); 1227 if (RT_SUCCESS(rc)) 1228 rc = drvCloudTunnelCloudInstanceInitialConfig(pThis); 1171 1229 1172 1230 ssh_disconnect(pThis->pSshSession); … … 1180 1238 static int establishTunnel(PDRVCLOUDTUNNEL pThis) 1181 1239 { 1182 pThis->pSshSession = ssh_new(); 1183 if (pThis->pSshSession == NULL) 1184 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS, 1185 N_("CloudTunnel: Failed to allocate new SSH session")); 1186 if (ssh_options_set(pThis->pSshSession, SSH_OPTIONS_LOG_VERBOSITY, &pThis->iSshVerbosity) < 0) 1187 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS, 1188 N_("Failed to set SSH_OPTIONS_LOG_VERBOSITY")); 1189 if (ssh_options_set(pThis->pSshSession, SSH_OPTIONS_USER, pThis->pszUser) < 0) 1190 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS, 1191 N_("Failed to set SSH_OPTIONS_USER")); 1192 if (ssh_options_set(pThis->pSshSession, SSH_OPTIONS_HOST, pThis->pszSecondaryIP) < 0) 1193 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS, 1194 N_("Failed to set SSH_OPTIONS_HOST")); 1195 1196 if (ssh_options_set(pThis->pSshSession, SSH_OPTIONS_TIMEOUT, &pThis->ulTimeoutInSecounds) < 0) 1197 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS, 1198 N_("Failed to set SSH_OPTIONS_TIMEOUT")); 1199 1200 int rc = ssh_connect(pThis->pSshSession); 1201 if (rc != SSH_OK) 1202 { 1203 ssh_disconnect(pThis->pSshSession); 1204 /* One more time, just to be sure. */ 1205 Log(("%s: failed to connect to %s, retrying...\n", pThis->pszInstance, pThis->pszSecondaryIP)); 1206 rc = ssh_connect(pThis->pSshSession); 1207 } 1208 if (rc != SSH_OK) 1209 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS, 1210 N_("CloudTunnel: Failed to connect to secondary interface")); 1211 1212 rc = ssh_userauth_publickey(pThis->pSshSession, NULL, pThis->SshKey); 1213 if (rc != SSH_AUTH_SUCCESS) 1214 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS, 1215 N_("Failed to authenticate with public key")); 1216 1217 rc = drvCloudTunnelCloudInstanceFinalConfig(pThis); 1240 int rc = drvCloudTunnelNewSession(pThis, false /* fPrimary */); 1241 if (RT_SUCCESS(rc)) 1242 rc = drvCloudTunnelCloudInstanceFinalConfig(pThis); 1218 1243 if (RT_SUCCESS(rc)) 1219 1244 rc = drvCloudTunnelOpenTunnelChannel(pThis); … … 1262 1287 /* -=-=-=-=- PDMDRVREG -=-=-=-=- */ 1263 1288 1289 DECLINLINE(void) drvCloudTunnelStrFree(char **ppszString) 1290 { 1291 if (*ppszString) 1292 { 1293 RTStrFree(*ppszString); 1294 *ppszString = NULL; 1295 } 1296 } 1297 1298 DECLINLINE(void) drvCloudTunnelHeapFree(PPDMDRVINS pDrvIns, char **ppszString) 1299 { 1300 if (*ppszString) 1301 { 1302 PDMDrvHlpMMHeapFree(pDrvIns, *ppszString); 1303 *ppszString = NULL; 1304 } 1305 } 1306 1264 1307 /** 1265 1308 * Destruct a driver instance. … … 1286 1329 } 1287 1330 1288 if (pThis->pszCloudPrimaryInterface) 1289 { 1290 RTStrFree(pThis->pszCloudPrimaryInterface); 1291 pThis->pszCloudPrimaryInterface = NULL; 1292 } 1293 1294 if (pThis->pszSecondaryIP) 1295 { 1296 RTStrFree(pThis->pszSecondaryIP); 1297 pThis->pszSecondaryIP = NULL; 1298 } 1299 1300 if (pThis->pszPrimaryIP) 1301 { 1302 RTStrFree(pThis->pszPrimaryIP); 1303 pThis->pszPrimaryIP = NULL; 1304 } 1305 1306 if (pThis->pszUser) 1307 { 1308 RTStrFree(pThis->pszUser); 1309 pThis->pszUser = NULL; 1310 } 1311 1312 if (pThis->pszInstanceDev) 1313 { 1314 RTStrFree(pThis->pszInstanceDev); 1315 pThis->pszInstanceDev = NULL; 1316 } 1317 1318 if (pThis->pszInstanceIo) 1319 { 1320 RTStrFree(pThis->pszInstanceIo); 1321 pThis->pszInstanceIo = NULL; 1322 } 1323 1324 if (pThis->pszInstance) 1325 { 1326 RTStrFree(pThis->pszInstance); 1327 pThis->pszInstance = NULL; 1328 } 1329 1330 if (pThis->pszOutputBuffer) 1331 { 1332 RTStrFree(pThis->pszOutputBuffer); 1333 pThis->pszOutputBuffer = NULL; 1334 } 1335 1336 if (pThis->pszCommandBuffer) 1337 { 1338 RTStrFree(pThis->pszCommandBuffer); 1339 pThis->pszCommandBuffer = NULL; 1340 } 1331 drvCloudTunnelStrFree(&pThis->pszCloudPrimaryInterface); 1332 1333 drvCloudTunnelHeapFree(pDrvIns, &pThis->pszPrimaryProxyType); 1334 drvCloudTunnelStrFree(&pThis->pszPrimaryProxyHost); 1335 drvCloudTunnelHeapFree(pDrvIns, &pThis->pszPrimaryProxyUser); 1336 drvCloudTunnelStrFree(&pThis->pszPrimaryProxyPassword); 1337 1338 drvCloudTunnelHeapFree(pDrvIns, &pThis->pszSecondaryProxyType); 1339 drvCloudTunnelStrFree(&pThis->pszSecondaryProxyHost); 1340 drvCloudTunnelHeapFree(pDrvIns, &pThis->pszSecondaryProxyUser); 1341 drvCloudTunnelStrFree(&pThis->pszSecondaryProxyPassword); 1342 1343 drvCloudTunnelStrFree(&pThis->pszSecondaryIP); 1344 drvCloudTunnelStrFree(&pThis->pszPrimaryIP); 1345 drvCloudTunnelStrFree(&pThis->pszUser); 1346 1347 drvCloudTunnelStrFree(&pThis->pszInstanceDev); 1348 drvCloudTunnelStrFree(&pThis->pszInstanceIo); 1349 drvCloudTunnelStrFree(&pThis->pszInstance); 1350 1351 drvCloudTunnelStrFree(&pThis->pszOutputBuffer); 1352 drvCloudTunnelStrFree(&pThis->pszCommandBuffer); 1341 1353 1342 1354 ssh_key_free(pThis->SshKey); … … 1442 1454 "|PrimaryIP" 1443 1455 "|SecondaryIP" 1444 "|TargetMAC", 1445 ""); 1456 "|TargetMAC" 1457 1458 "|PrimaryProxyType" 1459 "|PrimaryProxyHost" 1460 "|PrimaryProxyPort" 1461 "|PrimaryProxyUser" 1462 "|PrimaryProxyPassword" 1463 "|SecondaryProxyType" 1464 "|SecondaryProxyHost" 1465 "|SecondaryProxyPort" 1466 "|SecondaryProxyUser" 1467 "|SecondaryProxyPassword" 1468 1469 ,""); 1446 1470 1447 1471 /* … … 1513 1537 return PDMDRV_SET_ERROR(pDrvIns, VERR_INVALID_BASE64_ENCODING, 1514 1538 N_("DrvCloudTunnel: Configuration error: Converting \"SshKey\" from base64 failed")); 1539 1540 /* PrimaryProxyType is optional */ 1541 rc = pHlp->pfnCFGMQueryStringAllocDef(pCfg, "PrimaryProxyType", &pThis->pszPrimaryProxyType, NULL); 1542 if (RT_FAILURE(rc)) 1543 return PDMDRV_SET_ERROR(pDrvIns, rc, 1544 N_("DrvCloudTunnel: Configuration error: Querying \"PrimaryProxyType\" as string failed")); 1545 if (pThis->pszPrimaryProxyType) 1546 { 1547 rc = pHlp->pfnCFGMQueryString(pCfg, "PrimaryProxyHost", szVal, sizeof(szVal)); 1548 if (RT_FAILURE(rc)) 1549 return PDMDRV_SET_ERROR(pDrvIns, rc, 1550 N_("DrvCloudTunnel: Configuration error: Querying \"PrimaryProxyHost\" as string failed")); 1551 rc = RTNetStrToIPv4Addr(szVal, &tmpAddr); 1552 if (RT_FAILURE(rc)) 1553 return PDMDRV_SET_ERROR(pDrvIns, rc, 1554 N_("DrvCloudTunnel: Configuration error: \"PrimaryProxyHost\" is not valid")); 1555 else 1556 pThis->pszPrimaryProxyHost = RTStrDup(szVal); 1557 1558 uint64_t u64Val; 1559 rc = pHlp->pfnCFGMQueryInteger(pCfg, "PrimaryProxyPort", &u64Val); 1560 if (RT_FAILURE(rc)) 1561 return PDMDRV_SET_ERROR(pDrvIns, rc, 1562 N_("DrvCloudTunnel: Configuration error: Querying \"PrimaryProxyPort\" as integer failed")); 1563 if (u64Val > 0xFFFF) 1564 return PDMDRV_SET_ERROR(pDrvIns, rc, 1565 N_("DrvCloudTunnel: Configuration error: \"PrimaryProxyPort\" is not valid")); 1566 pThis->u16PrimaryProxyPort = (uint16_t)u64Val; 1567 1568 /* PrimaryProxyUser is optional */ 1569 rc = pHlp->pfnCFGMQueryStringAllocDef(pCfg, "PrimaryProxyUser", &pThis->pszPrimaryProxyUser, NULL); 1570 if (RT_FAILURE(rc)) 1571 return PDMDRV_SET_ERROR(pDrvIns, rc, 1572 N_("DrvCloudTunnel: Configuration error: Querying \"PrimaryProxyUser\" as string failed")); 1573 /* PrimaryProxyPassword must be present if PrimaryProxyUser is present */ 1574 if (pThis->pszPrimaryProxyUser) 1575 { 1576 rc = pHlp->pfnCFGMQueryPassword(pCfg, "PrimaryProxyPassword", szVal, sizeof(szVal)); 1577 if (RT_FAILURE(rc)) 1578 return PDMDRV_SET_ERROR(pDrvIns, rc, 1579 N_("DrvCloudTunnel: Configuration error: Querying \"PrimaryProxyPassword\" as string failed")); 1580 pThis->pszPrimaryProxyPassword = RTStrDup(szVal); 1581 } 1582 } 1583 1584 /* SecondaryProxyType is optional */ 1585 rc = pHlp->pfnCFGMQueryStringAllocDef(pCfg, "SecondaryProxyType", &pThis->pszSecondaryProxyType, NULL); 1586 if (RT_FAILURE(rc)) 1587 return PDMDRV_SET_ERROR(pDrvIns, rc, 1588 N_("DrvCloudTunnel: Configuration error: Querying \"SecondaryProxyType\" as string failed")); 1589 if (pThis->pszSecondaryProxyType) 1590 { 1591 if (RT_FAILURE(rc)) 1592 return PDMDRV_SET_ERROR(pDrvIns, rc, 1593 N_("DrvCloudTunnel: Configuration error: Querying \"SecondaryProxyType\" as string failed")); 1594 1595 rc = pHlp->pfnCFGMQueryString(pCfg, "SecondaryProxyHost", szVal, sizeof(szVal)); 1596 if (RT_FAILURE(rc)) 1597 return PDMDRV_SET_ERROR(pDrvIns, rc, 1598 N_("DrvCloudTunnel: Configuration error: Querying \"SecondaryProxyHost\" as string failed")); 1599 rc = RTNetStrToIPv4Addr(szVal, &tmpAddr); 1600 if (RT_FAILURE(rc)) 1601 return PDMDRV_SET_ERROR(pDrvIns, rc, 1602 N_("DrvCloudTunnel: Configuration error: \"SecondaryProxyHost\" is not valid")); 1603 else 1604 pThis->pszSecondaryProxyHost = RTStrDup(szVal); 1605 1606 uint64_t u64Val; 1607 rc = pHlp->pfnCFGMQueryInteger(pCfg, "SecondaryProxyPort", &u64Val); 1608 if (RT_FAILURE(rc)) 1609 return PDMDRV_SET_ERROR(pDrvIns, rc, 1610 N_("DrvCloudTunnel: Configuration error: Querying \"SecondaryProxyPort\" as integer failed")); 1611 if (u64Val > 0xFFFF) 1612 return PDMDRV_SET_ERROR(pDrvIns, rc, 1613 N_("DrvCloudTunnel: Configuration error: \"SecondaryProxyPort\" is not valid")); 1614 pThis->u16SecondaryProxyPort = (uint16_t)u64Val; 1615 1616 /* SecondaryProxyUser is optional */ 1617 rc = pHlp->pfnCFGMQueryStringAllocDef(pCfg, "SecondaryProxyUser", &pThis->pszSecondaryProxyUser, NULL); 1618 if (RT_FAILURE(rc)) 1619 return PDMDRV_SET_ERROR(pDrvIns, rc, 1620 N_("DrvCloudTunnel: Configuration error: Querying \"SecondaryProxyUser\" as string failed")); 1621 /* SecondaryProxyPassword must be present if SecondaryProxyUser is present */ 1622 if (pThis->pszSecondaryProxyUser) 1623 { 1624 rc = pHlp->pfnCFGMQueryPassword(pCfg, "SecondaryProxyPassword", szVal, sizeof(szVal)); 1625 if (RT_FAILURE(rc)) 1626 return PDMDRV_SET_ERROR(pDrvIns, rc, 1627 N_("DrvCloudTunnel: Configuration error: Querying \"SecondaryProxyPassword\" as string failed")); 1628 pThis->pszSecondaryProxyPassword = RTStrDup(szVal); 1629 } 1630 } 1515 1631 1516 1632 pThis->pszCommandBuffer = (char *)RTMemAlloc(DRVCLOUDTUNNEL_COMMAND_BUFFER_SIZE);
Note:
See TracChangeset
for help on using the changeset viewer.