I managed to get this working and thought I'd share it here for anybody else who stumbled across it. It takes a slightly different approach, so see what works best for you.
As a disclaimer, this works for PPTP connections set up using the network prefpane in System Preferences. I'm sure you could get it working with an OpenVPN client, but I'm not sure how you'd do that.
I'm using a modified AppleScript application - the bulk of the original code was written by Jack0817 on the
µTorrent forums, so most of the credit goes to him. I just changed the application to Transmission and added some code to grab the VPN's current IP address and edit the plist file (so that if the VPN goes down for any reason Transmission INSTANTLY stops downloading), similar to some of the other solutions.
The script runs every 60 seconds and checks if the VPN is connected. If it's not, it closes Transmission and attempts to reconnect to the VPN. Once the VPN is reconnected it will get the VPN's IP address, bind Transmission to this IP address, then start Transmission up again. Because Transmission doesn't start unless the VPN is fully connected, the script usually needs to cycle twice if the VPN disconnects; once to reconnect to the VPN and then again to start Transmission. Even so, this ensures that (assuming you have no connection problems with your VPN) your torrents will only be down for 2 minutes.
You'll need to add BindAddressIPv4 to the Transmission plist file first (as covered in the earlier posts first), then save this script as an application (make sure you check "Stay open after run handler") and, if you like, set it run on startup:
Code: Select all
------------------------------------------------
--Main Routine
------------------------------------------------
on idle
--Script Variables
set appName to "Transmission"
set vpnName to "NAME_OF_VPN" -- Enter the name of your VPN service as it
set waitTIme to 60 as integer -- appears in your Network preferences
--Main Script Logic
if isVPNConnected(vpnName) then
startApplication(appName)
else
stopApplication(appName)
connectVPNConnection(vpnName)
end if
return waitTIme
end idle
------------------------------------------------
--Sub Routine - Determines if specified vpn is connected
------------------------------------------------
on isVPNConnected(vpnName)
--Init return value to default
set isConnected to false
tell application "System Events"
tell current location of network preferences
set vpnConnection to the service vpnName
set isConnected to current configuration of vpnConnection is connected
end tell
end tell
return isConnected
end isVPNConnected
------------------------------------------------
--Sub Routine - Attempts to connect to the specified VPN
------------------------------------------------
on connectVPNConnection(vpnName)
tell application "System Events"
tell current location of network preferences
set vpnConnection to the service vpnName
if vpnConnection is not null then
connect vpnConnection
end if
end tell
end tell
end connectVPNConnection
------------------------------------------------
--Sub Routine - Starts an application if it is not already running
------------------------------------------------
on startApplication(appName)
if appIsRunning(appName) is false then
set vpnAddress to (do shell script ("/sbin/ifconfig ppp0 | grep 'inet ' | cut -d' ' -f 2")) -- change ppp0 to vpn interface in ifconfig if needed
tell application "System Events"
set plistFile to property list file "/Users/robroy/Library/Preferences/org.m0k.transmission.plist"
tell plistFile
set value of property list item "BindAddressIPv4" to vpnAddress
end tell
end tell
tell application appName to activate
end if
end startApplication
------------------------------------------------
--Sub Routine - Stop an application if it is running
------------------------------------------------
on stopApplication(appName)
if appIsRunning(appName) then
tell application appName to quit
end if
end stopApplication
------------------------------------------------
--Sub Routine - Determines if specified app is currently running
------------------------------------------------
on appIsRunning(appName)
set isRunning to false
tell application "System Events"
set isRunning to (name of processes) contains appName
end tell
return isRunning
end appIsRunning
Two last things - first, you'll want to make sure that you've disabled any warnings about closing Transmission (otherwise the script will hang as Transmission asks you if you want to close with active transfers).
Second, if you want to make Transmission launch on startup, use this script instead of adding Transmission itself to the login items. This will ensure that the VPN is fully started (and that you have the VPNs current IP address in Transmission's plist file).
EDIT: Updated link to µTorrent forums thread so that it points to Jack0817's post.