14

My challenge

We have Exchange servers at various sites, but also aboard ships. The ships are connected to our network through satellite links when at sea, but switch to WiFi bridges when in port.

Due the high latency (500+ ms) and not-uncommon drop-outs (e.g. when the ships are turning), attempting to send any e-mails above a few megabytes while at sea, is likely to fail and be retried until the limit has been reached. The result: The email doesn't get delivered and each try consumes valuable bandwidth on the sat link.

One "solution" is to limit the maximum e-mail size to say 5 MB, but that's hardly user friendly and an unnecessary restriction while in port.

Rough idea

What I'd rather do, is to queue all e-mails larger than a set limit for later delivery when at sea, while sending all small e-mails immediately. I was then thinking I'd ping the hub transport server in our datacenter regularly, when latency drops under ~400 ms, I'd start processing the large e-mails queue. When latency goes up over 400 ms, I'd plug the hole and let e-mails queue up again.

Now, I haven't gotten my hands really dirty with Exchange since version 2003. Back then, you could schedule large e-mails for later delivery, so my idea was do something similar in Exchange 2010, then script a way to switch the delivery schedule for large e-mails between 'always' and 'never'.

Obstacle

It shouldn't be too complicated to create a script like that, but then I read that the feature I'd rely on was removed with Exchange 2007:

This was a feature present in Exchange 2003 but has been removed for Exchange 2007. It was set on an SMTP Connector with the 'use different delivery times for oversize messages'.

TechCenter: Is it possible to schedule email delivery based on size in Exchange?

Questions

Is it true? - Is this feature no longer present in Exchange 2010, or has it merely transformed into something similar, I can use to accomplish my goal? If so, what?

Is there another way to defer delivery of large e-mails on certain Exchange servers? It could be based on a schedule or maybe even requiring specific action - I'm fairly certain there will be some way to trigger the delivery through script, I just need large e-mails in a separate queue on ships.

Your thoughts on this will be highly appreciated! :-)

Edit #1: Refined Rough Idea

I stumpled upon two PowerShell CmdLets I think can bring me pretty close to my goal:

I toyed around with Get-Message for a while, to see what kind of messages the commands above would deal with.

Most importantly, these commands accept a message size filter. This command will list queued messages,on the current server, larger than 5 MB (5,242,880 bytes):

get-message -Filter {Size -gt 5242880}

It seems Get-Message only returns messages from various remote delivery queues. But does messages flowing within the server, however briefly, show up in a queue that Get/Suspend/Resume-Message will mess with?

If not, the solution could be as simple as a scheduled script every few minutes, along the lines of (in pseudo code):

if ping_rtt > 400 Then
    Suspend-Message -Filter {Size -gt 5242880}
Else
    Resume-Message
EndIf

Concerns/follow-up questions:

Mostly irrelvant now - see edit #2.

Will Get-Message only return messages from remote delivery queues - never messages for intra-server delivery? If not, does the identity name of remote delivery queues follow a certain pattern, that I can use for filtering?

Could/should this be done via a custom Transport Agent (as suggested by @longneck) or an Event Sink (if this concept still exists in Exchange 2010)?

Say I run the script every 5 minutes, that still means large messages being sent, can potentially cause problems for up to 5 minutes, before getting suspended. We'd still be better off than we are now, but it's not optimal. I could increase the frequency to every minute, but it wouldn't be the most elegant solution.

Even if I only check round-trip time every 5 minutes (to save sat traffic), what Exchange mechanism would I need to setup, in order to check against the last recorded RTT, each time a message is submitted that goes to a remote delivery queue, and then take approriate action?

Edit #2: Proposed Solutions

Allow me to summarise the proposed solutions, and their pros and cons as I see it:

Custom Transport Agent

Concept

  • Periodically monitor latency, classify as high or low (threshold: 400 ms?)
  • Through a custom Transport Agent, suspend/resume all e-mails larger than a set threshold, when latency classification changes
  • Through the custom TA, immediately put subsequently submitted large messages in "suspend" mode, if latency is high

Strengths

  • Large e-mails are never attempted delivered when latency is high

Weaknesses

  • No development skills to make this in-house (note to self: source code should belong to my company as part of the contract with the external developer)
  • 3rd party software that ties into Exchange can cause problems when patching or updating
  • Some sort of support agreement necessary, in case something goes wrong (see above)

Moderate Large Messages

Concept

  • Periodically monitor latency, classify as high or low (threshold: 400 ms?)
  • Based on latency classification, configure Exchange Transport Rules through scripting, to either let all messages flow or forward large messages to moderator
  • Approve messages in moderator queue when ship's in port, possibly by a human

Strengths

  • Large e-mails are never attempted delivered when latency is high
  • Messages are suspended using native native Exchange Transport Rules

Weaknesses

  • By the looks of it, messages can not be approved programmatically when latency is low, hence human intervention is required each time ship's in port
  • Possibly privacy issues, if moderation is not handled programmatically

Questions

  • Can messages be approved programmatically from moderator mailbox? How?

Scheduled PowerShell commands

Concept

  • Periodically monitor latency, classify as high or low (threshold: 400 ms?)
  • As long as latency is high, frequently (every minute?) suspend any large messages (Suspend-Message -Filter {Size -gt 5242880})
  • When latency drops to low, resume all messages (Resume-Message)

Strengths

  • Very simple to implement

Weaknesses

  • Not the most elegant solution
  • Delivery of each new large message can be attempted for as long as the interval between Suspend-Message commands, possibly still wasting some bandwidth and create congestions (though very briefly compared to not doing anything)

Questions

  • Any ideas on how to prevent attempts to deliver large messages, in-between Suspend-Message commands?
  • Will Get-Message only return messages from remote delivery queues - never messages for intra-server delivery? If not, does the identity name of remote delivery queues follow a certain pattern, that I can use for filtering?

Edit #3: The Way Forward

After bringing the proposed solutions up in my team (including the SMTP proxy, which I failed to include in edit #2), and based on my own gut feeling, we decided to go for a custom Exchange Transport Agent.

I'm in contact with a couple of consultancy companies, who will get back to me with how the will attack the problem and what it would cost.

If you have any experience with outsourcing programming tasks, feel free to leave feedback to my related question on Stack Overflow, because I don't.

abstrask
  • 1,668
  • 14
  • 24
  • 3
    +1 for one of the better questions I've seen of late. – John Gardeniers Jan 25 '13 at 09:23
  • which roles do the Exchange servers on the ships hold? – August Jan 25 '13 at 13:52
  • The Exchange servers on ships hold the Hub Transport, Mailbox and Client Access roles. – abstrask Jan 25 '13 at 13:59
  • 1
    are you running any type of QoS or WAN optimizer on the satellite links? – longneck Jan 25 '13 at 14:04
  • Hmm with the Mailbox role, you could also have the link get saturated when external mail gets sent to a mailbox of someone on the ship's Exchange server... – August Jan 25 '13 at 14:15
  • @longneck: Yes, both. Exchange traffic has the default priority. Only VoIP and Citrix prioritised higher. We also use Cisco WAAS, but since intra-Exchange traffic is TLS tunnelled, it doesn't do much good here. With that said, we are planning to disable TLS between ships and datacenter, so WAAS can optimise the traffic. This will help with our problem, but not eliminate it – abstrask Jan 25 '13 at 14:37
  • @August: That's true, but that doesn't happen a lot. The issues we've experienced, is mostly with staff aboard ships, sending e-mails out of their Exchange server. With that said, it would be great if the same mechanism can be applied to all mail queues towards ships. – abstrask Jan 25 '13 at 14:40

3 Answers3

3

Message Moderation

One probably non-ideal solution is to use a transport rule to forward messages over a certain size to either the sender's manager or a designated mailbox (on the ship's Exchange server) for moderation. This way if they are at sea, large messages can be essentially queued up in another mailbox. When the ship arrives at port, the manager or designated moderator can approve them for delivery.

The downsides are:

  • this rule is always on unless you manually disable it (but could be done via a script) so even in port large messages would redirect to the moderator mailbox
  • all large messages would need manual review by someone before sending, but you can add exceptions in the rule for specific things
  • another person would be reading outgoing mail, which may not be ideal due to privacy concerns, but this depends on your org

One upside is you would have a human making decisions on whether or not a message should even be sent such as if a user was trying to send a bunch of non work-related crap that would just bog down the connection for no reason. They could be corrected by administrative controls like pointing to a policy and slapping them on the wrist so they don't do it again.

Exchange 2010 Transport Rules

Custom Script

RE: A custom script to manage large e-mails. I could see something like the below that would enable/disable your Send Connector on the Exchange server. A downside is all mail is held in queue instead of just large messages, but some logic along these lines should work:

  1. Check for latency. If it is low, enable the Send Connector, unsuspend any large messages, and wait 5 minutes (or other arbitrary length of time). If it is high, disable the Send Connector.
  2. Wait 5 minutes.
  3. After 5 minutes, check for large messages and suspend them. Re-enable the Send Connector so small, queued messages are released until the queue is empty (you could even cycle through 1 message at a time so as to not clog the queue/WAN link after re-enabling the Send connector)
  4. Disable the Send Connector and goto #1

This logic isn't fully polished to make 100% sense, but you get the idea - queue all mail, check for latency, suspend large messages if it is high, un-queue mail, queue all mail, etc. Another downside of running a script like this is if it ever crashes or stops, how would you know to reinitialize it with no IT staff on board the ships? It could either potentially stop all outbound mail indefinitely (if it stops after disabling the Send Connector) or you could lose your large message control if it just leaves the Send Connector enabled and the script is no longer running.

SMTP Proxy

Even though you have indicated you are against any message handling outside of Exchange, After thinking about this some more, I've decided I'm with @longneck on using some type of SMTP proxy solution. Even IIS SMTP has a deferred delivery mechanism that it would seem Exchange 2010 does not. You could redirect large messages to the IIS SMTP server which could store them on disk, and, checking for latency first, have the IIS SMTP server send them via a script when latency is low. The worst-case if your scheduling mechanism got stuck or stopped would be the large messages get stuck on disk, but small messages continue to be sent. There are probably better solutions than IIS SMTP, and I have never used it myself, but it is just an example.

Configure SMTP E-Mail in IIS 7

August
  • 3,114
  • 15
  • 17
  • Thanks for your input! While not directly specified, it's a requirement for me that the deferred e-mails eventually reach their destination unaltered. Is that the case, when first forwarding them to a moderator mailbox, or will it leave signs - hidden or visible? As for the manual process of approving them, I would think this can be scripted somehow? – abstrask Jan 30 '13 at 23:36
  • Good question, and since I have never implemented this I created a quick test rule in our Exchange org and sent a test e-mail. The moderator received the message with an 'Approve' or 'Reject' option. Once I approved the message, it was released and sent to the destination unaltered with no signs of the moderator mailbox anywhere in the message header or the e-mail body. I can't seem to find anything on scripting the approval process, however, so you may need to actually designate a human for this task. – August Jan 31 '13 at 13:46
  • Thank you very much for the idea. I would think the rule can easily be modified through scripting, but the human intervention part is a big drawback to us, as we have no dedicated IT staff on board. Does anyone know if messages can be approved programatically and how? – abstrask Feb 04 '13 at 18:18
2

Try to take a look to the new features of "Message Throttling" introduced with Exchange 2010 SP1. It could be very helpful for your use case.

http://technet.microsoft.com/en-us/library/bb232205(v=exchg.141).aspx

Emyl
  • 380
  • 2
  • 11
  • 1
    I'm not so sure Message Throttling would help in this particular scenario. Reading through the article it seems more geared towards preventing a Transport or Edge server from getting overwhelmed with a ton of messages so it applies costing to give a QoS-type level of message delivery. In this case though a single user sending a 10 MB message could saturate the whole WAN link, making other services unavailable. A deferred-delivery mechanism would be more appropriate I think. – August Jan 25 '13 at 13:31
  • 1
    Sorry, but as I read it, "Message Throttling" will just **favour** sending smaller messages (_By default, the normal-to-low message ratio is 20:1_), not **prevent** sending larger messages. Do you have a more specific suggestion, on how to accomplish my goal? Thanks. – abstrask Jan 25 '13 at 13:32
2

To solve the problem the way you have requested, you could write your own Transport Agent using the Microsoft Exchange Transport Agent SDK. Transport Agents are event based so Exchange will call a function in your library when a message is received. Your library can then do something like hold the message. If you don't have the skills in-house to do this, I'm sure you could hire a developer to write it for you.

But I don't think this is a great solution. As an alternative for you to investigate, you might want to look in to something like an SMTP proxy for low-quality links. As you have discovered, SMTP is a horrible protocol for low-quality links because an interrupted connection causes the message transmission to restart from the beginning instead of resuming from where it left off. If you're going to hire a developer for something, I would consider writing a server program that accepts incoming SMTP connections and sends the message on to a remote instance of this same program at the other end of the satellite connection in a resumable manner (possibly segregating the large messages from the small messages via TCP port to allow for QoS treatment by your WAN accelerator). The remote instance could then, upon receipt of the complete message, complete the delivery of the message via SMTP.

longneck
  • 22,793
  • 4
  • 50
  • 84
  • Thanks for your input! I must say it's a lot less out-of-the-box-like than I had hoped for. I'm a big fan of the KISS principle. While I don't know much about writing transport agents, it's somewhat compelling to me, to keep the handling within Exchange. In Exchange 2010, it seems queues are created and destroyed on demand. Maybe the agent could force large mails into a separate queue and a script can switch between 'suspend' and 'resume'. Any idea is that's the sort of thing you can do with TA's in Exchange 2010? – abstrask Jan 30 '13 at 23:18
  • As for the SMTP proxy/smarthost suggestion, it also sounds as an OK solution, if I can find an off-the-shelf solution, preferably being actively maintained. It seems to be a bigger more complex programming task than an Exchange transport agent, that modifies the flow within Exchange (I could be wrong?). It's my experience that complex, custom-made solutions, like I imagine an SMTP proxy would be, tends to be expensive to support in the long run. – abstrask Jan 30 '13 at 23:22
  • re: seperate queues, i'm not familiar enough with the internals of Exchange to know if queues work like that, or if that's the best way. i know that individual messages can be held by a TA for processing based on my experience with Litera Metadact-e, which does exactly that: hold a message until it's done processing (which can take many minutes). i don't know if it's possible to hold them indefinitely. – longneck Jan 31 '13 at 01:42
  • my overall point of my answer is that you should probably consult a developer as there isn't an out-of-the-box solution for you. however, this is a pretty simple problem and hiring a developer to solve this problem for you is probably not cost prohibitive. – longneck Jan 31 '13 at 01:44
  • The existence of the Suspend-Message PowerShell CmdLet has be convinced that the delivery state of messages can also be modified programmatically. I like the idea of a custom transport agent, that merely modifies the delivery state of the message, over a separate SMTP proxy, as we'll be able to still keep all message tracking, delegation of admin rights etc. under Exchange. Thanks for your input! – abstrask Feb 04 '13 at 18:14
  • To be honest, I like the idea of an Exchange transport agent the best, partly because I don't have any knowledge of SMTP proxies that supports retry and different scheduling based on size, let alone experience. This is also the solution that my team found most appropriate. Thanks for your feedback! – abstrask Feb 07 '13 at 08:12